Friday, July 10, 2015

LeetCode [235] Lowest Common Ancestor of a Binary Search Tree

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given binary search tree:  root = [6,2,8,0,4,7,9,null,null,3,5]

Example 1:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.
Example 2:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

Note:
  • All of the nodes' values will be unique.
  • p and q are different and both values will exist in the BST.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root) return NULL;
        if((root->val - p->val)*(root->val - q->val)<=0) return root;
        if((root->val < p->val)) return lowestCommonAncestor(root->right, p, q);
        else return lowestCommonAncestor(root->left, p, q);
    }
};

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        while((root->val-p->val)*(root->val-q->val)>0){
            if(root->val>p->val)
                root = root->left;
            else
                root = root->right;
        }
        return root;
    }
};

LeetCode [56] Merge Intervals

 56. Merge Intervals

Medium

Given a collection of intervals, merge all overlapping intervals.

Example 1:

Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].

Example 2:

Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.

NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.

 

Constraints:

  • intervals[i][0] <= intervals[i][1]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//C++: 588 ms
/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */

bool compare(const Interval &a, const Interval &b){
  return a.start<b.start;
}

class Solution {
public:
    vector<Interval> merge(vector<Interval>& intervals) {
        sort(intervals.begin(), intervals.end(), compare);
        vector<Interval> res;
        int n = intervals.size();
        int i = 0;
        while(i<n){
            int j = i+1;
            while(j<n && intervals[i].end>=intervals[j].start){
                intervals[i].end = max(intervals[i].end, intervals[j].end);
                j++;
            }
            res.push_back(intervals[i]);
            i = j;
        }
        return res;
    }
};

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (a,b)->a[0]-b[0]);
        int n = intervals.length;
        int i = 0;
        List<int[]> list = new ArrayList<>();
        while(i<n){
            int start = intervals[i][0], end = intervals[i][1];
            int j=i+1;
            while(j<n && intervals[j][0]<=end){
                end = Math.max(end, intervals[j][1]);
                j++;
            } 
            list.add(new int[]{start, end});
            i = j;
        }

        return list.toArray(new int[0][]);
    }
}

Thursday, July 9, 2015

LeetCode [234] Palindrome Linked List

Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode *H1 = new ListNode(0);
        H1->next = head;
        ListNode *p1 = H1, *p2 = H1;
        while(p2 && p2->next){
            p1 = p1->next;
            p2 = p2->next->next;
        }
        
        ListNode *H2 = new ListNode(0), *h2 = p1->next;
        H2->next = h2;
        if(!h2) return true;
        p2 = h2->next;
        h2->next = NULL;
        while(p2){
            ListNode *next = p2->next;
            p2->next = h2;
            H2->next = p2;
            h2 = p2;
            p2 = next;
        }
        
        p1 = H1;
        p2 = H2;
        while(p2){
            if(p1->val!=p2->val) return false;
            p1 = p1->next;
            p2 = p2->next;
        }
        return true;
    }
};

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null || head.next==null) return true;
        if(head.next.next==null) return head.val==head.next.val;
        
        ListNode fast = head, slow = head;
        while(fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        
        ListNode prev = slow;
        ListNode cur = slow.next;
        ListNode p1 = head;
        ListNode p2 = null;
        while(cur!=null){
            ListNode next = cur.next;
            if(next==null) p2 = cur;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        
        
        while(true){
            if(p1.val!=p2.val) return false;
            if(p1.next == p2 || p1.next == p2.next) break;
            p1 = p1.next;
            p2 = p2.next;
        }
        
        return true;
    }
}

Wednesday, July 8, 2015

LeetCode [233] Number of Digit One

Note:

  • There's one 1 on 1-th digit for every 10 numbers;
  • There's ten 1s on 10-th digit for every 100 number;
  • There's one hundred 1s on 100-th digit for every 1000 number;
  • ......
  • line 8 computes the number of 1s on w/10-th digit and denoted it by c

  • If the input n=14, for example, when computing the number of 1s on 10-th digit, c would be evaluated to 0. However, there are 5 numbers with 1 on 10-th digit (10,11,12,13,14). I use extra at line 10 to handle such case.



  0    1    2     3     4     5     6     7    8    9    one 1 on 1-th digit for every 10 numbers
10  11  12   13   14   15   16   17  18  19    ten 1s on 10-th digit for every 100 numbers 
..............
90  91  92   93   94   95   96   97  98  99
.............
100 101            .....                        109   one hundred 1s on 100-th digit for every 1000 numbers 
.............
190 191            .....                        199

Ref
[1] https://leetcode.com/problems/number-of-digit-one/
OJ

LeetCode [232] Implement Queue using Stacks


Ref
[1] https://leetcode.com/problems/implement-queue-using-stacks/
OJ

LeetCode [231] Power of Two


Ref
[1] https://leetcode.com/problems/power-of-two/
OJ

LeetCode [230] Kth Smallest Element in a BST

 230. Kth Smallest Element in a BST

Medium

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

 

Example 1:

Input: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
Output: 1

Example 2:

Input: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
Output: 3

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

 

Constraints:

  • The number of elements of the BST is between 1 to 10^4.
  • You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        int nLeft = countN(root->left);
        if(k==nLeft+1) return root->val;
        else if(k<=nLeft) return kthSmallest(root->left, k);
        else return kthSmallest(root->right, k-nLeft-1);
    }
    
    int countN(TreeNode* root){
        if(!root) return 0;
        return 1+countN(root->left)+countN(root->right);
    }
};

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        int ret, cur = k;
        dfs(root, cur, ret);
        return ret;
    }
    void dfs(TreeNode* root, int &cur, int &ret){
        if(!root) return;
        dfs(root->left, cur, ret);
        cur--;
        if(cur==0) ret = root->val;
        dfs(root->right, cur, ret);
    }
};

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int left, ret;
    public int kthSmallest(TreeNode root, int k) {
        left = k;
        dfs(root);
        return ret;
    }
    
    void dfs(TreeNode node){
        if(node==null) return;
        dfs(node.left);
        left--;
        if(left==0) ret = node.val;
        dfs(node.right);
    }
}