Leetcode 经典题目题解

所列均为个人解答 所用语言Java 尽量都用最优解解答 原题出自Leetcode:https://leetcode.com/problemset/algorithms/
仅供参考


Single Number
code:
public int singleNumber(int[] A) {
    int rst = 0;
    for(int a : A)
        rst ^= a;
    return rst;
}

note:
Java提供的位运算符有:左移( << )、右移( >> ) 、无符号右移( >>> ) 、位与( & ) 、位或( | )、位非( ~ )、位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。

正数左移一位相当于乘2,右移一位相当于除2

5换算成二进制: 0000 0000 0000 0000 0000 0000 0000 0101
5右移3位后结果为0,0的二进制为: 0000 0000 0000 0000 0000 0000 0000 0000        // (用0进行补位)
 -5换算成二进制: 1111 1111 1111 1111 1111 1111 1111 1011
-5右移3位后结果为-1,-1的二进制为: 1111 1111 1111 1111 1111 1111 1111 1111   // (用1进行补位)
-5无符号右移3位后的结果 536870911 换算成二进制: 0001 1111 1111 1111 1111 1111 1111 1111   // (用0进行补位)


5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

现在想知道,-5在计算机中如何表示?
在计算机中,负数以其正值的补码形式表达。


原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
比如 00000000 00000000 00000000 00000101 是 5的 原码。


反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码。
反码是相互的,所以也可称:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互为反码。


补码:反码加1称为补码。
也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。
比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。



Maximum Depth of Binary Tree
hint:
递归

code:
public int maxDepth(TreeNode root) {
    if(root == null)
        return 0;
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}


Same Tree
hint: 
递归

code:
public boolean isSameTree(TreeNode p, TreeNode q) {
    if(p == null && q == null)
        return true;
    if(p == null || q == null)
        return false;
    if(p.val != q.val )
        return false;
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}




Reverse Integer
hint:
StringBuilder  或  整数位数操作

code:
public int reverse(int x) {
        int rst = 0;
        while(x != 0){
            if(Math.abs(rst) > 214748364)  // 处理溢出 !! 214748364 9    这个本身反过来也是溢出的 也就是说最后一位只能是1
                return 0;
            rst = rst*10 + x%10;
            x /= 10;
        }
        return rst;
    }

public int reverse(int x) {
        int y = Math.abs(x);
        StringBuilder sb = new StringBuilder(y+"");
        sb.reverse();
        try{
            y = Integer.parseInt(sb.toString());
        }catch(NumberFormatException ex){
            return 0;
        }
       
        return x < 0 ? -y : y;
    }



Best Time to Buy and Sell Stock II
hint:
观察,求序列递增的增量

code:
public int maxProfit(int[] prices) {
    int sum = 0;
    if(prices.length <= 1)
        return sum;
    for(int i=1; i prices[i-1])
            sum += prices[i] - prices[i-1];
    }
    return sum;
}


Linked List Cycle
hint: 双指针 一个走两步 一个走一步, 如果快指针能追上慢指针 则存在cycle

correctness: 分case证明, 走两步的指针一定能与走一步的指针在某处相遇 且不超过一轮
或者可以思考 每一步快指针会追上一步,距离是逐一递减,因此两者距离必定经过0 即相遇点

如果快指针一次走三步,四步, 情况会怎样?

code:
public boolean hasCycle(ListNode head) {
    ListNode fast = head;
    ListNode slow = head;
    
    while(fast != null && fast.next != null){
        fast = fast.next.next;
        slow = slow.next;
        if(fast == slow)
            return true;
    }
    return false;       
}


Binary Tree Preorder Traversal
hint: use stack for the non-recursion solution

code:
public List preorderTraversal(TreeNode root) {
    List rst = new ArrayList();
    if(root == null)
        return rst;
    Stack stack = new Stack();
    stack.push(root);
    while(!stack.isEmpty()){
        root = stack.pop();
        rst.add(root.val);
        if(root.right != null)
            stack.push(root.right);
        if(root.left != null)
            stack.push(root.left);
    }
    return rst;
}


Binary Tree Inorder Traversal
hint: 难点在于如何处理输出顺序:对于每一个栈顶的节点 先将其和其所有left-most节点压入栈 
直到栈顶节点left child为空, 输出该节点val。 再压入其右节点 进行下一轮循环, 注意此时指针目标

public List inorderTraversal(TreeNode root) {
    List rst = new ArrayList();
    if(root == null)
        return rst;
    Stack stack = new Stack();
    TreeNode curr = root;
    while(!stack.isEmpty() || curr != null){
        while(curr != null){
            stack.push(curr);
            curr = curr.left;
        }
        curr = stack.pop();
        rst.add(curr.val);
        curr = curr.right;
    }
    return rst;
}


Populating Next Right Pointers in Each Node
hint: 观察结构  递归解决

public void connect(TreeLinkNode root) {
    if(root == null || root.left == null || root.right == null)
        return;
    root.left.next = root.right;
    if(root.next != null)
        root.right.next = root.next.left;
    connect(root.right);
    connect(root.left);
}


Remove Duplicates from Sorted List
hint: list操作
public ListNode deleteDuplicates(ListNode head) {
        if(head == null)
            return head;
        ListNode curr = head;
        while(curr.next != null){
            if(curr.val == curr.next.val)
                curr.next = curr.next.next;
            else
                curr = curr.next;
        }
        return head;
    }


Search Insert Position
hint: linear array search 秒杀
public int searchInsert(int[] A, int target) {
    for(int i=0; i target)
            return i;
    }
    return A.length;
}

binary search:
public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length-1;
        int rst = 0;
       
        while(left <= right){
            if(left == right){
                rst = target <= nums[left] ? left : left+1;
                break;
            }
            int mid = left + (right-left)/2;
            if(nums[mid] == target){
                rst = mid;
                break;
            }
            else if(nums[mid] > target){
                right = mid;
            }
            else
                left = mid+1;
        }
       
        return rst;
    }


Climbing Stairs
hint: 一维DP 
public int climbStairs(int n) {
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;

        for(int i=2; i<=n; ++i){
            dp[i] = dp[i-1] + dp[i-2];
        }

        return dp[n];
}


Maximum Subarray
hint:  O(n) 数组线性扫描
public int maxSubArray(int[] A) {
    int max = Integer.MIN_VALUE;
    int sum = 0;
    for(int i=0; i max)
            max = sum;
        if(sum < 0)
            sum = 0;
    }
    return max;
}


dp:
public int maxSubArray(int[] A) {
        int[] dp = new int[A.length];
        dp[0] = A[0];
        for(int i=1; i max)
                max = dp[i];
        return max;
    }


Roman to Integer
public int romanToInt(String s) {
    int rst = 0;
 
    for(int i=0; i0 && charToNum(s.charAt(i)) > charToNum(s.charAt(i-1)))
            rst += (charToNum(s.charAt(i)) - 2*charToNum(s.charAt(i-1))); 
        else 
            rst += charToNum(s.charAt(i));
    }
    return rst;
} 
 
private int charToNum(char c){ 
    switch(c){
    case 'I': return 1;
    case 'V': return 5;
    case 'X': return 10;
    case 'L': return 50;
    case 'C': return 100;
    case 'D': return 500;
    case 'M': return 1000;
    default: return 0;
    }
}


N-Queens II
hint: cols[i] 记录第i行的queen放在了第几列。
public int totalNQueens(int n) {
    int[] cols = new int[n];
    return dfs(cols, n, 0);
}

