Jerry's Blog

Recording what I learned everyday

View on GitHub


10 March 2020

LeetCode(112) -- 228, 229, 236

by Jerry Zhang

P228. Summary Ranges (Medium)

Given a sorted integer array without duplicates, return the summary of its ranges.

My Solution

class Solution {
    public List<String> summaryRanges(int[] nums) {
        StringBuilder sb = new StringBuilder();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            sb.append(nums[i]);
            if (i == nums.length - 1) {
                list.add(sb.toString());
                break;
            }
            boolean isRange = false;
            while (i + 1 < nums.length && nums[i + 1] - nums[i] == 1) {
                if (!isRange) {
                    sb.append("->");
                }
                isRange = true;
                i++;
            }
            if (isRange) {
                sb.append(nums[i]);
            }
            list.add(sb.toString());
            sb.setLength(0);
        }
        return list;
    }
}

100%

The Best Solution

class Solution {
    public List<String> summaryRanges(int[] nums) {
        
        int idx = 0; 
        List<String> summaryRanges = new ArrayList<>();
        for( int i = 0; i < nums.length; i++ ){
            
            idx = i;
            while( i < nums.length - 1 && ( nums[ i + 1] == nums[i] + 1 ) ){
                
                i++;
                
            }
            
            if( idx == i ){
                
                summaryRanges.add( Integer.toString(nums[idx]) );
                
            }
            else{
                
                StringBuilder sb = new StringBuilder();
                sb.append(Integer.toString(nums[idx]));
                sb.append("->");
                sb.append(Integer.toString(nums[i]));
                
                summaryRanges.add( sb.toString() );
                
            }
            
            
        }
        
        return summaryRanges;
    }
}

P229. Majority Element II (Medium)

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.

Note: The algorithm should run in linear time and in O(1) space.

My Solution

class Solution {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> ans = new ArrayList<>();
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            Integer occurrences = map.getOrDefault(num, 0);
            map.put(num, occurrences + 1);
        }
        int times = nums.length / 3;
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if (entry.getValue() > times) {
                ans.add(entry.getKey());
            }
        }
        return ans;
    }
}

33%

The Best Solution

class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int count1 = 0, count2 = 0;
        int num1 = 0, num2 = 1;
        
        for (int num : nums) {
            if (num == num1) {
                count1++;
            } else if (num == num2) {
                count2++;
            } else if (count1 == 0) {
                num1 = num;
                count1++;
            } else if (count2 == 0) {
                num2 = num;
                count2++;
            } else {
                count1--;
                count2--;
            }
        }
        int n = nums.length;
        
        count1 = 0;
        count2 = 0;
        
        for (int num : nums) {
            if (num == num1) {
                count1++;
            }
            if (num == num2) {
                count2++;
            }
        }
        
        List<Integer> res = new ArrayList<>();
        if (count1 > n / 3) {
            res.add(num1);
        }
        if (count2 > n / 3) {
            res.add(num2);
        }
        return res;
    }
}

P236. Lowest Common Ancestor of a Binary Tree (Medium)

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

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 the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]

My Solution

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        ArrayList<TreeNode> ancestor1 = new ArrayList<>();
        ArrayList<TreeNode> ancestor2 = new ArrayList<>();
        ancestor1.add(p);
        ancestor2.add(q);
        List<TreeNode> list1 = dfs(root, ancestor1);
        List<TreeNode> list2 = dfs(root, ancestor2);
        for (TreeNode treeNode : list1) {
            if (list2.contains(treeNode)) {
                return treeNode;
            }
        }
        return null;
    }

    private List<TreeNode> dfs(TreeNode root, List<TreeNode> ancestor) {
        if (root == null) {
            return ancestor;
        }
        dfs(root.left, ancestor);
        dfs(root.right, ancestor);
        if (ancestor.contains(root.left) || ancestor.contains(root.right)) {
            ancestor.add(root);
            return ancestor;
        }
        return ancestor;
    }

}

5% 很慢,勉强用最笨的办法做出来了。

方法一:

Solution

class Solution {
    private TreeNode ans;

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        recurseTree(root, p, q);
        return ans;
    }

    private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
        if (currentNode == null) {
            return false;
        }
        int left = recurseTree(currentNode.left, p, q) ? 1 : 0;
        int right = recurseTree(currentNode.right, p, q) ? 1 : 0;
        int mid = (currentNode == p || currentNode == q) ? 1 : 0;
        if (mid + left + right >= 2) {
            this.ans = currentNode;
        }
        return mid + left + right > 0;
    }
}

100% 这个方法最好。

方法二:

先用hashmap把所有父子关系记录清楚,然后顺着一条线把所有节点放到一个set中,从另一个节点向上找,第一个交点就是答案。

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        Map<TreeNode, TreeNode> parent = new HashMap<>();
        parent.put(root, null);
        stack.push(root);
        while (!parent.containsKey(p) || !parent.containsKey(q)) {
            TreeNode node = stack.pop();
            if (node.left != null) {
                parent.put(node.left, node);
                stack.push(node.left);
            }
            if (node.right != null) {
                parent.put(node.right, node);
                stack.push(node.right);
            }
        }
        Set<TreeNode> ancestors = new HashSet<>();
        while (p != null) {
            ancestors.add(p);
            p = parent.get(p);
        }
        while (!ancestors.contains(q)) {
            q = parent.get(q);
        }
        return q;
    } 
}

24%

方法三:

class Solution {
    private static int BOTH_PENDING = 2;
    
    private static int LEFT_DONE = 1;

    private static int BOTH_DONE = 0;

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        Stack<Pair<TreeNode, Integer>> stack = new Stack<Pair<TreeNode, Integer>>();
        stack.push(new Pair<>(root, Solution.BOTH_PENDING));

        boolean one_node_found = false;
        TreeNode LCA = null;
        TreeNode child_node = null;

        while (!stack.isEmpty()) {
            Pair<TreeNode, Integer> top = stack.peek();
            TreeNode parent_node = top.getKey();
            int parent_state = top.getValue();

            if (parent_state != Solution.BOTH_DONE) {
                if (parent_state == Solution.BOTH_PENDING) {
                    if (parent_node == p || parent_node == q) {
                        if (one_node_found) {
                            return LCA;
                        } else {
                            one_node_found = true;
                            LCA = stack.peek().getKey();
                        }
                    }
                    child_node = parent_node.left;
                } else {
                    child_node = parent_node.right;
                }
                stack.pop();
                stack.push(new Pair<TreeNode, Integer>(parent_node, parent_state - 1));
                if (child_node != null) {
                    stack.push(new Pair<>(child_node, Solution.BOTH_PENDING));
                }
            } else {
                if (LCA == stack.pop().getKey() && one_node_found) {
                    LCA = stack.peek().getKey();
                }
            }
        }
        return null;
    }
}

16%

tags: LeetCode