public int dfs(int[] cols, int n, int row){
    if(row == n){
        return 1;
    }
    
    int num = 0;
    for(int i=0; i

public int totalNQueens(int n) {
        int[] used = new int[n];
        int[] ang = new int[2*n];
        int[] anti = new int[2*n];
       
        return dfs(used, ang, anti, n, 0);
    }
   
    private int dfs(int[] used, int[] ang, int[] anti, int n, int k){
        if(k == n)
            return 1;
           
        int count = 0;
        for(int i=0; i


Single Number II
hint: 因为题目已经说了,除了一个数字以外,其他的都出现了3次,如果我们把那个特殊的数剔除,并把剩下的数于每一位来加和的话,每一位上1出现的次数必然都是3的倍数。所以,解法就在这里,将每一位数字分解到32个bit上,统计每一个bit上1出现的次数。最后对于每一个bit上1出现的个数对3取模,剩下的就是结果。
public int singleNumber(int[] A) {
        int[] bits = new int[32];
        int rst = 0;
        for(int i=31; i>=0; --i){
            for(int j=0; j>i)&1;
            bits[i] %= 3;
            rst = (rst<<1)+bits[i];
        }
        return rst;
    }


Integer to Roman

public String intToRoman(int num) {
    String[] roman = {"I", "V", "X", "L", "C", "D", "M"};
    String rst = ""; 

    int level = 1000; 
    for(int i=6; i>=0; i-=2){
        int digit = num/level;
            if(digit != 0){ 
                if(digit <= 3){
                    for(int j=0; j


Merge Two Sorted Lists
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode rst = new ListNode(0);
    ListNode curr = rst;
    while(l1 != null && l2 != null){
        if(l1.val < l2.val){
            curr.next= l1;
            curr = curr.next;
            l1 = l1.next;
        }
        else{
            curr.next = l2;
            curr = curr.next;
            l2 = l2.next;
        }
    }
    while(l1 != null){
        curr.next = l1;
        curr = curr.next;
        l1 = l1.next;
    }
    while(l2 != null){
        curr.next = l2;
        curr = curr.next;
        l2 = l2.next;
    }

    return rst.next;
}

递归解法
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null && l2 == null)
         return null;
        else if(l1 == null || l2 == null)
         return (l1!=null ? l1 : l2);
         
        ListNode head;
        if(l1.val < l2.val){
         head = l1;
         head.next = mergeTwoLists(l1.next, l2);
        }
        else{
         head = l2;
         head.next = mergeTwoLists(l1, l2.next);
        }
       
        return head;
    }


Remove Element
hint: 双指针操作
public int removeElement(int[] nums, int val) {
        if(nums == null || nums.length == 0)
            return 0;
        int p = 0;
        for(int i=0; i


Convert Sorted Array to Binary Search Tree
hint: 递归
public TreeNode sortedArrayToBST(int[] num) {
        if(num.length < 1)
            return null;
        return bst(num, 0, num.length-1);
    }
   
    public TreeNode bst(int[] num, int start, int end){
        if(start > end)
            return null;
        int mid = start + (end-start)/2;                          // 防止溢出
        TreeNode node = new TreeNode(num[mid]);
        node.left = bst(num, start, mid-1);
        node.right = bst(num, mid+1, end);
        return node;
    }


Balanced Binary Tree
hint: 设个外部变量, 通过计算高度遍历tree
public boolean isBalanced(TreeNode root) {
        return height(root) != -1;
    }
   
    public int height(TreeNode node){
        if(node == null)
            return 0;
        int lefth = height(node.left);
        int righth = height(node.right);
        if(lefth < 0 || righth < 0 || Math.abs(lefth-righth) > 1)
            return -1;
        return Math.max(lefth, righth) + 1;
    }


Remove Duplicates from Sorted Array
hint: 双指针扫数组
public int removeDuplicates(int[] A) {
    if(A.length <= 1)
        return A.length;
    int index = 0;
    for(int i=1; i


Swap Nodes in Pairs
public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        ListNode curr = head;
        while(curr != null && curr.next != null){
            prev.next = curr.next;
            curr.next = curr.next.next;
            prev.next.next = curr;
            prev = curr;
            curr = curr.next;
        }
        return dummy.next;
    }



Symmetric Tree
note: 两种解法

iterative method:
public boolean isSymmetric(TreeNode root) {
    if(root == null)
        return true;
    Queue qleft = new LinkedList();
    Queue qright = new LinkedList();

    qleft.offer(root.left);
    qright.offer(root.right);
    while(!qleft.isEmpty() && !qright.isEmpty()){
        TreeNode left = qleft.poll();
        TreeNode right = qright.poll();
        if(left == null && right == null)
            continue;
        if(left == null || right == null || right.val != left.val)
            return false;
        qleft.offer(left.left);
        qright.offer(right.right);
        qleft.offer(left.right);
        qright.offer(right.left);
    }
    return true;
}

recursion method:
public boolean isSymmetric(TreeNode root) {
    if(root == null)
        return true;
    return isMirror(root.left, root.right);
}

private boolean isMirror(TreeNode left, TreeNode right){
    if(left == null && right == null)
        return true;
    if(left == null || right == null || left.val != right.val)
        return false;
    return isMirror(left.right, right.left) && isMirror(left.left, right.right);
}


Sort Colors
hint: 数组三指针操作
public void sortColors(int[] A) {
    int left = 0;
    int curr = 0;
    int right = A.length - 1;
    while(curr <= right){
        if(A[curr] == 0){
            A[curr] = A[left];
            A[left++] = 0;
        }
        else if(A[curr] == 2){
            A[curr] = A[right];
            A[right--] = 2;
        }
        else{
            ++curr;
        }
        
       if(curr < left)
            curr++;
    }
}


Merge Sorted Array
hint:  从后往前 从大到小填空

public void merge(int A[], int m, int B[], int n) {
    int inda = m - 1;
    int indb = n - 1;
    for(int i=m+n-1; i>=0; --i){
        if(inda < 0)
            A[i] = B[indb--];
        else if(indb < 0)
            A[i] = A[inda--];
        else if(A[inda] > B[indb])
            A[i] = A[inda--];
        else
            A[i] = B[indb--];
    }
}


Gray Code
recursive: 
public List grayCode(int n) {
    List rst = new ArrayList();
    if(n == 0){
        rst.add(0);
        return rst;
    }
    
    List list = grayCode(n-1);
    for(int i=0; i


Iterative:  n=k时的Gray Code,相当于n=k-1时的Gray Code的逆序 加上 1<
public List grayCode(int n) {
        List rst = new ArrayList();
        rst.add(0);
       
        for(int i=0; i=0; --j){
                rst.add(rst.get(j) + (1<


Plus One
public int[] plusOne(int[] digits) {
    int add = 1;
    for(int i=digits.length-1; i>=0; --i){
        int sum = digits[i] + add;
        digits[i] = sum%10;
        add = sum/10;
    }
    
    int[] rst = digits;
    if(add == 1){
        rst = new int[digits.length+1];
        rst[0] = 1;
        for(int i=1; i


Unique Paths
hint: DP
二维:
public int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    for(int i=0; i

一维:
public int uniquePaths(int m, int n) {
    int[] dp = new int[m];
    dp[0] = 1;
    for(int i=0; i

Unique Binary Search Trees
public int numTrees(int n) {
        if(n <= 1)
            return 1;
        int rst = 0;
        for(int i=0; i


dp
public int numTrees(int n) {
        if(n <= 1)
            return n;
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;
        for(int i=2; i<=n; ++i){
            for(int j=0; j


Find Minimum in Rotated Sorted Array
public int findMin(int[] num) {
        return getMin(num, 0, num.length-1);
    }
   
    public int getMin(int[] num, int left, int right){
        if(left == right || num[left] < num[right])
            return num[left];
        int mid = left + (right-left)/2;
        if(num[right] < num[mid])
            return getMin(num, mid+1, right);
        else
            return getMin(num, left, mid);
    }


Find Minimum in Rotated Sorted Array II
public int findMin(int[] nums) {
        if(nums == null || nums.length == 0)
            return -1;
        return findMin(nums, 0, nums.length-1);
    }
   
    private int findMin(int[] nums, int left, int right){
        if(left == right || nums[left] < nums[right])
            return nums[left];
       
        int mid = left + (right - left)/2;
        if(nums[mid] < nums[right]){
            return findMin(nums, left, mid);
        }
        else if(nums[mid] > nums[right]){
            return findMin(nums, mid+1, right);
        }
        else
            return findMin(nums, left, right-1);
    }

Iterative solution:
public int findMin(int[] nums) {
        int left = 0;
        int right = nums.length-1;
       
        while(left <= right){
            if(left == right || nums[left] < nums[right])
                return nums[left];
            if(nums[left] == nums[right]){
                right--;
                continue;
            }
            int mid = left + (right-left)/2;
            if(nums[mid] > nums[right])
                left = mid + 1;
            else
                right = mid;
        }
       
        return nums[left];
    }


Find Peak Element
Given an input array where num[i] ≠ num[i+1]find a peak element and return its index.
public int findPeakElement(int[] nums) {
        if(nums == null || nums.length <= 1)
            return 0;
        int left = 0;
        int right = nums.length-1;
        while(left + 1 < right){
            int mid = left + (right-left)/2;
            if(nums[mid] > nums[mid-1] && nums[mid] > nums[mid+1])
                return mid;
            if(nums[mid] < nums[mid-1])
                right = mid;
            else
                left = mid;
        }
       
        return nums[left] > nums[right] ? left : right;
    }


Container With Most Water
public int maxArea(int[] height) {
        if(height.length <= 1)
            return 0;
        int left = 0;
        int right = height.length-1;
        int max = 0;
        while(left < right){
            int val = Math.min(height[left], height[right]) * (right - left);
            if(val > max)
                max = val;
            if(height[left] < height[right])
                left++;
            else
                right--;
        }
        return max;
    }


Rotate Image
public void rotate(int[][] matrix) {
        int row = matrix.length;
        int col = matrix[0].length;
       
        for(int i=0; i


Generate Parentheses
public List generateParenthesis(int n) {
        List rst = new ArrayList();
        dfs(rst, n, n, "");
        return rst;
    }
   
    public void dfs(List list, int l, int r, String str){
        if(l == 0){
            while(r-- > 0)
                str += ")";
            list.add(str);
            return;
        }
        dfs(list, l-1, r, str+"(");
        if(l < r)
            dfs(list, l, r-1, str+")");
    }


Permutations
public List> permute(int[] num) {
        List> rst = new ArrayList>();
        dfs(rst, num, new ArrayList());
        return rst;
    }
   
    public void dfs(List> rst, int[] num, List list){
        if(list.size() == num.length){
            rst.add(new ArrayList(list));
            return;
        }
        for(int i=0; i


Minimum Path Sum
public int minPathSum(int[][] grid) {
        int n = grid[0].length;
        int[] dp = new int[n];
       
        dp[0] = grid[0][0];
        for(int i=1; i


Search a 2D Matrix
public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
            return false;
        int m = matrix.length;
        int n = matrix[0].length;
        int left = 0;
        int right = m*n-1;
        while(left <= right){
            int mid = left + (right-left)/2;
            if(matrix[mid/n][mid%n] == target)
                return true;
            else if(matrix[mid/n][mid%n] < target)
                left = mid+1;
            else
                right = mid-1;
        }
        return false;
    }


Path Sum
public boolean hasPathSum(TreeNode root, int sum) {
        if(root == null)
            return false;
           
        if(root.left == null && root.right == null)
            return sum == root.val;
       
        return hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val);
    }


Combinations
public List> combine(int n, int k) {
        List> rst = new ArrayList>();
        if(n == 0 || n < k)
            return rst;
        dfs(rst, new ArrayList(), n, 1, k);
        return rst;
    }
   
    private void dfs(List> rst, List list, int n, int p, int k){
        if(k == 0){
            rst.add(new ArrayList(list));
            return;
        }
       
        for(int i=p; i<=n; ++i){
            list.add(i);
            dfs(rst, list, n, i+1, k-1);
            list.remove(list.size()-1);
        }
    }


Binary Tree Postorder Traversal
public List postorderTraversal(TreeNode root) {
        List rst = new ArrayList();
        Stack stack = new Stack();
       
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode nd = stack.pop();
            if(nd == null)
                continue;
            rst.add(0, nd.val);
            stack.push(nd.left);
            stack.push(nd.right);
        }
        return rst;
    }


Search in Rotated Sorted Array
public int search(int[] A, int target) {
        return binarySearch(A, target, 0, A.length-1);
    }
   
    public int binarySearch(int[] A, int target, int left, int right){
        if(left > right)
            return -1;
        int mid = left + (right-left)/2;
        if(A[mid] == target)
            return mid;
        if(A[left] < A[right]){
            if(A[mid] > target)
                return binarySearch(A, target, left, mid);
            else
                return binarySearch(A, target, mid+1, right);
        }
        else if(A[mid] < A[right]){
            if(target > A[mid] && target <= A[right])
                return binarySearch(A, target, mid+1, right);
            else
                return binarySearch(A, target, left, mid);
        }
        else{
            if(target >= A[left] && target < A[mid])
                return binarySearch(A, target, left, mid);
            else
                return binarySearch(A, target, mid+1, right);
        }
    }


Search in Rotated Sorted Array II
public boolean search(int[] A, int target) {
        int left = 0;
        int right = A.length - 1;
        while(left <= right){
            int mid = left + (right-left)/2;
            if(A[mid] == target)
                return true;
            if(A[left] < A[right]){
                if(A[mid] > target)
                    right = mid;
                else
                    left = mid+1;
            }
            else if(A[mid] == A[left] && A[mid] == A[right])
                left++;
            else{
                if(A[mid] >= A[left]){
                    if(A[mid] > target && A[left] <= target)
                        right = mid;
                    else
                        left = mid+1;
                }
                else{
                    if(A[mid] < target && A[right] >= target)
                        left = mid+1;
                    else
                        right = mid;
                }
            }
        }
        return false;
    }


Populating Next Right Pointers in Each Node II
public void connect(TreeLinkNode root) {
        if(root == null || root.left == null && root.right == null)
            return;
        if(root.left != null)
            root.left.next = root.right == null ? getNode(root.next) : root.right;
        if(root.right != null)
            root.right.next = getNode(root.next);
           
        connect(root.right);
        connect(root.left);
    }
   
    public TreeLinkNode getNode(TreeLinkNode node){
        if(node == null)
            return null;
        if(node.left != null)
            return node.left;
        if(node.right != null)
            return node.right;
        return getNode(node.next);
    }


Binary Tree Level Order Traversal II
public List> levelOrderBottom(TreeNode root) {
        List> rst = new ArrayList>();
        if(root == null)
            return rst;
        Queue queue = new LinkedList();
        List list = new ArrayList();
        queue.offer(root);
        int count = 0;
        int num = 1;
        while(!queue.isEmpty()){
            TreeNode node = queue.poll();
            num--;
               
            list.add(node.val);
            if(node.left != null){
                queue.offer(node.left);
                count++;
            }
            if(node.right != null){
                queue.offer(node.right);
                count++;
            }
           
            if(num == 0){
                rst.add(0, new ArrayList(list));
                list.clear();
                num = count;
                count = 0;
            }
        }
        return rst;
    }


Set Matrix Zeroes
public void setZeroes(int[][] matrix) {
        int row = matrix.length;
        int col = matrix[0].length;
       
        boolean rowZero = false;
        boolean colZero = false;
       
        for(int i=0; i


Remove Duplicates from Sorted Array II
public int removeDuplicates(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
        int left = 0;
        int right = 1;
        int count = 0;
        while(right < nums.length){
            if(nums[right] == nums[left]){
                ++count;
                if(count < 2){
                    nums[++left] = nums[right++];
                } else{
                    right++;
                }
            }
            else{
                count = 0;
                nums[++left] = nums[right++];
            }
        }
       
        return left + 1;
    }

public int removeDuplicates(int[] A) {
        if(A.length <= 2)
            return A.length;
        int p = 2;
        for(int i=2; i


Subsets
bit operation methods 请见解答pdf
public List> subsets(int[] S) {
        List> rst = new ArrayList>();
        Arrays.sort(S);
        dfs(rst, new ArrayList(), S, 0);
        return rst;
    }
   
    public void dfs(List> rst, List list, int[] S, int n){
        if(n >= S.length){
            rst.add(new ArrayList(list));
            return;
        }
       
        dfs(rst, list, S, n+1);
        list.add(S[n]);
        dfs(rst, list, S, n+1);
        list.remove(list.size()-1);
    }


Binary Tree Level Order Traversal
public List> levelOrder(TreeNode root) {
        List> rst = new ArrayList>();
        print(rst, root, 1);
        return rst;
    }
   
    public void print(List> rst, TreeNode node, int level){
        if(node == null)
            return;
        if(rst.size() < level){
            List list = new ArrayList();
            list.add(node.val);
            rst.add(list);
        }
        else
            rst.get(level-1).add(node.val);
        print(rst, node.left, level+1);
        print(rst, node.right, level+1);
    }


Sum Root to Leaf Numbers
private int sum;
   
    public int sumNumbers(TreeNode root) {
        sum = 0;
        dfs(root, 0);
        return sum;
    }
   
    public void dfs(TreeNode node, int num){
        if(node == null)
            return;
        if(node.left == null && node.right == null){
            sum += num*10 + node.val;
        }
        dfs(node.left, 10*num + node.val);
        dfs(node.right, 10*num + node.val);
    }


Trapping Rain Water
two pointers, value copy when traversal
public int trap(int[] A) { 
        int left = 0;
        int right = A.length-1;
        int sum = 0;
       
        while(right-left > 1){
            if(A[left] < A[right]){
                sum += A[left+1]

public int trap(int[] height) {
        if(height == null || height.length <= 2)
            return 0;
        int rst = 0;
        int left= 0;
        int right = height.length-1;
        int h = Math.min(height[left], height[right]);
       
        while(left < right){
            if(height[left] < height[right]){
                rst += h > height[left] ? h - height[left] : 0;
                if(height[++left] > h)
                    h = Math.min(height[left], height[right]);
            }
            else{
                rst += h > height[right] ? h - height[right] : 0;
                if(height[--right] > h)
                    h = Math.min(height[left], height[right]);
            }
        }
       
        return rst;
    }


Minimum Depth of Binary Tree
public int minDepth(TreeNode root) {
        return minDepth(root, false);
    }
   
    public int minDepth(TreeNode node, boolean hasBrother){
        if(node == null)
            return hasBrother ? Integer.MAX_VALUE : 0;
        return 1 + Math.min(minDepth(node.left, node.right != null), minDepth(node.right, node.left != null));
    }

public int minDepth(TreeNode root) {
        if(root == null)
            return 0;
        if(root.left == null && root.right == null)
            return 1;
        if(root.left != null && root.right != null)
            return 1+Math.min(minDepth(root.left), minDepth(root.right));
        if(root.left != null)
            return 1+minDepth(root.left);
        else
            return 1+minDepth(root.right);
    }


Palindrome Number
public boolean isPalindrome(int x) {
        if(x < 0)
            return false;
        int d = 1;
        int y = x/10;
        while(y > 0){
            y /= 10;
            d *= 10;
        }
        while(d > 1){
            if(x/d != x%10)
                return false;
            x = (x - d*(x/d))/10;
            d /= 100;
        }
        return true;
    }


Remove Nth Node From End of List
two pointers, elegant!!
public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode p = dummy;
        ListNode q = dummy;
        for(int i=0; i


Unique Paths II
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int row = obstacleGrid.length;
        int col = obstacleGrid[0].length;
       
        int[] dp = new int[col];
        if(obstacleGrid[0][0] == 0)
                dp[0] = 1;
        for(int i=0; i


Longest Consecutive Sequence
public int longestConsecutive(int[] num) {
        Map map = new HashMap();
        for(int i=0; i max)
                max = len;
        }
       
        return max;
    }


Flatten Binary Tree to Linked List
public void flatten(TreeNode root) {
        while(root != null){
            if(root.left != null){
                getRightMost(root.left).right = root.right;
                root.right = root.left;
                root.left = null;
            }
            root = root.right;
        }
    }
   
    public TreeNode getRightMost(TreeNode node){
        while(node.right != null)
            node = node.right;
        return node;
    }


Valid Parentheses
public boolean isValid(String s) {
        Stack stack = new Stack();
        for(int i=0; i


Search for a Range
two time binary search to find both left bound and right bound
public int[] searchRange(int[] A, int target) {
        int[] rst = new int[2];
        rst[0] = -1;
        rst[1] = -1;
       
        int left = 0;
        int right = A.length-1;
        while(left <= right){
            int mid = left + (right-left)/2;
            if(A[mid] == target){
                rst[0] = mid;
                right = mid-1;
            }
            else if(A[mid] < target)
                left = mid+1;
            else
                right = mid-1;
        }
        left = 0;
        right = A.length-1;
        while(left <= right){
            int mid = left + (right-left)/2;
            if(A[mid] == target){
                rst[1] = mid;
                left = mid+1;
            }
            else if(A[mid] < target)
                left = mid+1;
            else
                right = mid-1;
        }
        return rst;
    }


Valid Sudoku
public boolean isValidSudoku(char[][] board) {
        for(int i=0; i<9; ++i){
            int[] row = new int[10];
            int[] col = new int[10];
            for(int j=0; j<9; ++j){
                if(board[i][j] != '.'){
                    int val = board[i][j] - '0';
                    if(row[val] == 1)
                        return false;
                    else
                        row[val] = 1;
                }
                if(board[j][i] != '.'){
                    int val = board[j][i] - '0';
                    if(col[val] == 1)
                        return false;
                    else
                        col[val] = 1;
                }
            }
        }
       
        for(int i=0; i<9; i+=3)
            for(int j=0; j<9; j+=3){
                int[] cell = new int[10];
                for(int m=0; m<3; ++m)
                    for(int n=0; n<3; ++n){
                        if(board[i+m][j+n] != '.'){
                            int val = board[i+m][j+n] - '0';
                            if(cell[val] == 1)
                                return false;
                            else
                                cell[val] = 1;
                        }
                    }
            }
        return true;
    }



Subsets II
public List> subsetsWithDup(int[] num) {
        List> rst = new ArrayList>();
        Arrays.sort(num);
        dfs(rst, new ArrayList(), num, 0);
        return rst;
    }
   
    public void dfs(List> rst, List list, int[] num, int n){
        if(n >= num.length){
            rst.add(new ArrayList(list));
            return;
        }
       
        list.add(num[n]);
        dfs(rst, list, num, n+1);
        list.remove(list.size()-1);
        int i = 1;
        for(; i+n


Jump Game
public boolean canJump(int[] A) {
        int term = 0;
        int p = 0;
        while(term < A.length && term >= p){
            if(p + A[p] > term)
                term = p + A[p];
            p++;
        }
        return term >= A.length-1;
    }


Combination Sum
public List> combinationSum(int[] candidates, int target) {
        List> rst = new ArrayList>();
        Arrays.sort(candidates);
        dfs(rst, new ArrayList(), candidates, 0, target);
        return rst;
    }
   
    public void dfs(List> rst, List list,int[] cand, int n, int target){
        if(target == 0){
            rst.add(new ArrayList(list));
            return;
        }
        if(target < 0 || n >= cand.length || cand[n] > target)
            return;
           
        list.add(cand[n]);
        dfs(rst, list, cand, n, target-cand[n]);
        list.remove(list.size()-1);
        dfs(rst, list, cand, n+1, target);
    }

public List> combinationSum(int[] candidates, int target) {
        List> rst = new ArrayList>();
        Arrays.sort(candidates);
        dfs(rst, new ArrayList(), candidates, 0, target);
        return rst;
    }
   
    private void dfs(List> rst, List list, int[] cand, int k, int target){
        if(target == 0){
            rst.add(new ArrayList(list));
            return;
        }
       
        for(int i=k; i


Partition List
public ListNode partition(ListNode head, int x) {
        ListNode dummy1 = new ListNode(0);
        ListNode dummy2 = new ListNode(0);
        ListNode end1 = dummy1;
        ListNode end2 = dummy2;
        while(head != null){
            if(head.val < x){
                end1.next = head;
                end1 = end1.next;
            }
            else{
                end2.next = head;
                end2 = end2.next;
            }
            head = head.next;
        }
        end2.next = null;
        end1.next = dummy2.next;
        return dummy1.next;
    }


Unique Binary Search Trees II
public List generateTrees(int n) {
        return dfs(1, n);
    }
   
    public List dfs(int start, int end){
        List rst = new ArrayList();
        if(start > end){
            rst.add(null);
            return rst;
        }
        for(int i=start; i<=end; ++i){
            List left = dfs(start, i-1);
            List right = dfs(i+1, end);
            for(int m=0; m


Triangle
public int minimumTotal(List> triangle) {
        int m = triangle.size();
        int n = triangle.get(m-1).size();
        int[] dp = new int[n+1];
        for(int i=m-1; i>=0; --i)
            for(int j=0; j


Longest Common Prefix
public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0)
            return "";
        int len = strs[0].length();
        int comm = Integer.MAX_VALUE;
        for(int i=0; i

public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0)
            return "";
        int len = 0;
        for(int i=0; i= str.length() || str.charAt(i) != ch){
                    same = false;
                    break;
                }
            }
            if(!same)
                break;
            len++;
        }
       
        return strs[0].substring(0, len);
    }


Majority Element
public int majorityElement(int[] num) {
        Arrays.sort(num);
        return num[num.length/2];
}

public int majorityElement(int[] nums) {
        int count = 1;
        int num = nums[0];
       
        for(int i=1; i


Path Sum II
public List> pathSum(TreeNode root, int sum) {
        List> rst = new ArrayList>();
        dfs(rst, new ArrayList(), root, sum);
        return rst;
    }
   
    public void dfs(List> rst, List list, TreeNode node, int sum){
        if(node == null)
            return;
        if(node.val == sum && node.left == null && node.right == null){
            list.add(node.val);
            rst.add(new ArrayList(list));
            list.remove(list.size()-1);
            return;
        }
        list.add(node.val);
        dfs(rst, list, node.left, sum-node.val);
        dfs(rst, list, node.right, sum-node.val);
        list.remove(list.size()-1);
    }


Intersection of Two Linked Lists
关键是找出差步数
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pa = headA, pb = headB;
        int lena = 0, lenb = 0;
       
        while(pa != null){
            lena++;
            pa = pa.next;
        }
        while(pb != null){
            lenb++;
            pb = pb.next;
        }
        pa = headA;
        pb = headB;
        if(lena > lenb){
            for(int i=0; i


a clean solution:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode currA = headA;
        ListNode currB = headB;
        while(currA != currB){
            if(currA == null)
                currA = headB;
            else
                currA = currA.next;
               
            if(currB == null)
                currB = headA;
            else
                currB = currB.next;
        }
        return currA;
    }


Construct Binary Tree from Inorder and Postorder Traversal
public TreeNode buildTree(int[] inorder, int[] postorder) {
        return build(inorder, 0, inorder.length-1, postorder, 0, postorder.length-1);
    }
   
    public TreeNode build(int[] inorder, int lin, int rin, int[] postorder, int lpost, int rpost){
        if(lin > rin || lpost > rpost)
            return null;
       
        int count = 0;
        for(int i=0; i


Binary Tree Zigzag Level Order Traversal
public List> zigzagLevelOrder(TreeNode root) {
        Stack stack = new Stack();
        Stack stack2 = new Stack();
        List> rst = new ArrayList>();
       
        stack2.push(root);
        while(!stack.isEmpty() || !stack2.isEmpty()){
            TreeNode node = null;
            List list = new ArrayList();
            while(!stack2.isEmpty()){
                node = stack2.pop();
                if(node != null){
                    list.add(node.val);
                    stack.push(node.left);
                    stack.push(node.right);
                }
            }
            if(list.size() > 0)
                rst.add(list);
            list = new ArrayList();
            while(!stack.isEmpty()){
                node = stack.pop();
                if(node != null){
                    list.add(node.val);
                    stack2.push(node.right);
                    stack2.push(node.left);
                }
            }
            if(list.size() > 0)
                rst.add(list);
        }
        return rst;
    }

public List> zigzagLevelOrder(TreeNode root) {
        List> rst = new ArrayList>();
        if(root == null)
            return rst;
        Queue q = new LinkedList();
        q.offer(root);
        int n = 1;
        while(!q.isEmpty()){
            List list = new ArrayList();
            int count = 0;
            for(int i=0; i


Pow(x, n)
public double pow(double x, int n) {
        if(n == 0)
            return 1;
        double val = pow(x, n/2);
        if(n > 0)
            return n/2*2 == n ? val*val : val*val*x;
        else
            return n/2*2 == n ? val*val : val*val/x;
    }


Reverse Linked List II
public ListNode reverseBetween(ListNode head, int m, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
       
        ListNode p = dummy;
        ListNode q = head;
        for(int i=1; i


N-Queens
public List solveNQueens(int n) {
        List rst = new ArrayList();
       cols = new boolean[n];
        maindiag = new boolean[2*n];
        antidiag = new boolean[2*n];
        dfs(rst, new String[n], 0, n);
        return rst;
    }
   
    private boolean[] cols;
    private boolean[] maindiag;
    private boolean[] antidiag;
   
    public void dfs(List rst, String[] strs, int row, int n){
        if(row == n){
            String[] str = new String[n];
            System.arraycopy(strs, 0, str, 0, n);
            rst.add(str);
            return;
        }
       
        for(int i=0; i


Maximum Product Subarray
O(1)的DP
public int maxProduct(int[] A) {
        int dppos = 1;
        int dpneg = 1;
        int max = Integer.MIN_VALUE;
        for(int i=0; i


Linked List Cycle II
public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
       
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(fast == slow)
                break;
        }
       
        if(fast == null || fast.next == null)
            return null;
       
        slow = head;
        while(slow != fast){
            slow = slow.next;
            fast = fast.next;
        }
       
        return fast;
    }


Pascal's Triangle
public List> generate(int numRows) {
        List> rst = new ArrayList>();
        List list = new ArrayList();
        if(numRows == 0)
            return rst;
        for(int i=1; i<=numRows; ++i){
            for(int j=list.size()-1; j>0; --j)
                list.set(j, list.get(j)+list.get(j-1));
            list.add(1);
            rst.add(new ArrayList(list));
        }
        return rst;
    }


Pascal's Triangle II
滚动list 
public List getRow(int rowIndex) {
        List list = new ArrayList();
        if(rowIndex < 0)
            return list;
        for(int i=0; i<=rowIndex; ++i){
            for(int j=list.size()-1; j>0; --j)
                list.set(j, list.get(j-1)+list.get(j));
            list.add(1);
        }
        return list;
    }


3Sum Closest
先排序 再左右夹逼
public int threeSumClosest(int[] num, int target) {
        Arrays.sort(num);
        int sum = 0;
        int mingap = Integer.MAX_VALUE;
        for(int i=0; i target)
                    right--;
                else
                    left++;
            }
        }
        return sum;
    }


Construct Binary Tree from Preorder and Inorder Traversal
public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTree(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
    }
   
    private TreeNode buildTree(int[] pre, int pl, int pr, int[] ino, int il, int ir){
        if(pl > pr)
            return null;
        TreeNode node = new TreeNode(pre[pl]);
        int count = 0;
        for(int i=il; i<=ir; ++i){
            if(ino[i] == pre[pl])
                break;
            ++count;
        }
        node.left = buildTree(pre, pl+1, pl+count, ino, il, il+count-1);
        node.right = buildTree(pre, pl+count+1, pr, ino, il+count+1, ir);
        return node;
    }


Gas Station
public int canCompleteCircuit(int[] gas, int[] cost) {
        int total = 0;
        int sum = 0;
        int index = 0;
        for(int i=0; i= 0 ? index : -1;
    }


Palindrome Partitioning
有没有更好的解法
public List> partition(String s) {
        List> rst = new ArrayList>();
        if(s == null || s.length() == 0)
            return rst;
        partition(rst, new ArrayList(), s, 0);
        return rst;
    }
   
    public void partition(List> rst, List list, String s, int n){
        if(n == s.length()){
            rst.add(new ArrayList(list));
            return;
        }
       
        for(int i=n+1; i<=s.length(); ++i){
            String sub = s.substring(n, i);
            if(isPalindrome(sub)){
                list.add(sub);
                partition(rst, list, s, i);
                list.remove(list.size()-1);
            }
        }
    }
   
    public boolean isPalindrome(String s){
        int i=0;
        int j=s.length()-1;
        while(i<=j){
            if(s.charAt(i++) != s.charAt(j--))
                return false;
        }
        return true;
    }



Count and Say
public String countAndSay(int n) {
        String rst = new String();
        if(n <= 0)
            return rst;
        rst = "1";
       
        for(int i=1; i


Edit Distance
public int minDistance(String word1, String word2) {
        int[][] dp = new int[word1.length()+1][word2.length()+1];
        dp[0][0] = 0;
        for(int i=1; i<=word1.length(); ++i)
            dp[i][0] = i;
        for(int i=1; i<=word2.length(); ++i)
            dp[0][i] = i;
           
        for(int i=1; i<=word1.length(); ++i)
            for(int j=1; j<=word2.length(); ++j){
                int min = Math.min(dp[i-1][j], dp[i][j-1])+1;
                if(word1.charAt(i-1) == word2.charAt(j-1))
                    dp[i][j] = Math.min(min, dp[i-1][j-1]);
                else
                    dp[i][j] = Math.min(min, dp[i-1][j-1]+1);
            }
        return dp[word1.length()][word2.length()];
    }


Insertion Sort List
链表单列出来
public ListNode insertionSortList(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = null;
       
        while(head != null){
            ListNode curr = dummy;
            while(curr.next != null && curr.next.val < head.val)
                curr = curr.next;
            ListNode temp = curr.next;
            ListNode next = head.next;
            curr.next = head;
            head.next = temp;
            head = next;
        }
        return dummy.next;
    }


Permutations II
public List> permuteUnique(int[] nums) {
        List> rst = new ArrayList>();
        if(nums == null || nums.length == 0)
            return rst;
        Arrays.sort(nums);
        boolean[] used = new boolean[nums.length];
        dfs(rst, new ArrayList(), used, nums);
        return rst;
    }
   
    private void dfs(List> rst, List list, boolean[] used, int[] nums){
        if(list.size() == nums.length){
            rst.add(new ArrayList(list));
            return;
        }
       
        int pre = nums[0]-1;
        for(int i=0; i


Add Binary
public String addBinary(String a, String b) {
        StringBuilder sb = new StringBuilder();
        int carry = 0;
        int ida = a.length()-1;
        int idb = b.length()-1;
       
        while(ida >=0 || idb >= 0){
            if(ida < 0){
                int val = carry + (b.charAt(idb--)-'0');
                sb.append(val%2);
                carry = val/2;
            }
            else if(idb < 0){
                int val = carry + (a.charAt(ida--)-'0');
                sb.append(val%2);
                carry = val/2;
            }
            else{
                int val = carry + (b.charAt(idb--)-'0') + (a.charAt(ida--)-'0');
                sb.append(val%2);
                carry = val/2;
            }
        }
        if(carry > 0)
            sb.append(carry);
        return sb.reverse().toString();
    }


Combination Sum II
public List> combinationSum2(int[] num, int target) {
        List> rst = new ArrayList>();
        Arrays.sort(num);
        comb(rst, new ArrayList(), num, 0, target);
        return rst;
    }
   
    public void comb(List> rst, List list, int[] num, int n, int target){
        if(target == 0){
            rst.add(new ArrayList(list));
            return;
        }
       
        if(n >= num.length || num[n] > target)
            return;
       
        int idx = n;
        while(idx+1 < num.length && num[idx+1] == num[n])
            ++idx;
       
        comb(rst, list, num, idx+1, target);
        list.add(num[n]);
        comb(rst, list, num, n+1, target-num[n]);
        list.remove(list.size()-1);
    }

public List> combinationSum2(int[] candidates, int target) {
        List> rst = new ArrayList>();
        if(candidates == null)
            return rst;
        Arrays.sort(candidates);
        dfs(rst, new ArrayList(), candidates, target, 0);
        return rst;
    }
   
    private void dfs(List> rst, List list, int[] nums, int target, int k){
        if(target == 0){
            rst.add(new ArrayList(list));
            return;
        }
       
        for(int i=k; i target)
                break;
            if(i==k || nums[i] != nums[i-1]){
                list.add(nums[i]);
                dfs(rst, list, nums, target-nums[i], i+1);
                list.remove(list.size()-1);
            }
        }
    }


Jump Game II
public int jump(int[] A) {
        int step = 0;
        int max = -1;
        int area = 0;
        for(int i=0; i area){
                area = max;
                step++;
                max = -1;
            }
            if(A[i]+i > max)
                max = A[i] + i;
        }
        return step;
    }

public int jump(int[] nums) {
        if(nums == null || nums.length <= 1)
            return 0;
       
        int steps = 0;
        int fast = 0;
        int p = 0;
        int q =0;
        while(p <= q){
            fast = Math.max(fast, p+nums[p]);
            if(p == q){
                q = fast;
                steps++;
                if(q >= nums.length-1)
                    break;
            }
            p++;
        }
       
        return q >= nums.length-1 ? steps : -1;
    }


Remove Duplicates from Sorted List II
public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null)
            return head;
       
        if(head.val != head.next.val){
            head.next = deleteDuplicates(head.next);
            return head;
        }
       
        while(head.next != null && head.val == head.next.val)
            head = head.next;
        return deleteDuplicates(head.next);
    }


Group Anagrams
public List> groupAnagrams(String[] strs) {
        Arrays.sort(strs);
        Map> map = new HashMap>();
       
        for(String str : strs){
            String key = getKey(str);
            if(!map.containsKey(key)){
                map.put(key, new ArrayList());
            }
            map.get(key).add(str);
        }
       
        List> rst = new ArrayList>();
        for(List list : map.values())
            rst.add(list);
       
        return rst;
    }
   
    private String getKey(String str){
        char[] chs = str.toCharArray();
        Arrays.sort(chs);
        return String.valueOf(chs);
    }


Word Search
public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        boolean[][] used = new boolean[m][n];
        for(int i=0; i=board.length || y<0 || y >= board[0].length ||
            used[x][y] || board[x][y] != word.charAt(str.length()))
            return false;
       
       
        used[x][y] = true;
        if(exist(board, used, word, str+board[x][y], x-1, y) ||
            exist(board, used, word, str+board[x][y], x+1, y) ||
            exist(board, used, word, str+board[x][y], x, y-1) ||
            exist(board, used, word, str+board[x][y], x, y+1))
            return true;
        used[x][y] = false;
        return false;
    }


Copy List with Random Pointer
public RandomListNode copyRandomList(RandomListNode head) {
        if(head == null)
            return null;
           
        RandomListNode curr = head;
        while(curr != null){
            RandomListNode next = new RandomListNode(curr.label);
            next.next = curr.next;
            curr.next = next;
            curr = next.next;
        }
       
        curr = head;
        while(curr != null){
            curr.next.random = curr.random == null ? null : curr.random.next;
            curr = curr.next.next;
        }
       
        curr = head;
        RandomListNode newhead = curr.next;
        while(curr != null){
            RandomListNode nd = curr.next;
            curr.next = nd.next;
            nd.next = nd.next == null ? null : nd.next.next;
            curr = curr.next;
        }
       
        return newhead;
    }


Clone Graph
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        Map map = new HashMap();
        return cloneNode(node, map);
    }
   
    private UndirectedGraphNode cloneNode(UndirectedGraphNode node, Map map){
        if(node == null)
            return null;
        if(map.containsKey(node.label))
            return map.get(node.label);
           
        UndirectedGraphNode cnode = new UndirectedGraphNode(node.label);
        map.put(node.label, cnode);
        for(UndirectedGraphNode nb : node.neighbors)
            cnode.neighbors.add(cloneNode(nb, map));

        return cnode;
    }


Validate Binary Search Tree
publicboolean isValidBST(TreeNode root){return isValidBST(root,Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);}
 
publicboolean isValidBST(TreeNode p, double min, double max){if(p==null)returntrue;
 
    if(p.val<= min || p.val>= max)returnfalse;
 
    return isValidBST(p.left, min, p.val)&& isValidBST(p.right, p.val, max);}

Add Two Numbers
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        int carry = 0;
       
        while(l1 != null || l2 != null){
            int val = 0;
            if(l1 == null){
                val = l2.val + carry;
                l2 = l2.next;
            }
            else if(l2 == null){
                val = l1.val + carry;
                l1 = l1.next;
            }
            else{
                val = l1.val + l2.val + carry;
                l1 = l1.next;
                l2 = l2.next;
            }
            curr.next = new ListNode(val % 10);
            carry = val / 10;
            curr = curr.next;
        }
        if(carry > 0)
            curr.next = new ListNode(carry);
        return dummy.next;
    }



Two Sum
public int[] twoSum(int[] numbers, int target) {
        Map map = new HashMap();
        int[] rst = new int[2];
       
        for(int i=0; i


Word Break
dp
public boolean wordBreak(String s, Set dict) {
        if(s == null || s.length() == 0)
            return true;
       
        boolean[] dp = new boolean[s.length()+1];
        dp[0] = true;
       
        for(int i=1; i<=s.length(); ++i){
            for(int j=0; j

public boolean wordBreak(String s, Set wordDict) {
        if(s == null || s.length() == 0)
            return true;
       
        boolean[] dp = new boolean[s.length()+1];
        dp[0] = true;
        for(int i=1; i<=s.length(); ++i){
            for(int j=i-1; j>=0; --j){
                String str = s.substring(j, i);
                if(wordDict.contains(str) && dp[j]){
                    dp[i] = true;
                    break;
                }
            }
        }
       
        return dp[s.length()];
    }



3Sum
public List> threeSum(int[] num) {
        List> rst = new ArrayList>();
        if(num.length < 3)
            return rst;
        Arrays.sort(num);
        for(int i=0; i 0)
                    --right;
                else{
                    List list = new ArrayList();
                    list.add(num[i]); list.add(num[left]); list.add(num[right]);
                    rst.add(list);
                    ++left;
                    --right;
                    while(left


Decode Ways
public int numDecodings(String s) {
        if(s == null || s.length() == 0)
            return 0;
        int[] dp = new int[s.length()+1];
        dp[0] = 1;
        dp[1] = s.charAt(0)=='0' ? 0 : 1;
        for(int i=2; i<=s.length(); ++i){
            if(s.charAt(i-1) == '0'){
          if(s.charAt(i-2) == '0' || s.charAt(i-2) > '2')
           return 0;
          dp[i] = dp[i-2];
         }
         else{
          if(s.charAt(i-2) == '0' || Integer.parseInt(s.substring(i-2, i)) > 26)
           dp[i] = dp[i-1];
          else
           dp[i] = dp[i-1] + dp[i-2];
         }
        }
        return dp[s.length()];
    }


Word Ladder
public int ladderLength(String start, String end, Set dict) {
        int rst = 1;
        Set visited = new HashSet();
        Queue queue = new LinkedList();
        int count = 0;
        int num = 1;
        queue.offer(start);
        visited.add(start);
        while(!queue.isEmpty()){
            String node = queue.poll();
            --num;
           
            if(node.equals(end))
                return rst;
           
            char[] chs = node.toCharArray();
            for(int i=0; i



Excel Sheet Column Title
public String convertToTitle(int n) {
        String rst = "";
        while(n > 0){
            rst = (char)('A' + (n-1)%26) + rst;
            n = (n-1)/26;
        }
        return rst;
    }



LRU Cache
public LRUCache(int capacity) {
        map = new HashMap();
        head = new Node(-1, -1);
        tail = head;
        for(int i=1; i map;
    private Node head;
    private Node tail;
   
    class Node{
        public int key;
        public int value;
        public Node prev;
        public Node next;
       
        public Node(int key, int value){
            this.key = key;
            this.value = value;
        }
    }



Convert Sorted List to Binary Search Tree
private ListNode list;
   
    public TreeNode sortedListToBST(ListNode head) {
        int n = 0;
        ListNode curr = head;
        while(curr != null){
            curr = curr.next;
            ++n;
        }
        list = head;
        return sortedListToBST(0, n-1);
    }
   
    private TreeNode sortedListToBST(int start, int end){
        if(start > end)
            return null;
        int mid = start + (end-start)/2;
        TreeNode left = sortedListToBST(start, mid-1);
        TreeNode root = new TreeNode(list.val);
        list = list.next;
        root.left = left;
        root.right = sortedListToBST(mid+1, end);
        return root;
    }


Permutation Sequence
public String getPermutation(int n, int k) {
        List nums = new ArrayList();
        int fac = 1;
       
        for(int i=1; i<=n; ++i){
            nums.add(i);
            fac *= i;
        }
        k--;
        String rst = "";
       
        for(int i=0; i


Longest Substring Without Repeating Characters
public int lengthOfLongestSubstring(String s) {
        int rst = 0;
        Map map = new HashMap();
       
        int left = -1;
        int right = 0;
        while(right < s.length()){
            char ch = s.charAt(right);
            if(!map.containsKey(ch) || map.get(ch) < left){
                map.put(ch, right);
                if(right-left > rst)
                    rst = right-left;
            }
            else{
                left = map.get(ch);
                map.put(ch, right);
            }
            ++right;
        }
        return rst;
    }



Candy
public int candy(int[] ratings) {
  int[] candy = new int[ratings.length];
 
  Arrays.fill(candy, 1);
 
  for(int i=1; i ratings[i-1] && candy[i] <= candy[i-1])
          candy[i] = candy[i-1]+1;
         
  for(int i=candy.length-2; i>=0; --i)
      if(ratings[i] > ratings[i+1] && candy[i] <= candy[i+1])
          candy[i] = candy[i+1]+1;
 
  int num = 0;
  for(int i=0; i


Next Permutation
public void nextPermutation(int[] nums) {
        int index = -1;
        for(int i=nums.length-1; i>0; --i)
            if(nums[i] > nums[i-1]){
                index = i-1;
                break;
            }
         if(index == -1){
            Arrays.sort(nums);
            return;
         }
         
         for(int i=nums.length-1; i>index; --i){
             if(nums[i] > nums[index]){
                 int temp = nums[i];
                 nums[i] = nums[index];
                 nums[index] = temp;
                 break;
             }
         }
         
         Arrays.sort(nums, index+1, nums.length);
    }



Reverse Nodes in k-Group
public ListNode reverseKGroup(ListNode head, int k) {
        if(head == null || head.next == null || k <= 1)
            return head;
       
        ListNode curr = head;
        int n = 1;
        while(n++ < k){
            curr = curr.next;
            if(curr == null)
                return head;
        }
        curr.next = reverseKGroup(curr.next, k);
        ListNode end = curr;
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        while(dummy.next != end){
            ListNode temp = curr.next;
            curr.next = dummy.next;
            dummy.next = dummy.next.next;
            curr.next.next = temp;
        }
       
        return dummy.next;
    }



Distinct Subsequences
public int numDistinct(String S, String T) {
        int[][] dp = new int[T.length()+1][S.length()+1];
       
        for(int i=0; i


Recover Binary Search Tree
private TreeNode first, second;
    boolean find;
   
    public void recoverTree(TreeNode root) {
        first = new TreeNode(Integer.MIN_VALUE);
        find = false;
       
        recover(root);
       
        if(first != null && second != null){
            int v = first.val;
            first.val = second.val;
            second.val = v;
        }
    }
   
    public void recover(TreeNode node){
        if(node == null)
            return;
        recover(node.left);
        if(node.val < first.val){
            second = node;
            find = true;
        }
        else if(!find){
            first = node;
        }
        recover(node.right);
    }


TreeNode first;
    TreeNode second;
    TreeNode iter;
   
    public void recoverTree(TreeNode root) {
        inorder(root);
        if(first != null && second != null){
            int temp = first.val;
            first.val = second.val;
            second.val = temp;
        }
    }
   
    private void inorder(TreeNode node){
        if(node == null)
            return;
       
        inorder(node.left);
       
        if(iter != null && node.val < iter.val){
            if(first == null){
                first = iter;
            }
            second = node;
        }
       
        iter = node;
        inorder(node.right);
    }


Reverse Words in a String
split() 会有""结果
public String reverseWords(String s) {
        String[] tokens = s.trim().split(" ");
        StringBuilder rst = new StringBuilder();
        
        for(int i=tokens.length-1; i>=0; --i){
            if(tokens[i] == null || tokens[i].length()==0)
                continue;
            rst.append(tokens[i]+" ");
        }
        
        return rst.toString().trim();
    }


First Missing Positive
public int firstMissingPositive(int[] A) {
        for(int i=0; i A.length || A[A[i]-1] == A[i]){
                ++i;
                continue;
            }
            int v = A[A[i]-1];
            A[A[i]-1] = A[i];
            A[i] = v;
        }
        for(int i=0; i


Largest Rectangle in Histogram
public int largestRectangleArea(int[] height) {
        int max = 0;
        Stack stack = new Stack();
        for(int i=0; i height[stack.peek()]){
                stack.push(i);
                continue;
            }
            while(!stack.empty() && height[i] <= height[stack.peek()]){
                int ind = stack.pop();
                if(stack.empty())
                    max = Math.max(max, height[ind] * (i-0));
                else
                    max = Math.max(max, height[ind] * (i-stack.peek()-1));
            }
            stack.push(i);
        }
       
        while(!stack.empty()){
            int ind = stack.pop();
            if(stack.empty())
                max = Math.max(max, height[ind] * height.length);
            else
                max = Math.max(max, height[ind] * (height.length-stack.peek()-1));
        }
       
        return max;
    }


Best Time to Buy and Sell Stock III
public int maxProfit(int[] prices) {
        if(prices.length < 2)
            return 0;
           
        int[] left = new int[prices.length];
        int[] right = new int[prices.length];
       
        int min = prices[0];
        int p = 0;
        for(int i=0; i=0; --i){
            if(prices[i] > max)
                max = prices[i];
            p = Math.max(p, max-prices[i]);
            right[i] = p;
        }
       
        max = 0;
        for(int i=0; i


Rotate List
public ListNode rotateRight(ListNode head, int n) {
        if(head == null)
            return head;
        int num = 1;
        ListNode curr = head;
        while(curr.next != null){
            curr = curr.next;
            ++num;
        }
        curr.next = head;
        for(int i=0; i


Sort List
快慢指针找中间结点!


Simplify Path
public String simplifyPath(String path) {
        Stack stack = new Stack();
        String[] tokens = path.split("/");
       
        for(int i=0; i


4Sum
public List> fourSum(int[] num, int target) {
        List> rst = new ArrayList>();
        if(num.length < 4)
            return rst;
        Arrays.sort(num);
        for(int i=0; i0 && num[i] == num[i-1])
                continue;
            for(int j=i+1; ji+1 && num[j] == num[j-1])
                    continue;
                int left = j+1;
                int right = num.length-1;
                while(left < right){
                    if(num[i] + num[j] + num[left] + num[right] == target){
                        List list = new ArrayList();
                        list.add(num[i]); list.add(num[j]);
                        list.add(num[left]); list.add(num[right]);
                        rst.add(list);
                        ++left;
                        while(left < right && num[left] == num[left-1])
                            ++left;
                        --right;
                        while(left < right && num[right] == num[right+1])
                            --right;
                    }
                    else if(num[i] + num[j] + num[left] + num[right] < target){
                        ++left;
                        //while(left < right && num[left] == num[left-1])
                         //   ++left;
                    }
                    else{
                        --right;
                        //while(left < right && num[right] == num[right+1])
                        //    --right;
                    }
                }
            }
        }
        return rst;
    }


Sudoku Solver
public void solveSudoku(char[][] board) {
        dfs(board);
    }
   
    private boolean dfs(char[][] board){
        for(int i=0; i<9; ++i)
            for(int j=0; j<9; ++j){
                if(board[i][j] != '.')
                    continue;
                for(int x=1; x<10; ++x){
                    if(isValid(board, i, j, x)){
                        board[i][j] = (char)('0'+x);
                        if(dfs(board))
                            return true;
                        board[i][j] = '.';
                    }
                }
                return false;
            }
        return true;
    }
   
    private boolean isValid(char[][] board, int x, int y, int v){
        for(int i=0; i<9; ++i)
            if(i!=x && board[i][y]-'0' == v || i!=y && board[x][i]-'0' == v)
                return false;
        for(int i=0; i<3; ++i)
            for(int j=0; j<3; ++j){
                int row = x/3*3+i;
                int col = y/3*3+j;
                if(row != x && col != y && board[row][col]-'0' == v)
                    return false;
            }
        return true;
    }



Longest Palindromic Substring
public String longestPalindrome(String s) {
        if(s == null || s.length()==0)
            return s;
        boolean[][] p = new boolean[s.length()][s.length()];
        int maxLen = 1;
        int start = 0;
        for(int i=0; i=0; --j){
                p[j][i] = (s.charAt(i)==s.charAt(j)) && (j+1 == i || p[j+1][i-1]);
                if(p[j][i] && i-j+1 > maxLen){
                    maxLen = i-j+1;
                    start = j;
                }
            }
        }
        return s.substring(start, start+maxLen);
    }


Merge k Sorted Lists
public ListNode mergeKLists(List lists) {
        if(lists == null || lists.size() == 0)
            return null;
        if(lists.size() == 1)
            return lists.get(0);
       
        int mid = lists.size()/2;
        List half = new ArrayList();
        while(mid-- > 0){
            half.add(lists.get(0));
            lists.remove(0);
        }
       
        ListNode left = mergeKLists(lists);
        ListNode right = mergeKLists(half);
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        while(left != null && right != null){
            if(left.val < right.val){
                curr.next = left;
                left = left.next;
            }
            else{
                curr.next = right;
                right = right.next;
            }
            curr = curr.next;
        }
        while(left != null){
            curr.next = left;
            curr = curr.next;
            left = left.next;
        }
        while(right != null){
            curr.next = right;
            curr = curr.next;
            right = right.next;
        }
       
        return dummy.next;
    }


Longest Valid Parentheses
public int longestValidParentheses(String s) {
        if(s == null || s.length() <= 1)
            return 0;
       
        int[] dp = new int[s.length()];
        int len = 0;
       
        for(int i=1; i= 0 ? dp[i-2]+2 : 2;
            }
            else{
                int v = dp[i-1];
                if(i-1-v >= 0 && s.charAt(i-1-v) == '('){
                    dp[i] = i-2-v >= 0 ? v+2+dp[i-2-v] : v+2;     // ()(())
                }
            }
           
            len = Math.max(len, dp[i]);
        }
       
        return len;
    }


Binary Tree Maximum Path Sum
public int maxPathSum(TreeNode root) {
        max = Integer.MIN_VALUE;
        dfs(root);
        return max;
    }
   
    private int max;
   
    private int dfs(TreeNode node){
        if(node == null)
            return 0;
           
        int left = dfs(node.left);
        int right = dfs(node.right);
       
        int v = node.val;
        if(left > 0)
            v += left;
        if(right > 0)
            v += right;
        max = Math.max(v, max);
       
        if(left < 0 && right < 0)
            return node.val;
        return left>right ? left+node.val : right+node.val;
    }


Reorder List
public void reorderList(ListNode head) {
        if(head == null || head.next == null || head.next.next == null)
            return;
       
        ListNode fast = head;
        ListNode slow = head;
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode mid = slow.next;
        slow.next = null;
       
        if(fast.next != null) fast = fast.next;
        while(mid != fast){
            slow = fast.next;
            fast.next = mid;
            mid = mid.next;
            fast.next.next = slow;
        }
       
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        while(head != null || mid != null){
            if(head != null){
                curr.next = head;
                head = head.next;
                curr = curr.next;
            }
            if(mid != null){
                curr.next = mid;
                mid = mid.next;
                curr = curr.next;
            }
        }
       
        head = dummy.next;
    }



Min Stack
private List stack = new ArrayList();
    private List minStack = new ArrayList();
   
    public void push(int x) {
        stack.add(x);
        if(minStack.isEmpty() || x <= minStack.get(minStack.size()-1))
            minStack.add(x);
    }

    public void pop() {
        if(stack.isEmpty())
            return;
        if(stack.get(stack.size()-1).equals(minStack.get(minStack.size()-1)))
            minStack.remove(minStack.size()-1);
        stack.remove(stack.size()-1);
    }

    public int top() {
        if(stack.isEmpty())
            return 0;
        return stack.get(stack.size()-1);
    }

    public int getMin() {
        if(minStack.isEmpty())
            return 0;
        return minStack.get(minStack.size()-1);
    }


Evaluate Reverse Polish Notation
public int evalRPN(String[] tokens) {
        Stack stack = new Stack();
        for(String str : tokens){
            if(str.equals("+")){
                int y = stack.pop();
                int x = stack.pop();
                stack.push(x+y);
            }
            else if(str.equals("*")){
                int y = stack.pop();
                int x = stack.pop();
                stack.push(x*y);
            }
            else if(str.equals("/")){
                int y = stack.pop();
                int x = stack.pop();
                stack.push(x/y);
            }
            else if(str.equals("-")){
                int y = stack.pop();
                int x = stack.pop();
                stack.push(x-y);
            }
            else{
                stack.push(Integer.parseInt(str));
            }
        }
        return stack.peek();
    }



Palindrome Partitioning II
public int minCut(String s) {
        if(s == null || s.length() < 2)
            return 0;
           
        boolean[][] p = new boolean[s.length()][s.length()];
        int[] dp = new int[s.length()];
        p[0][0] = true;
        for(int i=1; i=0; --j){
                if((j == i-1 || p[j+1][i-1] )&& s.charAt(i)==s.charAt(j)){
                    p[j][i] = true;
                    int cut = j == 0 ? 0 : dp[j-1]+1;
                    minc = Math.min(minc, cut);
                }
            }
            dp[i] = minc;
        }
       
        return dp[s.length()-1];
    }


Regular Expression Matching
public boolean isMatch(String s, String p) {
        return isMatch(s, 0, p, 0);
    }
   
    private boolean isMatch(String s, int sl, String p, int pl){
        if(pl == p.length())
            return sl == s.length();
           
        if(pl == p.length()-1 || p.charAt(pl+1) != '*'){
            if(sl == s.length())
                return false;
            return (s.charAt(sl)==p.charAt(pl) || p.charAt(pl)=='.') ? isMatch(s, sl+1, p, pl+1) : false;
        }
        else{
            for(int i=sl; i


Surrounded Regions
public void solve(char[][] board) {
        if(board == null || board.length==0)
            return;
           
        Stack stackr = new Stack();
        Stack stackc = new Stack();
       
        for(int i=0; i=board.length || c<0 || c>=board[0].length || board[r][c] != 'O')
                continue;
            board[r][c] = 'Y';
            stackr.push(r+1); stackc.push(c);
            stackr.push(r); stackc.push(c+1);
            stackr.push(r-1); stackc.push(c);
            stackr.push(r); stackc.push(c-1);
        }
       
        for(int i=0; i



Wildcard Matching
public boolean isMatch(String s, String p) {
        if(p == null)
            return s == null;
        int i = 0;
        int j = 0;
        int star = -1;
        int mark = -1;
        while(i < s.length()){
            if(j < p.length() && p.charAt(j) == '*'){
                star = j++;
                mark = i;
            }
            else if(j < p.length() && (p.charAt(j) == '?' || p.charAt(j) == s.charAt(i))){
                ++i;
                ++j;
            }
            else if(star != -1){
                j = star + 1;
                i = ++mark;
            }
            else
                return false;
        }
        while(j < p.length() && p.charAt(j)=='*')
            ++j;
        return j == p.length();
    }



Max Points on a Line
public int maxPoints(Point[] points) {
        int max = 0;
        for(int i=0; i map = new HashMap();
            int infinity = 1;
            int same = 0;
            int count = 1;
            for(int j=i+1; j


Maximal Rectangle
O(n^3)
public int maximalRectangle(char[][] matrix) {
        if(matrix == null || matrix.length == 0)
            return 0;
 int[][] arr = new int[matrix.length][matrix[0].length];
 for(int i=0; i=0; --h){
   if(arr[h][j] < w)
    w = arr[h][j];
   max = Math.max(max,w*(i-h+1));
}
}
}
return max;
}



O(n^2)
largestRectangleArea on histogram

public int maximalRectangle(char[][] matrix) {
        if(matrix == null)
            return 0;
        if(matrix.length == 0 || matrix[0].length == 0)
            return 0;
           
        int r = matrix.length;
        int c = matrix[0].length;
       
        int[] height = new int[c];
       
        int area = 0;
       
        for(int i=0; i stack = new Stack();
        for(int i=0; i height[stack.peek()]){
                stack.push(i);
                continue;
            }
            while(!stack.empty() && height[i] <= height[stack.peek()]){
                int ind = stack.pop();
                if(stack.empty())
                    max = Math.max(max, height[ind] * (i-0));
                else
                    max = Math.max(max, height[ind] * (i-stack.peek()-1));
            }
            stack.push(i);
        }
       
        while(!stack.empty()){
            int ind = stack.pop();
            if(stack.empty())
                max = Math.max(max, height[ind] * height.length);
            else
                max = Math.max(max, height[ind] * (height.length-stack.peek()-1));
        }
       
        return max;
    }


Multiply Strings
public String multiply(String num1, String num2) {
        StringBuilder sb1 = new StringBuilder(num1);
        StringBuilder sb2 = new StringBuilder(num2);
        sb1.reverse();
        sb2.reverse();
       
        int[] num = new int[num1.length()+num2.length()];
       
        for(int i=0; i=0 && num[i] == 0)
            i--;
        while(i >=0){
            rst += num[i--];
        }
        return rst.equals("") ? "0" : rst;
    }


Insert Interval
public List insert(List intervals, Interval newInterval) {
        List rst = new ArrayList();
        boolean done = false;
        for(Interval curr : intervals){
            if(done){
                rst.add(curr);
            }
            else if(newInterval.end < curr.start){
                rst.add(newInterval);
                rst.add(curr);
                done = true;
            }
            else if(newInterval.start > curr.end){
                rst.add(curr);
            }
            else{
                newInterval.start = Math.min(newInterval.start, curr.start);
                newInterval.end = Math.max(newInterval.end, curr.end);
            }
        }
        if(!done)
            rst.add(newInterval);
        return rst;
    }


Factorial Trailing Zeroes
public int trailingZeroes(int n) {
        int num = 0;
        while(n >= 5){
            num += n/5;
            n /= 5;
        }
        return num;
    }



Maximum Gap
radix sort
public int maximumGap(int[] nums) {
        if(nums.length <= 1)
            return 0;
        Map> map = new HashMap>();
        for(int x : nums){
            int key = x%10;
            if(!map.containsKey(key))
                map.put(key, new ArrayList());
            map.get(key).add(x);
        }
       
        int d = 10;
        for(int i=0; i<9; ++i){
            Map> nmap = new HashMap>();
            for(List list : map.values()){
                for(int x : list){
                    int key = (x/d)%10;
                    if(!nmap.containsKey(key))
                        nmap.put(key, new ArrayList());
                    nmap.get(key).add(x);
                }
            }
            map = nmap;
            d *= 10;
        }
       
        int gap = 0;
        int pre = -1;
        for(int j=0; j<10; ++j){
            List list = map.get(j);
            if(list == null)
                    continue;
            for(int x : list){
                if(pre == -1){
                    pre = x;
                    continue;
                }
                gap = Math.max(gap, x - pre);
                pre = x;
            }
        }
       
        return gap;
    }


Compare Version Numbers
public int compareVersion(String version1, String version2) {
        String[] v1 = version1.split("[.]");
        String[] v2 = version2.split("[.]");
       
        int len = Math.max(v1.length, v2.length);
        for(int i=0; i= v1.length){
                if(Integer.parseInt(v2[i]) != 0)
                    return -1;
                continue;
            }
            if(i >= v2.length){
                if(Integer.parseInt(v1[i]) != 0)
                    return 1;
                continue;
            }
            if(Integer.parseInt(v1[i]) > Integer.parseInt(v2[i]))
                return 1;
            if(Integer.parseInt(v1[i]) < Integer.parseInt(v2[i]))
                return -1;
        }
        return 0;
    }


Excel Sheet Column Number
public int titleToNumber(String s) {
        if(s == null || s.length() == 0)
            return 0;
       
        int rst = 0
        for(int i=0; i


Binary Search Tree Iterator
public class BSTIterator {
   
    private Stack stack;
    private TreeNode p;
    public BSTIterator(TreeNode root) {
        p = root;
        stack = new Stack();
       
        while(p != null){
            stack.push(p);
            p = p.left;
        }
       
    }
    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return !stack.isEmpty();
    }
    /** @return the next smallest number */
    public int next() {
        TreeNode next = stack.pop();
        p = next.right;
        while(p != null){
            stack.push(p);
            p = p.left;
        }
        return next.val;
    }
}


Dungeon Game
public int calculateMinimumHP(int[][] dungeon) {
        if(dungeon == null || dungeon.length == 0 || dungeon[0].length == 0)
            return 0;
       
        int r = dungeon.length;
        int c = dungeon[0].length;
        int[][] dp = new int[r][c];
       
        dp[r-1][c-1] = Math.max(-dungeon[r-1][c-1]+1, 1);
        for(int i=r-2; i>=0; --i){
            dp[i][c-1] = Math.max(1, dp[i+1][c-1] - dungeon[i][c-1]);
        }
        for(int i=c-2; i>=0; --i){
            dp[r-1][i] = Math.max(1, dp[r-1][i+1] - dungeon[r-1][i]);
        }
       
        for(int i=r-2; i>=0; --i){
            for(int j=c-2; j>=0; --j){
               
                dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j]);
            }
        }
       
        return dp[0][0];
    }


Largest Number
public String largestNumber(int[] nums) {
        String[] strs = new String[nums.length];
  for(int i=0; i=0; --i)
            rst += strs[i];
       
        return rst.charAt(0) == '0' ? "0" : rst;
    }
   
    public static class Comp implements Comparator{
        public int compare(String a, String b){
            String ab = a + b;
            String ba = b + a;
            return ab.compareTo(ba);
        }
    }

public String largestNumber(int[] nums) {
        Integer[] A = new Integer[nums.length];
        for(int i=0; i{
        public int compare(Integer a, Integer b){
            String sa = String.valueOf(a);
            String sb = String.valueOf(b);
            return (sa+sb).compareTo(sb+sa);
        }
    }



Repeated DNA Sequences
public List findRepeatedDnaSequences(String s) {
        List list = new ArrayList();
        if(s == null || s.length() <= 10)
            return list;
       
        Map map = new HashMap();
       
        for(int i=0; i


Binary Tree Right Side View
public List rightSideView(TreeNode root) {
        List rst = new ArrayList();
        if(root == null)
            return rst;
       
        Queue queue = new LinkedList();
        queue.offer(root);
        int num = 1;
        while(!queue.isEmpty()){
            int count = 0;
            rst.add(queue.peek().val);
            for(int i=0; i


Number of Islands
public int numIslands(char[][] grid) {
        if(grid == null || grid.length == 0 || grid[0].length == 0)
            return 0;
       
        int count = 1;
        for(int i=0; i= grid.length)
            return;
        if(c < 0 || c >= grid[0].length)
            return;
        if(grid[r][c] != '1')
            return;
        grid[r][c] = (char)(cl+'0');
        color(grid, r-1, c, cl);
        color(grid, r+1, c, cl);
        color(grid, r, c-1, cl);
        color(grid, r, c+1, cl);
    }


Bitwise AND of Numbers Range
public int rangeBitwiseAnd(int m, int n) {
        int rst = 0;
        int d = 0;
        while(m > 0){
            if(n == m)
                rst += (m&1)<>= 1;
            n >>= 1;
            ++d;
        }
        return rst;
    }


Course Schedule
public boolean canFinish(int numCourses, int[][] prerequisites) {
        Map> nodes = new HashMap>();
        for(int i=0; i());
       
        for(int i=0; i visited = new HashSet();
        Set valid = new HashSet();
        for(int i=0; i visited, Set valid, Map> nodes){
        if(valid.contains(id))
            return true;
        for(int next : nodes.get(id)){
            if(visited.contains(next))
                return false;
            visited.add(next);
            if(!check(next, visited, valid, nodes))
                return false;
            valid.add(next);
            visited.remove(next);
        }
        return true;
    }


Minimum Size Subarray Sum
positive array
public int minSubArrayLen(int s, int[] nums) {
        if(nums.length == 0)
            return 0;
        int len = 0;
        int left = 0;
        int right = 0;
        int sum = nums[0];
        while(right < nums.length){
            if(sum >= s){
                len = len == 0 ? right-left+1 : Math.min(len, right-left+1);
                sum -= nums[left++];
                continue;
            }
            if(right < nums.length-1)
                sum += nums[++right];
            else
                break;
        }
        return len;
    }



House Robber
public int rob(int[] nums) {
        if(nums.length == 0)
            return 0;
        int[] dp = new int[nums.length+1];
        dp[1] = nums[0];
       
        for(int i=2; i


Kth Largest Element in an Array
public int findKthLargest(int[] nums, int k) {
        PriorityQueue q = new PriorityQueue();
        for(int x : nums){
            if(q.size() < k){
                q.offer(x);
                continue;
            }
            if(x > q.peek()){
                q.poll();
                q.offer(x);
            }
        }
        return q.peek();
    }
QuickSort Partition O(n)



Combination Sum III
public List> combinationSum3(int k, int n) {
        List> rst = new ArrayList>();
        if(k <= 0 || n <= 0)
            return rst;
        Set set = new HashSet();
        dfs(rst, new ArrayList(), set, 1, k, n);
        return rst;
    }
private void dfs(List> rst, List list, Set set, int s, int k, int n){
        if(k == 0 && n == 0){
            rst.add(new ArrayList(list));
            return;
        }
        if(k == 0 || n <= 0)
            return;
       
        for(int i=s; i<=9; ++i){
            if(!set.contains(i)){
                list.add(i);
                set.add(i);
                dfs(rst, list, set, i+1, k-1, n-i);
                set.remove(i);
                list.remove(list.size()-1);
            }
        }
       
    }


 
  

Contains Duplicate II
public boolean containsNearbyDuplicate(int[] nums, int k) {
        if(nums == null || nums.length < 2)
            return false;
           
        Map map = new HashMap();
        for(int i=0; i


Valid Anagram
public boolean isAnagram(String s, String t) {
        char[] sch = s.toCharArray();
        char[] tch = t.toCharArray();
        Arrays.sort(sch);
        Arrays.sort(tch);
        String ns = String.valueOf(sch);
        String nt = String.valueOf(tch);
        return ns.equals(nt);
    }



Kth Smallest Element in a BST
int rst;
    public int kthSmallest(TreeNode root, int k) {
        inorder(root, k);
        return rst;
    }
   
    private int inorder(TreeNode root, int k){
        if(root == null)
            return 0;
        int num = inorder(root.left, k);
        if(num >= k)
            return k+1;
        num++;
        if(num == k){
            rst = root.val;
            return num;
        }
        return num + inorder(root.right, k-num);
    }

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?
  1. Try to utilize the property of a BST.
  2. What if you could modify the BST node's structure?
  3. The optimal runtime complexity is O(height of BST).
每个树节点可以设一个值:其下所有节点数

House Robber II
public int rob(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
        if(nums.length == 1)
            return nums[0];
        if(nums.length == 2)
            return Math.max(nums[0], nums[1]);
       
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for(int i=2; i


Fraction to Recurring Decimal
public String fractionToDecimal(int numerator, int denominator) {
        if (numerator == 0) return "0";
        if (denominator == 0) return "";
         
        String ans = "";
         
        //如果结果为负数
        if ((numerator < 0) ^ (denominator < 0)) {
            ans += "-";
        }
         
        //下面要把两个数都转为正数,为避免溢出,int转为long
        long num = numerator, den = denominator;
        num = Math.abs(num);
        den = Math.abs(den);
         
        //结果的整数部分
        long res = num / den;
        ans += String.valueOf(res);
         
        //如果能够整除,返回结果
        long rem = (num % den) * 10;
        if (rem == 0) return ans;
         
        //结果的小数部分
        HashMap map = new HashMap();
        ans += ".";
        while (rem != 0) {
            //如果前面已经出现过该余数,那么将会开始循环
            if (map.containsKey(rem)) {
                int beg = map.get(rem); //循环体开始的位置
                String part1 = ans.substring(0, beg);
                String part2 = ans.substring(beg, ans.length());
                ans = part1 + "(" + part2 + ")";
                return ans;
            }
             
            //继续往下除
            map.put(rem, ans.length());
            res = rem / den;
            ans += String.valueOf(res);
            rem = (rem % den) * 10;
        }
         
        return ans;
    }


Majority Element II
public List majorityElement(int[] nums) {
        List rst = new ArrayList();
        if(nums == null || nums.length == 0)
            return rst;
        if(nums.length < 2){
            rst.add(nums[0]);
            return rst;
        }
       
        int a = nums[0];
        int b = 0;
        int ac = 1;
        int bc = 0;
       
        for(int i=1; i nums.length/3)
            rst.add(a);
        if(bc > nums.length/3)
            rst.add(b);
       
        return rst;
    }



Reverse Bits
public int reverseBits(int n) {
        int rst = 0;
        for(int i=0; i<32; ++i){
            rst += (n >> i & 1) << 31-i;
        }
        return rst;
    }


Happy Number
public boolean isHappy(int n) {
        Set set = new HashSet();
        while(n != 1){
            if(set.contains(n))
                return false;
            set.add(n);
            int m = 0;
            while(n > 0){
                int d = n%10;
                m += d*d;
                n /= 10;
            }
            n = m;
        }
        return true;
    }


Reverse Linked List
public ListNode reverseList(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        while(head != null && head.next != null){
            ListNode node = head.next;
            head.next = node.next;
            node.next = dummy.next;
            dummy.next = node;
        }
        return dummy.next;
    }

// without dummy
public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null)
            return head;
       
        ListNode left = head;
        ListNode right = head;
       
        while(right.next != null){
            ListNode node = right.next;
            right.next = right.next.next;
            node.next = left;
            left = node;
        }
       
        return left;
    }


Number of 1 Bits
public int hammingWeight(int n) {
        int count = 0;
        for(int i=0; i<32; ++i){
            count += n >> i & 1;
        }
       
        return count;
    }



Best Time to Buy and Sell Stock IV
locale[i][j] ith day involved in the jth transaction.
global[i][j] ith day may be not involved in the jth transaction. it is the global max value.

public int maxProfit(int k, int[] prices) {
        if(prices.length <= 1 || k <= 0)
            return 0;
       
       // if (k == 1000000000)
       // return 1648961;
 
        int[][] local = new int[prices.length][k+1];
        int[][] global = new int[prices.length][k+1];
       
        for(int j=1; j<=k; ++j)
            for(int i=1; i


Rotate Array
public void rotate(int[] nums, int k) {
        k %= nums.length;
        if(k <= 0)
            return;
           
        int left = 0;
        int right = nums.length-k-1;
        while(left < right){
            swap(nums, left++, right--);
        }
        left = nums.length-k;
        right = nums.length-1;
        while(left < right){
            swap(nums, left++, right--);
        }
        left = 0;
        right = nums.length-1;
        while(left < right){
            swap(nums, left++, right--);
        }
    }
   
    private void swap(int[] nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }


Remove Linked List Elements
public ListNode removeElements(ListNode head, int val) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode curr = dummy;
       
        while(curr.next != null){
            if(curr.next.val == val)
                curr.next = curr.next.next;
            else
                curr = curr.next;
        }
       
        return dummy.next;
    }


Count Primes
public int countPrimes(int n) {
        boolean[] isPrime = new boolean[n];
        for (int i = 2; i < n; i++)
            isPrime[i] = true;
       
        for(int i=2; i*i


// my solution
public int countPrimes(int n) {
        List primes = new ArrayList();
       
        for(int i=2; i i)
                    break;
                if(i%x == 0){
                    isprime = false;
                    break;
                }
            }
            if(isprime){
                primes.add(i);
            }
        }
       
        return primes.size();
    }


Isomorphic Strings
public boolean isIsomorphic(String s, String t) {
        if(s.length() != t.length())
            return false;
       
        Map map = new HashMap();
       
        for(int i=0; i



Implement Trie (Prefix Tree)
class TrieNode {
    // Initialize your data structure here.
    public boolean isLeaf;
    public Map children;
    public TrieNode() {
        children = new HashMap ();
    }
}

public class Trie {
    private TrieNode root;

    public Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    public void insert(String word) {
        if(word == null || word.length() == 0)
            return;
        TrieNode node = root;
        for(int i=0; i


Course Schedule II
public int[] findOrder(int numCourses, int[][] prerequisites) {
        Map> map = new HashMap>();
        Map> connect = new HashMap>();
        for(int i=0; i());
            connect.put(i, new HashSet());
        }
           
        for(int i=0; i q = new LinkedList();
        for(int i=0; i



Add and Search Word - Data structure design
public class WordDictionary {
   
    private class Node{
        public boolean isleaf;
        public Map children;
        public Node(){
            children = new HashMap();
        }
    }
   
    private Node root = new Node();

    // Adds a word into the data structure.
    public void addWord(String word) {
        if(word == null || word.length() == 0)
            return;
        Node node = root;
        for(int i=0; i


Contains Duplicate
public boolean containsDuplicate(int[] nums) {
        if(nums == null || nums.length <= 1)
            return false;
        Set set = new HashSet();
        for(int x : nums){
            if(set.contains(x))
                return true;
            set.add(x);
        }
       
        return false;
    }


Different Ways to Add Parentheses
public List diffWaysToCompute(String input) {
        List rst = new ArrayList();
        if(input == null || input.length() == 0)
            return rst;
       
        boolean op = false;
        for(int i=1; i left = diffWaysToCompute(input.substring(0, i));
                List right = diffWaysToCompute(input.substring(i+1, input.length()));
                for(int x : left)
                    for(int y : right)
                        rst.add(x - y);
                op = true;
            }
            else if(ch == '+'){
                List left = diffWaysToCompute(input.substring(0, i));
                List right = diffWaysToCompute(input.substring(i+1, input.length()));
                for(int x : left)
                    for(int y : right)
                        rst.add(x + y);
                op = true;
            }
            else if(ch == '*'){
                List left = diffWaysToCompute(input.substring(0, i));
                List right = diffWaysToCompute(input.substring(i+1, input.length()));
                for(int x : left)
                    for(int y : right)
                        rst.add(x * y);
                op = true;
            }
        }
        if(!op){
            rst.add(Integer.parseInt(input));
        }
        return rst;
    }



Maximal Square
public int maximalSquare(char[][] matrix) {
        if(matrix == null)
            throw new IllegalArgumentException();
        if(matrix.length == 0 || matrix[0].length == 0)
            return 0;
       
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] dp = new int[m][n];
        int max = 0;
       
        for(int i=0; i


Merge Intervals
public List merge(List intervals) {
        Collections.sort(intervals, new Comp());
       
        List rst = new ArrayList();
        if(intervals == null || intervals.size() == 0)
            return intervals;
       
        Interval inter = null;
        for(Interval it : intervals){
            if(inter == null){
                inter = it;
                continue;
            }
            if(inter.end >= it.start){
                inter.end = Math.max(inter.end, it.end);
                continue;
            }
            rst.add(inter);
            inter = it;
        }
        rst.add(inter);
       
        return rst;
    }
   
    private static class Comp implements Comparator{
        public int compare(Interval inter1, Interval inter2){
            return inter1.start - inter2.start;
        }
    }



Binary Tree Paths
public List binaryTreePaths(TreeNode root) {
        List rst = new ArrayList();
        dfs(rst, new ArrayList(), root);
        return rst;
    }
   
    private void dfs(List rst, List list, TreeNode node){
        if(node == null)
            return;
       
        list.add(node.val);
        if(node.left == null && node.right == null){
            String str = "" + list.get(0);
            for(int i=1; i


Word Pattern
public boolean wordPattern(String pattern, String str) {
        String[] strs = str.split(" ");
        Map map = new HashMap();
        int index = 0;
        for(int i=0; i= pattern.length())
                return false;
            char ch = pattern.charAt(index++);
            if(map.containsKey(ch)){
                if(!map.get(ch).equals(strs[i]))
                    return false;
                continue;
            }
            if(map.containsValue(strs[i]))
                return false;
            map.put(ch, strs[i]);
        }
        return index == pattern.length();
    }


Minimum Window Substring
public String minWindow(String s, String t) {
        if(s == null || t == null)
            throw new IllegalArgumentException();
        if(s.length() == 0 || t.length() == 0)
            return "";
       
        Map map = new HashMap();
        int count = 0;
        for(int i=0; i


Lowest Common Ancestor of a Binary Search Tree
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null)
            return null;
        int min = Math.min(q.val, p.val);
        int max = Math.max(q.val, p.val);
       
        if(root.val == min || root.val == max || root.val > min && root.val < max)
            return root;
       
        if(root.val < min)
            return lowestCommonAncestor(root.right, p, q);
        else
            return lowestCommonAncestor(root.left, p, q);
    }



Lowest Common Ancestor of a Binary Tree
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null)
            return null;
        if(root == p || root == q)
            return root;
       
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
       
        if(left == null && right == null)
            return null;
        if(left != null && right != null)
            return root;
        return left != null ? left : right;
    }


H-Index
public int hIndex(int[] citations) {
        int[] counts = new int[citations.length+1];
       
        for(int num : citations)
            if(num > citations.length)
                counts[citations.length]++;
            else
                counts[num]++;
       
        int sum = 0;
        for(int i=counts.length-1; i>0; --i){
            int count = sum + counts[i];
            if(count >= i)
                return i;
            sum = count;
        }
        return 0;
    }



H-Index II
O(logn)
public int hIndex(int[] citations) {
        int left = 0;
        int right = citations.length-1;
        int total = citations.length;
        int hindex = 0;
       
        while(left <= right){
            int mid = left + (right-left)/2;
            if(citations[mid] >= total - mid){
                hindex = Math.max(hindex, total - mid);
                right = mid-1;
            }
            else
                left = mid+1;
        }
       
        return hindex;
    }



Sliding Window Maximum
public int[] maxSlidingWindow(int[] nums, int k) {
        if(k > nums.length)
            throw new IllegalArgumentException();
        if(nums.length == 0)
            return nums;
           
        int[] rst = new int[nums.length-k+1];
        Deque deq = new ArrayDeque();
       
        int index = 0;
        for(int i=0; i= k-1)
                rst[index++] = nums[deq.getFirst()];
        }
       
        return rst;
    }















你可能感兴趣的:(Leetcode 经典题目题解)