• LeetCode 全解(bug free 训练)


    1.Two Sum

    Given an array of integers, return indices of the two numbers such that they add up to a specific target.
    You may assume that each input would have exactly one solution, and you may not use the same element twice.
    

    使用hash

    public int[] twoSum(int[] nums, int target) {
            int[] res = new int[2];
            if (nums == null || nums.length < 2) {
                return res;
            }
            HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (map.containsKey(target - nums[i])) {
                    res[0] = map.get(target - nums[i]);
                    res[1] = i;
                    return res;
                }
                map.put(nums[i], i);
            }
            return res;
        }
    View Code

    2.Add Two Numbers

    You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
    You may assume the two numbers do not contain any leading zero, except the number 0 itself.
    Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
    Output: 7 -> 0 -> 8
    

    dummyHead cur控制。carry携带进位

    def addTwoNumbers(self, l1, l2):
            """
            :type l1: ListNode
            :type l2: ListNode
            :rtype: ListNode
            """
            dummyHead = ListNode(0)
            cur = dummyHead
            carry = 0
            while (l1 or l2):
                sum = 0
                if l1:
                    sum += l1.val
                    l1 = l1.next
                if l2:
                    sum += l2.val
                    l2 = l2.next
                sum += carry
                carry = sum / 10
                cur.next = ListNode(sum % 10)
                cur = cur.next
            if carry != 0:
                cur.next = ListNode(carry)
            return dummyHead.next
    View Code

    3.Longest Substring Without Repeating Characters --- not bug free

    Given a string, find the length of the longest substring without repeating characters.
    
    Examples:
    
    Given "abcabcbb", the answer is "abc", which the length is 3.
    
    Given "bbbbb", the answer is "b", with the length of 1.
    
    Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
    

    使用数组充当map

    注意:left的更新规则,可能有些出现过的点上次出现的位置还在left的左边。最后也需要一个max的操作

     1 public int lengthOfLongestSubstring(String s) {
     2         if (s == null || s.length() == 0) {
     3             return 0;
     4         }
     5         int[] map = new int[128];
     6         Arrays.fill(map, -1);
     7         char[] chars = s.toCharArray();
     8         int n = s.length();
     9         int left = 0;
    10         int right = 0;
    11         int res = 0;
    12         while (right < n) {
    13             if (map[chars[right]] == -1) {
    14                 map[chars[right]] = right;
    15                 right++;
    16             } else {
    17                 res = Math.max(res, right - left); 
    18                 left = Math.max(left, map[chars[right]] + 1); // Attention!
    19                 map[chars[right]] = right;
    20                 right++;
    21             }
    22         }
    23         res = Math.max(res, right - left);
    24         return res; // Attention!
    25     }
    View Code

    4.Median of Two Sorted Arrays

    There are two sorted arrays nums1 and nums2 of size m and n respectively.
    
    Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
    

    findTopK。检测四个条件:是否一个为空了,是否找第一个,是否其中一个不够 k / 2 了,谁大谁小。

    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
            if (nums1 == null || nums2 == null) {
                return 0.0;
            }
            int m = nums1.length;
            int n = nums2.length;
            int total = m + n;
            if (total % 2 == 0) {
                return (findTopK(nums1, 0, m - 1, nums2, 0, n - 1, total / 2) 
                    + findTopK(nums1, 0, m - 1, nums2, 0, n - 1, total / 2 + 1)) / 2.0;
            } else {
                return (double)findTopK(nums1, 0, m -1, nums2, 0, n - 1, total / 2 + 1);
            }
        }
        public int findTopK(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
            if (start1 > end1) {
                return nums2[start2 + k - 1];
            }
            if (start2 > end2) {
                return nums1[start1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[start1], nums2[start2]);
            }
            if (start1 + k / 2 - 1 > end1) {
                return findTopK(nums1, start1, end1, nums2, start2 + k / 2, end2, k - k / 2);
            }
            if (start2 + k / 2 - 1 > end2) {
                return findTopK(nums1, start1 + k / 2, end1, nums2, start2, end2, k - k / 2);
            }
            if (nums1[start1 + k / 2 - 1] > nums2[start2 + k / 2 - 1]) {
                 return findTopK(nums1, start1, end1, nums2, start2 + k / 2, end2, k - k / 2);
            } else {
                return findTopK(nums1, start1 + k / 2, end1, nums2, start2, end2, k - k / 2);
            }
        }
    View Code

    5.Longest Palindromic Substring

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
    

    以每个点为中心扩张

    global low
        global res
        def longestPalindrome(self, s):
            """
            :type s: str
            :rtype: str
            """
            global low
            global res
            low = 0
            res = 1
            if not s:
                return s
            n = len(s)
            for i in range(n - 1):
                self.test(s, i, i)
                self.test(s, i, i + 1)
            return s[low : low + res]
        def test(self, s, i, j):
            n = len(s)
            global res
            global low
            while (i >= 0 and j < n and s[i] == s[j]):
                i -= 1
                j += 1
            if (j - i - 1 > res):
                res = j - i - 1
                low = i + 1
    View Code

    dp dp[i][j]表示[i, j]子串是不是回文串。全局记录一个最大最小

    def longestPalindrome(self, s):
            """
            :type s: str
            :rtype: str
            """
            if not s:
                return s
            n = len(s)
            start = 0
            end = 0
            dp = [[False for col in range(n)] for row in range(n)] # dp[i][j]表示[i, j]是否是回文串
            for i in range(n):
                dp[i][i] = True
            for k in range(1, n):
                for i in range(n - k):
                    j = i + k
                    if (s[i] == s[j] and (k == 1 or dp[i + 1][j - 1])):
                        dp[i][j] = True
                        if (end - start < k) :
                            start = i
                            end = j
            return s[start : end + 1]
    View Code

    6.ZigZag Conversion

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
    P   A   H   N
    A P L S I I G
    Y   I   R
    And then read line by line: "PAHNAPLSIIGYIR"
    Write the code that will take a string and make this conversion given a number of rows:
    string convert(string text, int nRows);
    convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".
    

    每一行用一个StringBuilder 来记录

    public String convert(String s, int numRows) {
            if (s == null || s.length() <= numRows || numRows == 1) {
                return s;
            }
            StringBuilder[] sb = new StringBuilder[numRows];
            for (int j = 0; j < numRows; j++) {
                sb[j] = new StringBuilder();
            }
            char[] chars = s.toCharArray();
            int n = s.length();
            int i = 0;
            while (i < n) {
                for (int j = 0; j < numRows && i < n; j++) {
                    sb[j].append(chars[i++]);
                }
                for (int j = numRows - 2; j > 0 && i < n; j--) {
                    sb[j].append(chars[i++]);
                }
            }
            for (int j = 1; j < numRows; j++) {
                sb[0].append(sb[j]);
            }
            return sb[0].toString();
        }
    View Code

    7.Reverse Integer

    Reverse digits of an integer.
    
    Example1: x = 123, return 321
    Example2: x = -123, return -321
    

    直接使用负数来计算也是可以的。注意越界单独处理就可以了。

    public int reverse(int x) {
            long res = 0;
            while (x != 0) {
                int temp = x % 10;
                res = res * 10 + temp;
                if (res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) {
                    return 0;
                }
                x /= 10;
            }
            return (int)res;
        }
    View Code

    8.String to Integer (atoi)

    首位空格,非数字,越界, 正负号

    public int myAtoi(String str) {
            if (str == null) {
                return 0;
            }
            str = str.trim();
            if (str.length() == 0) {
                return 0;
            }
            char[] chars = str.toCharArray();
            long res = 0;
            int start = 0;
            boolean flag = false;
            if (chars[0] == '-') {
                flag = true;
                start = 1;
            }
            if (chars[0] == '+') {
                start = 1;
            }
            int n = str.length();
            while (start < n) {
                if (Character.isDigit(chars[start])) {
                    res = 10 * res + chars[start++] - '0';
                    if (res > Integer.MAX_VALUE) {
                        break;
                    }
                } else {
                    break;
                }
            }
            if (flag) {
                res = -res;
            }
            if (res > Integer.MAX_VALUE) {
                return Integer.MAX_VALUE;
            }
            if (res < Integer.MIN_VALUE) {
                return Integer.MIN_VALUE;
            }
            return (int)res;
        }
    View Code

    9.Palindrome Number

    Determine whether an integer is a palindrome. Do this without extra space.
    

    reverse之后看看等不等就可以了

    public boolean isPalindrome(int x) {
            if (x < 0) {
                return false;
            }
            long reverse = 0;
            int temp = x;
            while (temp != 0) {
                reverse = reverse * 10 + temp % 10;
                temp = temp / 10;
            }
            return (int)reverse == x;
        }
    View Code

    10.Regular Expression Matching

    Implement regular expression matching with support for '.' and '*'.
    
    '.' Matches any single character.
    '*' Matches zero or more of the preceding element.
    
    The matching should cover the entire input string (not partial).
    
    The function prototype should be:
    bool isMatch(const char *s, const char *p)
    
    Some examples:
    isMatch("aa","a") → false
    isMatch("aa","aa") → true
    isMatch("aaa","aa") → false
    isMatch("aa", "a*") → true
    isMatch("aa", ".*") → true
    isMatch("ab", ".*") → true
    isMatch("aab", "c*a*b") → true
    

    *可以把前边的字符也拿走。

    dp[i][j]表示s的前i个字符是否能够与p的前j个字符匹配。

    首先初始化s取0个,p的话如果遇到*,就把之前的一个拿走a*b*c*,这样可能匹配。

    然后如果遇到字符相等或p遇到'.',那简单。

    如果p遇到'*',那么就考虑代表0个1个多个。注意如果p的*的前一个不等于s的当前 ,也不为'.'。那么就是能拿走,代表0个。不然一起处理会带来“*”代表的不是之前字符的问题。

    public boolean isMatch(String s, String p) {
            if (s == null || p == null) {
                return false;
            }
            int m = s.length();
            int n = p.length();
            char[] sChars = s.toCharArray();
            char[] pChars = p.toCharArray();
            boolean[][] dp = new boolean[m + 1][n + 1]; // dp[i][j] 表示 s 的前 i 个字符和 p 的前 j 个字符是否能够匹配
            dp[0][0] = true;
            if (n != 0 && pChars[0] == '*') {
                return false;
            }
            for (int j = 2; j <= n; j++) {
                if (pChars[j - 1] == '*') {
                    dp[0][j] = dp[0][j - 2];
                }
            }
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                    if (sChars[i - 1] == pChars[j - 1] || pChars[j - 1] == '.') {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else if (pChars[j - 1] == '*') {
                        if (pChars[j - 2] == sChars[i - 1] || pChars[j - 2] == '.') {
                            dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];
                        } else {
                            dp[i][j] = dp[i][j - 2];
                        }
                    }
                }
            }
            return dp[m][n];
        }
    View Code

    11.Container With Most Water

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
    Note: You may not slant the container and n is at least 2.
    

    左右两个指针控制移动,哪边小就移动哪边,因为如果移动另一边的话,这边始终会是一个限制。

    public int maxArea(int[] height) {
            if (height == null || height.length < 2) {
                return 0;
            }
            int left = 0;
            int right = height.length - 1;
            int res = 0;
            while (left < right) {
                res = Math.max(res, (right - left) * Math.min(height[left], height[right]));
                if (height[left] < height[right]) {
                    left++;
                } else {
                    right--;
                }
            }
            return res;
        }
    View Code

    12.Integer to Roman --- not bug free

    Given an integer, convert it to a roman numeral.
    Input is guaranteed to be within the range from 1 to 3999.
    

    变换点为1 4 5 9 10 40 50 90 100...所以特别标注出这些点来,其他的就是累加

    // 罗马数字共有七个,即I(1),V(5),X(10),L(50),C(100),D(500),M(1000)。按照下面的规则可以表示任意正整数。
        // 重复数次:一个罗马数字重复几次,就表示这个数的几倍。 
        // 右加左减:在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。在一个较大的数字的左边记上一个较小的罗马数字,表示大数字减小数字。但是,左减不能跨越等级。比如,99不可以用IC表示,用XCIX表示。 
        // 加线乘千:在一个罗马数字的上方加上一条横线或者在右下方写M,表示将这个数字乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的1000000倍。 
        // 单位限制:同样单位只能出现3次,如40不能表示为XXXX,而要表示为XL。
        public String intToRoman(int num) {
            int[] values={1000,900,500,400,100,90,50,40,10,9,5,4,1};
            String[] str={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < values.length; i++) {
                while (num >= values[i]) {
                    sb.append(str[i]);
                    num -= values[i];
                }
            }
            return sb.toString();
        }
    View Code

    13.Roman to Integer --- not bug free

    Given a roman numeral, convert it to an integer.
    Input is guaranteed to be within the range from 1 to 3999.

    从后边开始遍历,以是否大于等于5 50 500 为界

    public int romanToInt(String s){
            if(s==null||s.length()==0){
                return 0;
            }
            int len=s.length();
            int res=0;
            for(int i=len-1;i>=0;i--){
                char cur=s.charAt(i);
                
                switch(cur){
                    case 'I':
                        res+=res>=5?-1:1;
                        break;
                    case 'V':
                        res+=5;
                        break;
                    case 'X':
                        res+=res>=50?-10:10;
                        break;
                    case 'L':
                        res+=50;
                        break;
                    case 'C':
                        res+=res>=500?-100:100;
                        break;
                    case 'D':
                        res+=500;
                        break;
                    case 'M':
                        res+=1000;
                        break;
                }
            }
            return res;
        }
    View Code

    14.Longest Common Prefix

    Write a function to find the longest common prefix string amongst an array of strings.
    

    先找出最短的,然后长度递减依次检测。

    public String longestCommonPrefix(String[] strs) {
            if (strs == null || strs.length == 0) {
                return "";
            }
            int n = strs.length;
            String shortest = strs[0];
            for (String str : strs) {
                if (str.length() < shortest.length()) {
                    shortest = str;
                }
            }
            while (shortest.length() > 0) {
                int i = 0;
                for (; i < n; i++) {
                    if (strs[i].indexOf(shortest) != 0) {
                        shortest = shortest.substring(0, shortest.length() - 1);
                        break;
                    }
                }
                if (i == n) {
                    return shortest;
                }
            }
            return "";
        }
    View Code

    上述方法在一个不满足的时候又重头开始检测,其实没这个必要,只要检测后边的就行了。注意一下

    public String longestCommonPrefix(String[] strs) {
            if (strs == null || strs.length == 0) {
                return "";
            }
            String shortest = strs[0];
            int n = strs.length;
            int i = 0;
            while (i < n) {
                while (i < n && strs[i].indexOf(shortest) == 0) {
                    i++;
                }
                if (i != n) {
                    shortest = shortest.substring(0, shortest.length() - 1);
                }
            }
            return shortest;
        }
    View Code

    15.3Sum --- not bug free

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
    

    排序之后两个指针控制移动。需要注意的是:找到一个满足条件之后,left right 的移动规则,为了避免重复是应该放在一个循环中的。

    public List<List<Integer>> threeSum(int[] nums) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if (nums == null || nums.length < 3) {
                return res;
            }
            Arrays.sort(nums);
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (i != 0 && nums[i] == nums[i - 1]) {
                    continue;
                }
                int left = i + 1;
                int right = n - 1;
                while (left < right) {
                    int sum = nums[left] + nums[right] + nums[i];
                    if (sum == 0) {
                        List<Integer> cur = new ArrayList<Integer>();
                        cur.add(nums[i]);
                        cur.add(nums[left]);
                        cur.add(nums[right]);
                        res.add(cur);
                        int temp1 = nums[left];
                        int temp2 = nums[right];
                        while (left < right && nums[left] == temp1) {
                            left++;
                        }
                        while (left < right && nums[right] == temp2) {
                            right--;
                        }
                    } else if (sum < 0) {
                        left++;
                    } else {
                        right--;
                    }
                }
            }
            return res;
        }
    View Code

    16.3Sum Closest

    Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
    For example, given array S = {-1 2 1 -4}, and target = 1.
    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
    

    和上题大同小异

    public int threeSumClosest(int[] nums, int target) {
            if (nums == null || nums.length < 3) {
                return Integer.MIN_VALUE;
            }
            Arrays.sort(nums);
            int n = nums.length;
            int res = nums[0] + nums[1] + nums[2];
            for (int i = 0; i < n; i++) {
                if (i != 0 && nums[i] == nums[i - 1]) {
                    continue;
                }
                int left = i + 1;
                int right = n - 1;
                while (left < right) {
                    int sum = nums[i] + nums[left] + nums[right];
                    if (sum == target) {
                        return target;
                    } else if (sum < target) {
                        left++;
                        if (Math.abs(res - target) > target - sum) {
                            res = sum;
                        }
                    } else {
                        right--;
                        if (Math.abs(res - target) > sum - target) {
                            res = sum;
                        }
                    }
                }
            }
            return res;
        }
    View Code

    17.Letter Combinations of a Phone Number

    Given a digit string, return all possible letter combinations that the number could represent.
    A mapping of digit to letters (just like on the telephone buttons) is given below.
    Input:Digit string "23"
    Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
    

    DFS

    public List<String> letterCombinations(String digits) {
            List<String> res = new ArrayList<String>();
            if (digits == null || digits.length() == 0) {
                return res;
            }
            char[][] base = {{},{},{'a', 'b', 'c'},{'d', 'e', 'f'},{'g', 'h', 'i'},{'j', 'k', 'l'},{'m', 'n', 'o'},
                    {'p', 'q', 'r', 's'},{'t', 'u', 'v'},{'w', 'x', 'y', 'z'}};
            dfs(digits.toCharArray(), base, res, new char[digits.length()], 0);
            return res;
        }
        public void dfs(char[] chars, char[][] base, List<String> res, char[] strChars, int index) {
            if (index == chars.length) {
                res.add(new String(strChars));
                return;
            }
            for (char c : base[chars[index] - '0']) {
                strChars[index] = c;
                dfs(chars, base, res, strChars, index + 1);
            }
        }
    View Code

    18.4Sum

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
    

    4sum -> 3sum ->2sum

     1 public List<List<Integer>> fourSum(int[] nums, int target) {
     2         List<List<Integer>> res = new ArrayList<List<Integer>>();
     3         if (nums == null || nums.length < 4) {
     4             return res;
     5         }
     6         Arrays.sort(nums);
     7         int n = nums.length;
     8         for (int i = 0; i < n - 3; i++) {
     9             if (i != 0 && nums[i] == nums[i - 1]) {
    10                 continue;
    11             }
    12             List<Integer> cur = new ArrayList<Integer>();
    13             cur.add(nums[i]);
    14             threeSum(nums, target - nums[i], i + 1, res, cur);
    15             cur.remove(cur.size() - 1);
    16         }
    17         return res;
    18     }
    19     public void threeSum(int[] nums, int target, int index, List<List<Integer>> res, List<Integer> cur) {
    20         int n = nums.length;
    21         for (int i = index; i < n - 2; i++) {
    22             if (i != index && nums[i] == nums[i - 1]) {
    23                 continue;
    24             }
    25             cur.add(nums[i]);
    26             twoSum(nums, target - nums[i], i + 1, res, cur);
    27             cur.remove(cur.size() - 1);
    28         }
    29     }
    30     public void twoSum(int[] nums, int target, int index, List<List<Integer>> res, List<Integer> cur) {
    31         int n = nums.length;
    32         int left = index;
    33         int right = n - 1;
    34         while (left < right) {
    35             int sum = nums[left] + nums[right];
    36             if (sum < target) {
    37                 left++;
    38             } else if (sum > target) {
    39                 right--;
    40             } else {
    41                 cur.add(nums[left]);
    42                 cur.add(nums[right]);
    43                 res.add(new ArrayList<Integer>(cur));
    44                 cur.remove(cur.size() - 1);
    45                 cur.remove(cur.size() - 1);
    46                 int temp1 = nums[left];
    47                 int temp2 = nums[right];
    48                 while (left < right && nums[left] == temp1) {
    49                     left++;
    50                 }
    51                 while (left < right && nums[right] == temp2) {
    52                     right--;
    53                 }
    54             }
    55         }
    56     }
    View Code

    19. Remove Nth Node From End of List

    Given a linked list, remove the nth node from the end of list and return its head.
    For example,
       Given linked list: 1->2->3->4->5, and n = 2.
       After removing the second node from the end, the linked list becomes 1->2->3->5.
    

    两个指针控制,找到倒数第n个节点的上一个节点。注意k大于结点总数的处理。

    public ListNode removeNthFromEnd(ListNode head, int n) {
            ListNode dummyHead = new ListNode(0);
            dummyHead.next = head;
            ListNode p1 = dummyHead;
            ListNode p2 = dummyHead;
            for (int i = 0; i < n; i++) {
                p1 = p1.next == null ? head : p1.next;
            }
            while (p1.next != null) {
                p1 = p1.next;
                p2 = p2.next;
            }
            p2.next = p2.next.next;
            return dummyHead.next;
        }
    View Code

    20.Valid Parentheses

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
    
    The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
    

    Stack

     1 public boolean isValid(String s) {
     2         if (s == null || s.length() == 0) {
     3             return false;
     4         }
     5         char[] chars = s.toCharArray();
     6         Stack<Character> stack = new Stack<Character>();
     7         for (char c : chars) {
     8             if (c == '(' || c == '[' || c == '{') {
     9                 stack.push(c);
    10             } else {
    11                 if (stack.isEmpty()) {
    12                     return false;
    13                 }
    14                 char top = stack.peek();
    15                 if (top == '[' && c == ']' || top == '(' && c == ')' || top == '{' && c == '}') {
    16                     stack.pop();
    17                 } else {
    18                     return false;
    19                 }
    20             }
    21         }
    22         return stack.isEmpty();
    23     }
    View Code

    21.Merge Two Sorted Lists

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
    

    dummyHead tail, l1 l2往后移动

    def mergeTwoLists(self, l1, l2):
            """
            :type l1: ListNode
            :type l2: ListNode
            :rtype: ListNode
            """
            if not l1:
                return l2
            if not l2:
                return l1
            dummyHead = ListNode(0)
            tail = dummyHead
            while (l1 or l2):
                if (not l1):
                    tail.next = l2
                    break
                if (not l2):
                    tail.next = l1
                    break
                if (l1.val < l2.val):
                    tail.next = l1
                    tail = l1
                    l1 = l1.next
                else:
                    tail.next = l2
                    tail = l2
                    l2 = l2.next
            return dummyHead.next
    View Code

    22.Generate Parentheses

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
    For example, given n = 3, a solution set is:
    [
      "((()))",
      "(()())",
      "(())()",
      "()(())",
      "()()()"
    ]
    

    dp。dp[i]表示i个括号的组合方式。i个括号组合方式的生成就是在i-1个括号上加一个括号,这个括号内部可以包含0,1,...i-1个括号。

    public List<String> generateParenthesis(int n) {
            List<String>[] dp = new ArrayList[n + 1]; // dp[i]表示i个括号的所有可能组合
            dp[0] = new ArrayList<String>();
            dp[0].add("");
            for (int i = 1; i <= n; i++) {
                dp[i] = new ArrayList<String>();
                for (int j = 0; j < i; j++) {
                    for (String inner : dp[j]) {
                        StringBuilder sb = new StringBuilder();
                        sb.append("(");
                        sb.append(inner);
                        sb.append(")");
                        int len = sb.length();
                        for (String outter : dp[i - j - 1]) {
                            sb.append(outter);
                            dp[i].add(sb.toString());
                            sb.setLength(len);
                        }
                    }
                }
            }
            return dp[n];
        }
    View Code

    23.Merge k Sorted Lists

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
    

    分治。klogn 另外还可以使用优先队列  两两合并

    public ListNode mergeKLists(ListNode[] lists) {
            if (lists == null || lists.length == 0) {
                return null;
            }
            return mergeHelper(lists, 0, lists.length - 1);
        }
        public ListNode mergeHelper(ListNode[] lists, int start, int end) {
            if (start == end) {
                return lists[start];
            }
            if (start + 1 == end) {
                return mergeTwo(lists[start], lists[end]);
            }
            int mid = start + (end - start) / 2;
            return mergeTwo(mergeHelper(lists, start, mid), mergeHelper(lists, mid + 1, end));
        }
        public ListNode mergeTwo(ListNode l1, ListNode l2) {
            ListNode dummyHead = new ListNode(0);
            ListNode tail = dummyHead;
            while (l1 != null || l2 != null) {
                if (l1 == null) {
                    tail.next = l2;
                    break;
                }
                if (l2 == null) {
                    tail.next = l1;
                    break;
                }
                if (l1.val < l2.val) {
                    tail.next = l1;
                    tail = l1;
                    l1 = l1.next;
                } else {
                    tail.next = l2;
                    tail = l2;
                    l2 = l2.next;
                }
            }
            return dummyHead.next;
        }
    View Code

    24.Swap Nodes in Pairs

    Given a linked list, swap every two adjacent nodes and return its head.
    
    For example,
    Given 1->2->3->4, you should return the list as 2->1->4->3.
    
    Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
    

    搞清逻辑就行了。

    public ListNode swapPairs(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            ListNode dummyHead = new ListNode(0);
            dummyHead.next = head;
            ListNode tail = dummyHead;
            ListNode cur = head;
            while (cur != null && cur.next != null) {
                ListNode swapNode = cur.next;
                ListNode temp = swapNode.next;
                tail.next = swapNode;
                swapNode.next = cur;
                cur.next = temp;
                tail = cur;
                cur = temp;
            }
            return dummyHead.next;
        }
    View Code

    25.Reverse Nodes in k-Group --- not bug free

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
    k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
    You may not alter the values in the nodes, only nodes itself may be changed.
    Only constant memory is allowed.
    For example,
    Given this linked list: 1->2->3->4->5
    For k = 2, you should return: 2->1->4->3->5
    For k = 3, you should return: 3->2->1->4->5
    

    递归。找出前k个之后,后边的分下去做。我对这前k个逆序之后连接上后边的。

    public ListNode reverseKGroup(ListNode head, int k) {
            if (k == 1) {
                return head;
            }
            int count = 0;
            ListNode cur = head;
            while (cur != null && count != k) {
                cur = cur.next;
                count++;
            }
            if (count == k) {
                ListNode prev = reverseKGroup(cur, k);
                while (head != cur) {
                    ListNode temp = head.next;
                    head.next = prev;
                    prev = head;
                    head = temp;
                }
                return prev;
            }
            return head;
        }
    View Code

    非递归。也是一段一段的找。

    public ListNode reverseKGroup(ListNode head, int k) {
            if (k == 1) {
                return head;
            }
            ListNode cur = head;
            ListNode dummyHead = new ListNode(0);
            dummyHead.next = head;
            ListNode tail = dummyHead;
            while (cur != null) {
                int count = 0;
                while (cur != null && count != k) {
                    cur = cur.next;
                    count++;
                }
                if (count == k) {
                    ListNode prev = cur;
                    while (head != cur) {
                        ListNode temp = head.next;
                        head.next = prev;
                        prev = head;
                        head = temp;
                    }
                    ListNode tempNext = tail.next;
                    tail.next = prev;
                    tail = tempNext;
                }
            }
            return dummyHead.next;
        }
    View Code

    26.Remove Duplicates from Sorted Array

    Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
    
    Do not allocate extra space for another array, you must do this in place with constant memory.
    
    For example,
    Given input array nums = [1,1,2],
    
    Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.
    

    two point.

    public int removeDuplicates(int[] nums) {
            if (nums == null || nums.length == 0) {
                return 0;
            }
            int left = 0;
            int right = 1;
            int n = nums.length;
            while (right < n) {
                if (nums[right] != nums[left]) {
                    swap(nums, ++left, right++);
                } else {
                    right++;
                }
            }
            return left + 1;
        }
        public void swap(int[] nums, int left, int right) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
        }
    View Code

    27.Remove Element

    Given an array and a value, remove all instances of that value in place and return the new length.
    
    Do not allocate extra space for another array, you must do this in place with constant memory.
    
    The order of elements can be changed. It doesn't matter what you leave beyond the new length.
    
    Example:
    Given input array nums = [3,2,2,3], val = 3
    
    Your function should return length = 2, with the first two elements of nums being 2.
    

    two point.

    public int removeElement(int[] nums, int val) {
            if (nums == null || nums.length == 0) {
                return 0;
            }
            int left = 0;
            int n = nums.length;
            int right = 0;
            while (right < n) {
                if (nums[right] != val) {
                    swap(nums, left++, right++);
                } else {
                    right++;
                }
            }
            return left;
        }
        public void swap(int[] nums, int left, int right) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
        }
    View Code

    28.Implement strStr()

    Implement strStr().
    
    Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
    

    就是分别检测每个点起始的这个子串可不可以。

    public int strStr(String haystack, String needle) {
            if (haystack == null || needle == null || haystack.length() < needle.length()) {
                return -1;
            }
            char[] chars1 = haystack.toCharArray();
            char[] chars2 = needle.toCharArray();
            int n1 = haystack.length();
            int n2 = needle.length();
            for (int i = 0; i + n2 <= n1; i++) {
                int j = 0;
                for (; j < n2; j++) {
                    if (chars1[i + j] != chars2[j]) {
                        break;
                    }
                }
                if (j == n2) {
                    return i;
                }
            }
            return -1;
        }
    View Code

     hash,只有hash值相等的时候才比较。O(n)

     public static final int BASE = 1000000;
        public int strStr(String haystack, String needle) {
            if (haystack == null || needle == null) {
                return -1;
            }
            if (needle.length() == 0) {
                return 0;
            }
            int hLen = haystack.length();
            int nLen = needle.length();
            int pow = 1;
            int targetCode = 0;
            char[] nChars = needle.toCharArray();
            for (int i = 0; i < nLen; i++) {
                if (i < nLen - 1) {
                    pow = (pow * 31) % BASE;    
                }
                targetCode = (targetCode * 31 + nChars[i]) % BASE;
            }
            int hashCode = 0;
            char[] hChars = haystack.toCharArray();
            for (int i = 0; i < hLen; i++) {
                hashCode = (hashCode * 31 + hChars[i]) % BASE;
                if (i < nLen - 1) {
                    continue;
                }
                if (targetCode == hashCode) {
                    if (haystack.substring(i - nLen + 1, i + 1).equals(needle)) {
                        return i - nLen + 1;
                    }
                } else {
                    hashCode = (hashCode - pow * hChars[i - nLen + 1]) % BASE;
                    if (hashCode < 0) {
                        hashCode += BASE;
                    }
                }
            }
            return -1;
        }
    View Code

    29.Divide Two Integers

    Divide two integers without using multiplication, division and mod operator.
    If it is overflow, return MAX_INT.
    

    二分。

    public int divide(int dividend, int divisor) {
             if (divisor == 0) {
                 return -1;
             }
             if (dividend == 0) {
                 return 0;
             }
             long longdividend = (long)dividend;
             long longdivisor = (long)divisor;
             int count = 0;
             if (longdividend < 0) {
                 longdividend = -longdividend;
                 count++;
             }
             if (longdivisor < 0) {
                 longdivisor = -longdivisor;
                 count++;
             }
             long res = 0;
             while (longdividend >= longdivisor) {
                 long base = longdivisor;
                 long num = 1;
                 while (longdividend >= base) {
                     res += num;
                     longdividend -= base;
                     base += base;
                     num += num;
                 }
             }
             if(count % 2 != 0) {
                 res = -res;
             }
             return res > Integer.MAX_VALUE ? Integer.MAX_VALUE : res < Integer.MIN_VALUE ? Integer.MIN_VALUE : (int)res;
        }
    View Code

    30.Substring with Concatenation of All Words

    You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
    
    For example, given:
    s: "barfoothefoobarman"
    words: ["foo", "bar"]
    

    两层循环,外层循环为wordLen。内存一次取出长度为wordLen的子串,如果不在map中,表明不满足,移动到下一位;在里面的话,还有可能出现次数多了的问题。

    public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> res = new ArrayList<Integer>();
            if (res == null || words == null || s.length() == 0 || words.length == 0) {
                return res;
            }
            int sLen = s.length();
            int wordLen = words[0].length();
            int m = words.length;
            int winLen = wordLen * m;
            if (sLen < winLen) {
                return res;
            }
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            for (String word : words) {
                map.put(word, map.getOrDefault(word, 0) + 1);
            }
            for (int i = 0; i < wordLen; i++) {
                int start = i;
                int j = i;
                int count = 0;
                HashMap<String, Integer> timesMap = new HashMap<String, Integer>();
                while (j + wordLen <= sLen) {
                    if (start + winLen > sLen) {
                        break;
                    }
                    String str = s.substring(j, j + wordLen);
                    if (!map.containsKey(str)) {
                        j += wordLen;
                        start = j;
                        timesMap.clear();
                        count = 0;
                        continue;
                    } else {
                        timesMap.put(str, timesMap.getOrDefault(str, 0) + 1);
                        count++;
                        while (timesMap.get(str) > map.get(str)) {
                            String temp = s.substring(start, start + wordLen);
                            timesMap.put(temp, timesMap.get(temp) - 1);
                            start += wordLen;
                            count--;
                        }
                        if (count == m) {
                            res.add(start);
                            String temp = s.substring(start, start + wordLen);
                            timesMap.put(temp, timesMap.get(temp) - 1);
                            start += wordLen;
                            count--;
                        }
                        j += wordLen; // 容易忘记
                    }
                }
            }
            return res;
        }
    View Code

    31.Next Permutation --- not bug free

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
    
    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
    
    The replacement must be in-place, do not allocate extra memory.
    
    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1
    

    找到第一个左边比我小的,然后右半部分逆序。如果654321直接返回。不是的话,右半部分找到第一个  49876 比4大的,交换。

    public void nextPermutation(int[] nums) {
            if (nums == null || nums.length < 2) {
                return;
            }
            int n = nums.length;
            int right = n - 1;
            while (right > 0 && nums[right] <= nums[right - 1]) {
                right--;
            }
            reverse(nums, right, n - 1);
            if (right != 0) {
                int index = findFirstBigger(nums, right, n - 1, nums[right - 1]);
                int temp = nums[right - 1];
                nums[right - 1] = nums[index];
                nums[index] = temp;
            }
        }
        public void reverse(int[] nums, int left, int right) {
            while (left < right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                left++;
                right--;
            }
        }
        public int findFirstBigger(int[] nums, int start, int end, int target) {
            while (start + 1 < end) {
                int mid = start + (end - start) / 2;
                if (nums[mid] <= target) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
            if (nums[start] > target) {
                return start;
            } else {
                return end;
            }
        }
    View Code

    32.Longest Valid Parentheses --- not bug free

    Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
    
    For "(()", the longest valid parentheses substring is "()", which has length = 2.
    
    Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.
    

    主要是思想,实现很简单。动规:dp[i]表示以i结尾的有效括号串的长度。

    public class Solution {
        public int longestValidParentheses(String s) {
            if (s == null || s.length() == 0) {
                return 0;
            }
            char[] chars = s.toCharArray();
            int n = s.length();
            int[] dp = new int[n]; // dp[i]表示以i结尾的最长有效串长度
            int res = 0;
            for (int i = 1; i < n; i++) {
                if (chars[i] == '(') {
                    continue;
                } else {
                    if (i- dp[i - 1] - 1 >= 0 && chars[i - dp[i - 1] - 1] == '(') {
                        dp[i] = dp[i - 1] + 2 + ((i - dp[i - 1] - 2 >= 0) ? dp[i - dp[i - 1] - 2] : 0);
                        res = Math.max(res, dp[i]);
                    }
                }
            }
            return res;
        }
    }
    View Code

    33.Search in Rotated Sorted Array

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
    
    (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
    
    You are given a target value to search. If found in the array return its index, otherwise return -1.
    
    You may assume no duplicate exists in the array.
    

    根据nums[left]与nums[mid]大小关系分段,然后再看target在不在区间上。

    public int search(int[] nums, int target) {
            if (nums == null || nums.length == 0) {
                return -1;
            }
            int left = 0;
            int right = nums.length - 1;
            while (left + 1 < right) {
                int mid = left + (right - left) / 2;
                if (nums[left] < nums[mid]) {
                    if (nums[left] <= target && target <= nums[mid]) {
                        right = mid;
                    } else {
                        left = mid;
                    }
                } else {
                    if (nums[mid] <= target && target <= nums[right]) {
                        left = mid;
                    }  else {
                        right = mid;
                    }
                }
            }
            if (nums[left] == target) {
                return left;
            }
            if (nums[right] == target) {
                return right;
            }
            return -1;
        }
    View Code

    34.Search for a Range

    Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.
    
    Your algorithm's runtime complexity must be in the order of O(log n).
    
    If the target is not found in the array, return [-1, -1].
    
    For example,
    Given [5, 7, 7, 8, 8, 10] and target value 8,
    return [3, 4].
    

    找第一个和最后一个相等的位置。

    def searchRange(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: List[int]
            """
            if not nums or len(nums) == 0:
                return [-1, -1]
            left = self.findFirstEqual(nums, target)
            if (left == -1):
                return [-1, -1]
            right = self.findFinalEqual(nums, target)
            return [left, right]
        def findFirstEqual(self, nums, target):
            left = 0;
            right = len(nums) - 1
            while (left + 1 < right):
                mid = left + (right - left) / 2
                if (nums[mid] < target):
                    left = mid
                else:
                    right = mid
            if nums[left] == target:
                return left
            elif nums[right] == target:
                return right
            else:
                return -1
        def findFinalEqual(self, nums, target):
            left = 0;
            right = len(nums) - 1
            while (left + 1 < right):
                mid = left + (right - left) / 2
                if (nums[mid] <= target):
                    left = mid
                else:
                    right = mid
            if nums[right] == target:
                return right
            elif nums[left] == target:
                return left
            else:
                return -1
    View Code

    35.Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
    
    You may assume no duplicates in the array.
    
    Here are few examples.
    [1,3,5,6], 5 → 2
    [1,3,5,6], 2 → 1
    [1,3,5,6], 7 → 4
    [1,3,5,6], 0 → 0
    

    找到第一个大于等于的位置。

    def searchInsert(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: int
            """
            if not nums or len(nums) == 0:
                return -1
            return self.findFirstBiggerOrEqual(nums, target)
        def findFirstBiggerOrEqual(self, nums, target):
            start = 0
            end = len(nums) - 1
            while (start + 1 < end):
                mid = start + (end - start) / 2
                if (nums[mid] < target):
                    start = mid
                else:
                    end = mid
            if nums[start] >= target:
                return start
            elif nums[end] >= target:
                return end
            else:
                return len(nums)
    

      

     36.Valid Sudoku --- not bug free

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
    
    The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
    

    依次检测每行每列 小方块。用一个统一的接口来进行检测。

    public boolean isValidSudoku(char[][] board) {
            if (board == null || board.length != 9) {
                return false;
            }
            for (int i = 0; i < 9; i++) {
                if (!isParticallyValid(board, i, i, 0, 8)) {
                    return false;
                }
                if (!isParticallyValid(board, 0, 8, i, i)) {
                    return false;
                }
            }
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    if (!isParticallyValid(board, 3 * i, 3 * i + 2, 3 * j, 3 * j + 2)) {
                        return false;
                    }
                }
            }
            return true;
        }
        public boolean isParticallyValid(char[][] board, int row_begin, int row_end, int col_begin, int col_end) {
            HashSet<Character> set = new HashSet<Character>();
            for (int i = row_begin; i <= row_end; i++) {
                for (int j = col_begin; j <= col_end; j++) {
                    if (board[i][j] == '.') {
                        continue;
                    } else {
                        if (!set.add(board[i][j])) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    View Code

    37.Sudoku Solver --- not bug free

    Write a program to solve a Sudoku puzzle by filling the empty cells.
    
    Empty cells are indicated by the character '.'.
    
    You may assume that there will be only one unique solution.
    

    递归程序控制行,然后内部控制列。遇到 '.' 检测合适的char,填入之后深搜下去看看行不,不行的话下一个,都不行的话返回false

    public void solveSudoku(char[][] board) {
            if (board == null || board.length != 9) {
                return;
            }
            solve(board, 0);
        }
        public boolean solve(char[][] board, int row_begin) {
            for (int i = row_begin; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    if (board[i][j] == '.') {
                        for (char c = '1'; c <= '9'; c++) {
                            if (isValid(board, i, j, c)) {
                                board[i][j] = c;
                                if (solve(board, i)) {
                                    return true;
                                }
                                board[i][j] = '.';
                            }
                        }
                        return false;
                    }
                }
            }
            return true;
        }
        public boolean isValid(char[][] board, int row, int col, char c) {
            for (int j = 0; j < 9; j++) {
                if (board[row][j] == c) {
                    return false;
                }
            }
            for (int i = 0; i < 9; i++) {
                if (board[i][col] == c) {
                    return false;
                }
            }
            for (int i = row / 3 * 3; i <= row / 3 * 3 + 2; i++) {
                for (int j = col / 3 * 3; j < col / 3 * 3+ 2; j++) {
                    if (board[i][j] == c) {
                        return false;
                    }
                }
            }
            return true;
        }
    View Code

    38.Count and Say

    The count-and-say sequence is the sequence of integers beginning as follows:
    1, 11, 21, 1211, 111221, ...
    
    1 is read off as "one 1" or 11.
    11 is read off as "two 1s" or 21.
    21 is read off as "one 2, then one 1" or 1211.
    Given an integer n, generate the nth sequence.
    
    Note: The sequence of integers will be represented as a string.
    

    就是按照规则来,一个一个的迭代。注意迭代过程中n--

    public String countAndSay(int n) {
            String res = "1";
            while (n > 1) {
                char[] chars = res.toCharArray();
                StringBuilder sb = new StringBuilder();
                int start = 0;
                int i = 0;
                int m = chars.length;
                while (i < m) {
                    while (i < m && chars[i] == chars[start]) {
                        i++;
                    }
                    int count = i - start;
                    sb.append(count);
                    sb.append(chars[start]);
                    start = i;
                }
                res = sb.toString();
                n--;
            }
            return res;
        }
    View Code

    39.Combination Sum

    Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
    
    The same repeated number may be chosen from C unlimited number of times.
    

    DFS

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if (candidates == null || candidates.length == 0) {
                return res;
            }
            Arrays.sort(candidates);
            DFS(candidates, target, res, new ArrayList<Integer>(), 0);
            return res;
        }
        public void DFS(int[] candidates, int target, List<List<Integer>> res, List<Integer> cur, int index) {
            if (target == 0) {
                res.add(new ArrayList<Integer>(cur));
                return;
            }
            int n = candidates.length;
            for (int i = index; i < n; i++) {
                if (candidates[i] > target) {
                    return;
                }
                cur.add(candidates[i]);
                DFS(candidates, target - candidates[i], res, cur, i);
                cur.remove(cur.size() - 1);
            }
        }
    View Code

    40.Combination Sum II

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
    
    Each number in C may only be used once in the combination.
    

    DFS

     public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if (candidates == null || candidates.length == 0) {
                return res;
            }
            Arrays.sort(candidates);
            DFS(candidates, target, res, new ArrayList<Integer>(), 0);
            return res;
        }
        public void DFS(int[] candidates, int target, List<List<Integer>> res, List<Integer> cur, int index) {
            if (target == 0) {
                res.add(new ArrayList<Integer>(cur));
                return;
            }
            int n = candidates.length;
            for (int i = index; i < n; i++) {
                if (i != index && candidates[i] == candidates[i - 1]) {
                    continue;
                }
                if (candidates[i] > target) {
                    return;
                }
                cur.add(candidates[i]);
                DFS(candidates, target - candidates[i], res, cur, i + 1);
                cur.remove(cur.size() - 1);
            }
        }
    View Code

    41.First Missing Positive

    Given an unsorted integer array, find the first missing positive integer.
    
    For example,
    Given [1,2,0] return 3,
    and [3,4,-1,1] return 2.
    
    Your algorithm should run in O(n) time and uses constant space.
    

    实现很简单,主要是思想:可能的结果为1..n + 1,我们把nums[i]放到 i +  1 位置,然后遍历数组,检测nums[i]是否等于 i + 1。

    交换的时候,如果遇到小于1的或者大于n的,或者位置上已经满足nums[i] = i + 1的就不用管。其他的如果换过去那个位置也满足条件了,也不用换,否则交换。

    public int firstMissingPositive(int[] nums) {
            if (nums == null || nums.length == 0) {
                return 1;
            }
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (nums[i] == i + 1 || nums[i] > n || nums[i] < 1) {
                    continue;
                } else if (nums[nums[i] - 1] != nums[i]){
                    int temp = nums[nums[i] - 1];
                    nums[nums[i] - 1] = nums[i];
                    nums[i] = temp;
                    i--;
                }
            }
            for (int i = 0; i < n; i++) {
                if (nums[i] != i + 1) {
                    return i + 1;
                }
            }
            return n + 1;
        }
    View Code

    42.Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
    
    For example, 
    Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
    

    找到最大后,最有两边分别求。有了最大就有了保障。

     public int trap(int[] height) {
            if (height == null || height.length == 0) {
                return 0;
            }
            int maxIndex = 0;
            int max = height[0];
            int n = height.length;
            for (int i = 1; i < n; i++) {
                if (height[i] > max) {
                    max = height[i];
                    maxIndex = i;
                }
            }
            int res = 0;
            int left = 0;
            for (int i = 1; i < maxIndex; i++) {
                if (height[i] < height[left]) {
                    res += (height[left] - height[i]);
                } else {
                    left = i;
                }
            }
            int right = n - 1;
            for (int i = right - 1; i > maxIndex; i--) {
                if (height[i] < height[right]) {
                    res += (height[right] - height[i]);
                } else {
                    right = i;
                }
            }
            return res;
        }
    View Code

    43.Multiply Strings --- not bug free

    Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2.
    Note:
    The length of both num1 and num2 is < 110.
    Both num1 and num2 contains only digits 0-9.
    Both num1 and num2 does not contain any leading zero.
    You must not use any built-in BigInteger library or convert the inputs to integer directly.

    因子 1 的第 i 位与因子 2 的第 j 位对乘积的影响是第 i + j 和第 i + j + 1 位,所以从后往前一位一位相乘。

    public String multiply(String num1, String num2) {
            if (num1 == null || num1.length() == 0) {
                return num2;
            }
            if (num2 == null || num2.length() == 0) {
                return num1;
            }
            char[] chars1 = num1.toCharArray();
            char[] chars2 = num2.toCharArray();
            int m = chars1.length;
            int n = chars2.length;
            int[] values = new int[m + n];
            for (int i = m - 1; i >= 0; i--) {
                for (int j = n - 1; j >= 0; j--) {
                    int p1 = i + j;
                    int p2 = i + j + 1;
                    int sum = (chars1[i] - '0') * (chars2[j] - '0') + values[p2];
                    values[p1] += sum / 10;
                    values[p2] = sum % 10;
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int value : values) {
                if (sb.length() == 0 && value == 0) {
                    continue;
                }
                sb.append(value);
            }
            return sb.length() ==0 ? "0" : sb.toString();
        }
    View Code

    44.Wildcard Matching

    Implement wildcard pattern matching with support for '?' and '*'.
    
    '?' Matches any single character.
    '*' Matches any sequence of characters (including the empty sequence).
    
    The matching should cover the entire input string (not partial).
    
    The function prototype should be:
    bool isMatch(const char *s, const char *p)
    
    Some examples:
    isMatch("aa","a") → false
    isMatch("aa","aa") → true
    isMatch("aaa","aa") → false
    isMatch("aa", "*") → true
    isMatch("aa", "a*") → true
    isMatch("ab", "?*") → true
    isMatch("aab", "c*a*b") → false
    

    一种思路可以求出一个数的0~9倍,然后主要设计两个字符串求和。

    另一种思路:dp.

    public boolean isMatch(String s, String p) {
            if (s == null || p == null) {
                return false;
            }
            char[] sChars = s.toCharArray();
            char[] pChars = p.toCharArray();
            int m = s.length();
            int n = p.length();
            boolean[][] dp = new boolean[m + 1][n + 1]; // dp[i][j]表示s的前i个字符和p的前j个字符是否匹配
            dp[0][0] = true;
            for(int j = 1; j <= n && pChars[j - 1] == '*'; j++) {
                dp[0][j] = true;
            }
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                    if (sChars[i - 1] == pChars[j - 1] || pChars[j - 1] == '?') {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else {
                        if (pChars[j - 1] == '*') {
                            dp[i][j] = dp[i][j - 1] || dp[i - 1][j - 1] || dp[i - 1][j];
                        }
                    }
                }
            }
            return dp[m][n];
        }
    View Code

    45.Jump Game II

    Given an array of non-negative integers, you are initially positioned at the first index of the array.
    
    Each element in the array represents your maximum jump length at that position.
    
    Your goal is to reach the last index in the minimum number of jumps.
    
    For example:
    Given array A = [2,3,1,1,4]
    
    The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
    

    方法一:dp。dp[i]表示到达第i个的最小步数。TLE

    public int jump(int[] nums) {
            if (nums == null || nums.length == 0) {
                return 0;
            }
            int n = nums.length;
            int[] dp = new int[n]; // dp[i]表示到达i的最小步数
            for (int i = 1; i < n; i++) {
                dp[i] = Integer.MAX_VALUE;
                for (int j = 0; j < i; j++) {
                    if (nums[j] + j >= i) {
                        dp[i] = Math.min(dp[i], dp[j] + 1);
                    }
                }
            }
            return dp[n - 1];
        }
    View Code

    方法二:贪心 --- not bug free

    public int jump(int[] nums) {
            if (nums == null || nums.length == 0) {
                return 0;
            }
            int edge = 0; // 当前步数可以到达哪儿
            int nextReach = nums[0]; // 当前步数加1最多可以的到达哪儿
            int step = 0;
            int n = nums.length;
            for (int i = 1; i < n; i++) {
                if (i > edge) {
                    step++;
                    edge = nextReach;
                    if (edge >= n - 1) {
                        return step;
                    }
                }
                nextReach = Math.max(nextReach, nums[i] + i);
                if (nextReach == i) {
                    return Integer.MAX_VALUE;
                }
            }
            return step;
        }
    View Code

    46.Permutations

    Given a collection of distinct numbers, return all possible permutations.
    
    For example,
    [1,2,3] have the following permutations:
    [
      [1,2,3],
      [1,3,2],
      [2,1,3],
      [2,3,1],
      [3,1,2],
      [3,2,1]
    ]
    

    DFS

    public List<List<Integer>> permute(int[] nums) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if (nums == null || nums.length == 0) {
                return res;
            }
            int n = nums.length;
            boolean[] used = new boolean[n];
            help(nums ,res, new ArrayList<Integer>(), used);
            return res;
        }
        public void help(int[] nums, List<List<Integer>> res, List<Integer> cur, boolean[] used) {
            if (cur.size() == nums.length) {
                res.add(new ArrayList<Integer>(cur));
                return;
            }
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (used[i]) {
                    continue;
                }
                used[i] = true;
                cur.add(nums[i]);
                help(nums, res, cur, used);
                cur.remove(cur.size() - 1);
                used[i] = false;
            }
        }
    View Code

    47.Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations.
    
    For example,
    [1,1,2] have the following unique permutations:
    [
      [1,1,2],
      [1,2,1],
      [2,1,1]
    ]
    

    DFS.别忘了排序

    public List<List<Integer>> permuteUnique(int[] nums) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if (nums == null || nums.length == 0) {
                return res;
            }
            int n = nums.length;
            Arrays.sort(nums);
            boolean[] used = new boolean[n];
            help(nums ,res, new ArrayList<Integer>(), used);
            return res;
        }
        public void help(int[] nums, List<List<Integer>> res, List<Integer> cur, boolean[] used) {
            if (cur.size() == nums.length) {
                res.add(new ArrayList<Integer>(cur));
                return;
            }
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (used[i]) {
                    continue;
                }
                if (i != 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
                    continue;
                }
                used[i] = true;
                cur.add(nums[i]);
                help(nums, res, cur, used);
                cur.remove(cur.size() - 1);
                used[i] = false;
            }
        }
    View Code

    48.Rotate Image

    You are given an n x n 2D matrix representing an image.
    
    Rotate the image by 90 degrees (clockwise).
    
    Follow up:
    Could you do this in-place?
    

    先对角线旋转,再列调换。

    public void rotate(int[][] matrix) {
            if (matrix == null || matrix.length == 0) {
                return;
            }
            reverse(matrix);
            exchange(matrix);
        }
        public void reverse(int[][] matrix) {
            int n = matrix.length;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < i; j++) {
                    int temp= matrix[i][j];
                    matrix[i][j] = matrix[j][i]; 
                    matrix[j][i] = temp;
                }
            }
        }
        public void exchange(int[][] matrix) {
            int n = matrix.length;
            int left = 0;
            int right = n - 1;
            while (left < right) {
                for (int i = 0; i < n; i++) {
                    int temp = matrix[i][left];
                    matrix[i][left] = matrix[i][right];
                    matrix[i][right] = temp;
                }
                left++;
                right--;
            }
        }
    View Code

    49.Group Anagrams

    Given an array of strings, group anagrams together.
    
    For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], 
    Return:
    
    [
      ["ate", "eat","tea"],
      ["nat","tan"],
      ["bat"]
    ]
    

    相同的放在一个map key 下。排序之后判断相同不。

    public class Solution {
        public List<List<String>> groupAnagrams(String[] strs) {
            if (strs == null || strs.length == 0) {
                return new ArrayList<List<String>>();
            }
            HashMap<String, List<String>> map = new HashMap<String, List<String>>();
            for (String str : strs) {
                char[] chars = str.toCharArray();
                Arrays.sort(chars);
                String key = new String(chars);
                if (!map.containsKey(key)) {
                    map.put(key, new ArrayList<String>());
                }
                map.get(key).add(str);
            }
            return new ArrayList<List<String>>(map.values());
        }
    }
    View Code

    50.Pow(x, n) --- not bug free

    Implement pow(x, n).
    

    二分。注意次方为 -2147483648 的时候简单的变为负处理会有溢出问题。所以需要检测讨论。

    public class Solution {
        public double myPow(double x, int n) {
            if (n == Integer.MIN_VALUE) {
                if (Math.abs(Math.abs(x) - 1) < 0.000001) {
                    return 1;
                } else {
                    return Math.abs(x) > 1 ? 0 : Integer.MAX_VALUE;
                 }
            }
            if (n < 0) {
                return 1.0 / myPow(x, -n);
            }
            double res = 1;
            while (n > 0) {
                double cur = x;
                int times = 1;
                while (n >= times) {
                    res *= cur;
                    n -= times;
                    cur *= cur;
                    times += times;
                }
            }
            return res;
        }
    }
    View Code

     上边的检测比较麻烦,直接写为不需要检测的。

    public double myPow(double x, int n) {
            if (n < 0) {
                return 1 / x * 1 / myPow(x, -(n + 1));
            }
            double res = 1;
            while (n > 0) {
                double cur = x;
                int times = 1;
                while (n >= times) {
                    res *= cur;
                    n -= times;
                    cur *= cur;
                    times += times;
                }
            }
            return res;
        }
    View Code

    51.N-Queens

    The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
    

    递归程序填充行。列检测,主对角线检测,副对角线检测 填充。

    public List<List<String>> solveNQueens(int n) {
            List<List<String>> res = new ArrayList<List<String>>();
            char[] base = new char[n];
            Arrays.fill(base, '.');
            boolean[] col_used = new boolean[n];
            boolean[] diag1_used = new boolean[2 * n];
            boolean[] diag2_used = new boolean[2 * n];
            help(n, res, new ArrayList<String>(), base, 0, col_used, diag1_used, diag2_used);
            return res;
        }
        public void help(int n, List<List<String>> res, List<String> cur, char[] base, int row, 
                boolean[] col_used, boolean[] diag1_used, boolean[] diag2_used) {
            if (row == n) {
                res.add(new ArrayList<String>(cur));
                return;
            }
            for (int j = 0; j < n; j++) {
                if (!col_used[j] && !diag1_used[row + j] && !diag2_used[j - row + n - 1]) {
                    col_used[j] = true;
                    diag1_used[row + j] = true;
                    diag2_used[j - row + n - 1] = true;
                    base[j] = 'Q';
                    cur.add(new String(base));
                    base[j] = '.';
                    help(n, res, cur, base, row + 1, col_used, diag1_used, diag2_used);
                    col_used[j] = false;
                    diag1_used[row + j] = false;
                    diag2_used[j - row + n - 1] = false;
                    cur.remove(cur.size() - 1);
                }
            }
        }
    View Code

    52.N-Queens II

    Follow up for N-Queens problem.
    
    Now, instead outputting board configurations, return the total number of distinct solutions.
    

    同样的道理DFS

    public int totalNQueens(int n) {
            int[] res = new int[1];
            boolean[] col_used = new boolean[n];
            boolean[] diag1_used = new boolean[2 * n];
            boolean[] diag2_used = new boolean[2 * n];
            help(n, res, col_used, diag1_used, diag2_used, 0);
            return res[0];
        }
        public void help(int n, int[] res, boolean[] col_used, boolean[] diag1_used, boolean[] diag2_used, int row) {
            if (n == row) {
                res[0]++;
                return;
            }
            for (int j = 0; j < n; j++) {
                if (!col_used[j] && !diag1_used[row + j] && !diag2_used[j - row + n - 1]) {
                    col_used[j] = true;
                    diag1_used[row + j] = true;
                    diag2_used[j - row + n - 1] = true;
                    help(n, res, col_used, diag1_used, diag2_used, row + 1);
                    col_used[j] = false;
                    diag1_used[row + j] = false;
                    diag2_used[j - row + n - 1] = false;
                }
            }
        }
    View Code

    53.Maximum Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
    
    For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
    the contiguous subarray [4,-1,2,1] has the largest sum = 6.
    

    前缀和为负则更新为0,遍历一遍实时更新res

    public int maxSubArray(int[] nums) {
            int res = Integer.MIN_VALUE;
            int cur = 0;
            for (int num : nums) {
                if (cur < 0) {
                    cur = 0;
                }
                cur += num;
                res = Math.max(res, cur);
            }
            return res;
        }
    View Code

    54.Spiral Matrix --- not bug free

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
    
    For example,
    Given the following matrix:
    
    [
     [ 1, 2, 3 ],
     [ 4, 5, 6 ],
     [ 7, 8, 9 ]
    ]
    You should return [1,2,3,6,9,8,7,4,5].
    

    从外到内,一层一层的添加。row_begin row_end col_begin col_end控制。注意代码中Attention部分。

    public List<Integer> spiralOrder(int[][] matrix) {
            List<Integer> res = new ArrayList<Integer>();
            if (matrix == null || matrix.length == 0) {
                return res;
            }
            int m = matrix.length;
            int n = matrix[0].length;
            help(matrix, res, 0, m - 1, 0, n - 1);
            return res;
        }
        public void help(int[][] matrix, List<Integer> res, int row_begin, int row_end, int col_begin, int col_end) {
            if (row_begin > row_end || col_begin > col_end) {
                return;
            }
            for (int j = col_begin; j <= col_end; j++) {
                res.add(matrix[row_begin][j]);
            }
            row_begin++;
            for (int i = row_begin; i <= row_end; i++) {
                res.add(matrix[i][col_end]);
            }
            col_end--;
            if (row_begin > row_end) { // Attention!
                return;
            }
            for (int j = col_end; j >= col_begin; j--) {
                res.add(matrix[row_end][j]);
            }
            row_end--;
            if (col_begin > col_end) { // Attention!
                return;
            }
            for (int i = row_end; i >= row_begin; i--) {
                res.add(matrix[i][col_begin]);
            }
            col_begin++;
            help(matrix, res, row_begin, row_end, col_begin, col_end);
        } 
    View Code

    55.Jump Game --- not bug free

    Given an array of non-negative integers, you are initially positioned at the first index of the array.
    
    Each element in the array represents your maximum jump length at that position.
    
    Determine if you are able to reach the last index.
    

    贪心算法。max_reach记录最远可以到达的地方。注意中途不可到达检测的返回(见代码Attention)

    public boolean canJump(int[] nums) {
            if (nums == null || nums.length == 0) {
                return false;
            }
            int max_reach = 0;
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (max_reach < i) { // Attention!
                    return false;
                }
                max_reach = Math.max(max_reach, nums[i] + i);
                if (max_reach >= n - 1) {
                    return true;
                }
            }
            return false;
        }
    View Code

    56.Merge Intervals

    Given a collection of intervals, merge all overlapping intervals.
    
    For example,
    Given [1,3],[2,6],[8,10],[15,18],
    return [1,6],[8,10],[15,18].
    

    方法一:使用stack

    public List<Interval> merge(List<Interval> intervals) {
            LinkedList<Interval> res = new LinkedList<Interval>();
            if (intervals == null || intervals.size() == 0) {
                return res;
            }
            Collections.sort(intervals, new Comparator<Interval>() {
               public int compare(Interval i1, Interval i2) {
                    return i1.start - i2.start;
                } 
            });
            Stack<Interval> stack = new Stack<Interval>();
            for (Interval interval : intervals) {
                if (stack.isEmpty()) {
                    stack.push(interval);
                } else {
                    if (stack.peek().end < interval.start) {
                        stack.push(interval);
                    } else {
                        Interval top = stack.pop();
                        stack.push(new Interval(top.start, Math.max(top.end, interval.end)));
                    }
                }
            }
            while (!stack.isEmpty()) {
                res.addFirst(stack.pop());
            }
            return res;
        }
    View Code

    方法二:使用stack多余了,直接遍历一遍就可以了。

    public List<Interval> merge(List<Interval> intervals) {
            if (intervals == null || intervals.size() < 2) {
                return intervals;
            }
            Collections.sort(intervals, new Comparator<Interval>() {
               public int compare(Interval i1, Interval i2) {
                   return i1.start - i2.start;
               } 
            });
            List<Interval> res = new ArrayList<Interval>();
            int start = intervals.get(0).start;
            int end = intervals.get(0).end;
            for (Interval interval : intervals) {
                if (interval.start > end) {
                    res.add(new Interval(start, end));
                    start = interval.start;
                    end = interval.end;
                } else {
                    end = Math.max(end, interval.end);
                }
            }
            res.add(new Interval(start, end));
            return res;
         }
    View Code

    57.Insert Interval   --- not bug free

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
    You may assume that the intervals were initially sorted according to their start times.
    

    一种方法当然是直接遍历一遍即可。

    另外一种是二分。找到第一个end比新区间左边大于等于的,找到第一个start比新区间右边大于的。 

    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
            List<Interval> res = new ArrayList<Interval>();
            if (intervals == null) {
                return res;
            }
            int left = findFirstBiggerOrEqual(intervals, newInterval.start); // 第一个end比新区间左边大于等于的
            int right = findFirstBigger(intervals, newInterval.end); // 第一个start比新区间右边大于的
            if (left == right) {
                intervals.add(left, newInterval);
                return intervals;
            } else {
                for (int i = 0; i < left; i++) {
                    res.add(intervals.get(i));
                }
                int start = Math.min(newInterval.start, intervals.get(left).start);
                int end = Math.max(newInterval.end, intervals.get(right - 1).end);
                res.add(new Interval(start, end));
                for (int i = right; i < intervals.size(); i++) {
                    res.add(intervals.get(i));
                }
                return res;
            }
        }
        public int findFirstBiggerOrEqual(List<Interval> intervals, int target) {
            if (intervals.size() == 0) {
                return 0;
            }
            int start = 0;
            int end = intervals.size() - 1;
            while (start + 1 < end) {
                int mid = start + (end - start) / 2;
                if (intervals.get(mid).end < target) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
            if (intervals.get(start).end >= target) {
                return start;
            } else if (intervals.get(end).end >= target) {
                return end;
            } else {
                return intervals.size();
            }
        }
        public int findFirstBigger(List<Interval> intervals, int target) {
            if (intervals.size() == 0) {
                return 0;
            }
            int start = 0;
            int end = intervals.size() - 1;
            while (start + 1 < end) {
                int mid = start + (end - start) / 2;
                if (intervals.get(mid).start <= target) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
            if (intervals.get(start).start > target) {
                return start;
            } else if (intervals.get(end).start > target) {
                return end;
            } else {
                return intervals.size();
            }
        }
    View Code

    58.Length of Last Word

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.
    If the last word does not exist, return 0.
    

    由后往前遍历一遍就可以了

    public int lengthOfLastWord(String s) {
            if (s == null || s.length() == 0) {
                return 0;
            }
            s = s.trim();
            char[] chars = s.toCharArray();
            int n = chars.length;
            int res = 0;
            for (int i = n - 1; i >= 0; i--) {
                if (chars[i] == ' ') {
                    return res;
                }
                res++;
            }
            return res;
        }
    View Code

    59.Spiral Matrix II

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.
    
    For example,
    Given n = 3,
    
    You should return the following matrix:
    [
     [ 1, 2, 3 ],
     [ 8, 9, 4 ],
     [ 7, 6, 5 ]
    ]
    

    和Spiral Matrix一样的道理。

    public int[][] generateMatrix(int n) {
            int[][] res = new int[n][n];
            fill(res, 0, n - 1, 0, n - 1, 1);
            return res;
        }
        public void fill(int[][] res, int row_start, int row_end, int col_start, int col_end, int num) {
            if (row_start > row_end || col_start > col_end) {
                return;
            }
            for (int j = col_start; j <= col_end; j++) {
                res[row_start][j] = num++;
            }
            row_start++;
            for (int i = row_start; i <= row_end; i++) {
                res[i][col_end] = num++;
            }
            col_end--;
            if (row_start > row_end) {
                return;
            }
            for (int j = col_end; j >= col_start; j--) {
                res[row_end][j] = num++;
            }
            row_end--;
            if (col_start > col_end) {
                return;
            }
            for (int i = row_end; i >= row_start; i--) {
                res[i][col_start] = num++;
            }
            col_start++;
            fill(res, row_start, row_end, col_start, col_end, num);
        }
    View Code

    60.Permutation Sequence --- not bug free

    The set [1,2,3,…,n] contains a total of n! unique permutations.
    
    By listing and labeling all of the permutations in order,
    We get the following sequence (ie, for n = 3):
    
    "123"
    "132"
    "213"
    "231"
    "312"
    "321"
    Given n and k, return the kth permutation sequence.
    

    依次确定每一位上的数字。

    1, 2 3 4

    2, 1 3 4

    3, 1 2 4

    4, 1 2 3

    k / 阶乘即可确定在哪一堆,即可确定当前数。同理,可以确定所有位上的数。

    public String getPermutation(int n, int k) {
            int[] factors = new int[n + 1];
            factors[0] = 1;
            for (int i = 1; i <= n; i++) {
                factors[i] = factors[i - 1] * i;
            }
            List<Integer> nums = new ArrayList<Integer>();
            for (int i = 1; i <= n; i++) {
                nums.add(i);
            }
            StringBuilder sb = new StringBuilder();
            k--;
            for (int i = 1; i <= n; i++) { // 每一轮循环确定第i位数
                int index = k / factors[n - i];
                sb.append(nums.get(index));
                nums.remove(index);
                k -= index * factors[n - i];
            }
            return sb.toString();
        }
    View Code

    61.Rotate List --- not bug free

    Given a list, rotate the list to the right by k places, where k is non-negative.
    
    For example:
    Given 1->2->3->4->5->NULL and k = 2,
    return 4->5->1->2->3->NULL.
    

    首先求出链表长度count,k % count

    然后通过指针找到翻转的上一个结点

    然后就是一些变换指针的操作

    public ListNode rotateRight(ListNode head, int k) {
            if (head == null) {
                return head;
            }
            ListNode left = head;
            ListNode right = head;
            int count = 0;
            while (right != null) {
                count++;
                right = right.next;
            }
            k %= count;
            right = head;
            for (int i = 0; i < k; i++) {
                right = right.next;
            }
            if (right == left) {
                return head;
            }
            while (right.next != null) {
                right = right.next;
                left = left.next;
            }
            right.next = head;
            ListNode temp = left.next;
            left.next = null;
            return temp;
        }
    View Code

    如果长度过长,k较小的话,上述方法效率较低。所以直接在求长度循环中,加入条件,如果节点数已经到达k,则直接结束循环。

    public ListNode rotateRight(ListNode head, int k) {
            if (head == null) {
                return head;
            }
            ListNode left = head;
            ListNode right = head;
            int count = 0;
            while (right != null && count != k) { // 未遍历完,数目已经达到k个也会停止
                count++;
                right = right.next;
            }
            if (right == null && count == k) { // 刚好有k个结点
                return head;
            }
            if (count < k) {
                k %= count;
                if (k == 0) { // k的整数倍结点
                    return head;
                }
                right = head;
                for (int i = 0; i < k; i++) {
                    right = right.next;
                }
            }
            while (right.next != null) {
                right = right.next;
                left = left.next;
            }
            right.next = head;
            ListNode temp = left.next;
            left.next = null;
            return temp;
        }
    View Code

    62.Unique Paths

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
    
    The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
    
    How many possible unique paths are there?
    

    方法一:二维DP

    public int uniquePaths(int m, int n) {
            int[][] dp = new int[m][n]; // dp[i][j]表示[0, 0]到达[i, j]的方案数
            for (int j = 0; j < n; j++) {
                dp[0][j] = 1;
            }
            for (int i = 1; i < m; i++) {
                dp[i][0] = 1;
            }
            for (int i = 1; i < m; i++) {
                for (int j = 1; j < n; j++) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
            return dp[m - 1][n - 1];
        }
    View Code

    方法二:滚动数组优化

    public int uniquePaths(int m, int n) {
            int[][] dp = new int[2][n];
            for (int j = 0; j < n; j++) {
                dp[0][j] = 1;
            }
            for (int i = 1; i < m; i++) {
                dp[i % 2][0] = 1;
                for (int j = 1; j < n; j++) {
                    dp[i % 2][j] = dp[(i - 1) % 2][j] + dp[i % 2][j - 1];
                }
            }
            return dp[(m - 1) % 2][n - 1];
        }
    View Code

    方法三:Math  C(m + n - 2, n - 1)

    public int uniquePaths(int m, int n) {
            if (m > n) {
                int temp = m;
                m = n;
                n = temp;
            }
            long res = 1;
            for (int i = 1; i < m; i++) {
                res = res * (i + n - 1) / i;
            }
            return (int)res;
        }
    View Code

    63.Unique Paths II

    Follow up for "Unique Paths":
    
    Now consider if some obstacles are added to the grids. How many unique paths would there be?
    
    An obstacle and empty space is marked as 1 and 0 respectively in the grid.
    
    For example,
    There is one obstacle in the middle of a 3x3 grid as illustrated below.
    
    [
      [0,0,0],
      [0,1,0],
      [0,0,0]
    ]
    

    一样的道理。只不过数学方法不能使用了

    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
            int m = obstacleGrid.length;
            int n = obstacleGrid[0].length;
            int[][] dp = new int[2][n];
            for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
                dp[0][j] = 1;
            }
            for (int i = 1; i < m; i++) {
                if (obstacleGrid[i][0] == 0) {
                    dp[i % 2][0] = dp[(i - 1) % 2][0];
                } else {
                    dp[i % 2][0] = 0;
                }
                for (int j = 1; j < n; j++) {
                    if (obstacleGrid[i][j] == 1) {
                        dp[i % 2][j] = 0;
                    } else {
                        dp[i % 2][j] = dp[(i - 1) % 2][j] + dp[i % 2][j - 1];
                    }
                }
            }
            return dp[(m - 1) % 2][n - 1];
        }
    View Code

    64.Minimum Path Sum

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
    
    Note: You can only move either down or right at any point in time.
    

    同理DP

    public int minPathSum(int[][] grid) {
            int m = grid.length;
            int n = grid[0].length;
            int[][] dp = new int[m][n];
            dp[0][0] = grid[0][0];
            for (int j = 1; j < n; j++) {
                dp[0][j] = dp[0][j - 1] + grid[0][j];
            }
            for (int i = 1; i < m; i++) {
                dp[i][0] = dp[i - 1][0] + grid[i][0];
            }
            for (int i = 1; i < m; i++) {
                for (int j = 1; j < n; j++) {
                    dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
                }
            }
            return dp[m - 1][n - 1];
        }
    View Code

    65.Valid Number

    Validate if a given string is numeric.
    
    Some examples:
    "0" => true
    " 0.1 " => true
    "abc" => false
    "1 a" => false
    "2e10" => true
    Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
    

    可能出现的字符有 数字 . e + -

    必须有数字出现

    e前边必须有数字 e后边必须有数字 e只能出现一次

    .前边不能有e .只能出现一次

    + -只能出现在开头或者e后边

    public boolean isNumber(String s) {
            if (s == null) {
                return false;
            }
            s = s.trim();
            char[] chars = s.toCharArray();
            boolean numSeen = false;
            boolean numAfterE = false;
            boolean eSeen = false;
            boolean dotSeen = false;
            int n = s.length();
            for (int i = 0; i < n; i++) {
                char c = chars[i];
                if (Character.isDigit(c)) {
                    numSeen = true;
                    numAfterE = true;
                } else if (c == 'e') {
                    if (eSeen || !numSeen) {
                        return false;
                    }
                    eSeen = true;
                    numAfterE = false;
                } else if (c == '.'){
                    if (eSeen || dotSeen) {
                        return false;
                    }
                    dotSeen = true;
                } else if (c == '+' || c == '-') {
                    if (i != 0 && chars[i - 1] != 'e') {
                        return false;
                    }
                } else {
                    return false;
                }
            }
            return numSeen && numAfterE;
        }
    View Code

    66.Plus One

    Given a non-negative integer represented as a non-empty array of digits, plus one to the integer.
    
    You may assume the integer do not contain any leading zero, except the number 0 itself.
    
    The digits are stored such that the most significant digit is at the head of the list.
    

    直接从后往前 carry携带进位就可以了

    def plusOne(self, digits):
            """
            :type digits: List[int]
            :rtype: List[int]
            """
            if not digits:
                return digits
            res = []
            carry = 1
            n = len(digits) - 1
            for i in xrange(n, -1, -1):
                temp = carry + digits[i]
                res.insert(0, temp % 10)
                carry = temp / 10
            if carry == 1:
                res.insert(0, 1)
            return res
    View Code

    直接原数组上操作

    def plusOne(self, digits):
            """
            :type digits: List[int]
            :rtype: List[int]
            """
            if not digits:
                return digits
            carry = 1
            n = len(digits) - 1
            for i in xrange(n, -1, -1):
                temp = carry + digits[i]
                digits[i] = temp % 10
                carry = temp / 10
                if carry == 0:
                    break
            if carry == 1:
                digits.insert(0, 1)
            return digits
    View Code

    67.Add Binary

    Given two binary strings, return their sum (also a binary string).
    
    For example,
    a = "11"
    b = "1"
    Return "100".
    

    从后开始,当前位为异或,carry当1的个数大于等于2为正

    def addBinary(self, a, b):
            """
            :type a: str
            :type b: str
            :rtype: str
            """
            if not a:
                return b
            if not b:
                return a
            m = len(a) - 1
            n = len(b) - 1
            carry = 0
            res = ""
            while m >= 0 or n >= 0 or carry != 0:
                oneNum = carry
                if m >= 0:
                    carry ^= int(a[m])
                    if a[m] == '1':
                        oneNum += 1
                if n >= 0:
                    carry ^= int(b[n])
                    if b[n] == '1':
                        oneNum += 1
                res = str(carry) + res
                carry = 1 if oneNum >= 2 else 0
                m -= 1
                n -= 1
            return res
    View Code

    68.Text Justification --- not bug free

    Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.
    
    You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters.
    
    Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
    
    For the last line of text, it should be left justified and no extra space is inserted between words.
    
    For example,
    words: ["This", "is", "an", "example", "of", "text", "justification."]
    L: 16.
    

    遍历原来的字符串数组,prevLen 和 afterLen分别表示不加和加上当前这个单词后的长度。

    如果 afterLen <= maxDepth:

      如果已经到达最后一个单词,那个直接处理即可

      如果没有达到,那么prevLen更新为afterLen,继续下一个

    afterLen > maxDepth:

      表明当前这个不能连上,所以处理前边的,处理前边时候由于涉及除以(end - start),所以对于一个单词的情况单独处理

    def fullJustify(self, words, maxWidth):
            """
            :type words: List[str]
            :type maxWidth: int
            :rtype: List[str]
            """
            if not words:
                return []
            res = []
            prevLen = 0
            afterLen = 0
            n = len(words)
            start = 0
            i = 0
            while i < n:
                afterLen = prevLen + len(words[i]) + (0 if prevLen == 0 else 1)
                if afterLen <= maxWidth:
                    if i == n - 1: # 到达最后一行
                        cur = ""
                        for j in xrange(start, i):
                            cur += words[j] + " "
                        cur += words[i]
                        cur += " " * (maxWidth - afterLen)
                        res.append(cur)
                        return res
                    else:
                        prevLen = afterLen
                        i += 1
                else:
                    end = i - 1
                    if end - start == 0: # 一个单词占一行
                        cur = words[start]
                        cur += " " * (maxWidth - prevLen)
                        res.append(cur)
                    else:
                        space_total = maxWidth - prevLen
                        space_one = space_total / (end - start)
                        space_ugly = space_total % (end - start)
                        cur = ""
                        for j in xrange(start, end):
                            if space_ugly > 0:
                                cur = cur + words[j] + " " * (space_one + 2)
                                space_ugly -= 1
                            else:
                                cur = cur + words[j] + " " * (space_one + 1)
                        cur += words[end]
                        res.append(cur)
                    prevLen = 0
                    start = i
            return res
    View Code

     69.Sqrt(x)

    Implement int sqrt(int x).
    
    Compute and return the square root of x.
    

    二分。

    def mySqrt(self, x):
            """
            :type x: int
            :rtype: int
            """
            start = 0
            end = x
            while start + 1 < end:
                mid = (start + end) / 2
                square = mid * mid
                if square < x:
                    start = mid
                elif square > x:
                    end = mid
                else:
                    return mid
            if end * end <= x:
                return end
            else:
                return start
    View Code

    70.Climbing Stairs

    You are climbing a stair case. It takes n steps to reach to the top.
    
    Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
    
    def climbStairs(self, n):
            """
            :type n: int
            :rtype: int
            """
            if n == 0:
                return 1
            if n <= 2:
                return n
            prevOne = 2
            prevTwo = 1
            for i in range(2, n):
                temp = prevOne
                prevOne = prevOne + prevTwo
                prevTwo = temp
            return prevOne
    View Code

    71.Simplify Path

    Given an absolute path for a file (Unix-style), simplify it.
    
    For example,
    path = "/home/", => "/home"
    path = "/a/./b/../../c/", => "/c"
    View Code

    使用stack。'..'弹出; '.' 不处理;'//'和'/'效果一样

    def simplifyPath(self, path):
            """
            :type path: str
            :rtype: str
            """
            if not path:
                return None
            strs = path.split("/")
            # print len(strs)
            stack = []
            for str in strs:
                if str == '..' and stack:
                    stack.pop()
                elif str != '..' and str != '.' and str != '':
                    stack.append(str)
            res = ''
            for str in stack:
                res += str + '/'
            res = '/' + res.strip('/')
            return res
    View Code

     72.Edit Distance

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
    
    You have the following 3 operations permitted on a word:
    
    a) Insert a character
    b) Delete a character
    c) Replace a character
    

    dp.

     def minDistance(self, word1, word2):
            """
            :type word1: str
            :type word2: str
            :rtype: int
            """
            if not word1 and not word2:
                return 0
            m = len(word1)
            n = len(word2)
            dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
            for i in range(n + 1):
                dp[0][i] = i
            for i in range(m + 1):
                dp[i][0] = i
            for i in range(1, m + 1):
                for j in range(1, n + 1):
                    if word1[i - 1] == word2[j - 1]:
                        dp[i][j] = dp[i - 1][j - 1]
                    else:
                        dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1
            return dp[m][n]
    View Code

     73.Set Matrix Zeroes --- not bug free

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
    
    click to show follow up.
    
    Follow up:
    Did you use extra space?
    A straight forward solution using O(mn) space is probably a bad idea.
    A simple improvement uses O(m + n) space, but still not the best solution.
    Could you devise a constant space solution?
    

    用第一行第一列来记录这行这列是否有"0",但是首先需要一个boolean来记录最开始的第一行第一列时候本身就有0。注意代码中Attention部分

    def setZeroes(self, matrix):
            """
            :type matrix: List[List[int]]
            :rtype: void Do not return anything, modify matrix in-place instead.
            """
            if not matrix:
                return
            m = len(matrix)
            n = len(matrix[0])
            firstRow = False
            firstCol = False
            for j in xrange(n):
                if matrix[0][j] == 0:
                    firstRow = True
                    break
            for i in xrange(m):
                if matrix[i][0] == 0:
                    firstCol = True
                    break
            for i in xrange(m):
                for j in xrange(n):
                    if matrix[i][j] == 0:
                        matrix[i][0] = 0
                        matrix[0][j] = 0
            for i in xrange(1, m): # Attention
                if matrix[i][0] == 0:
                    self.setRowZero(matrix, i)
            for j in xrange(1, n): # Attention
                if matrix[0][j] == 0:
                    self.setColZero(matrix, j)
            if firstRow:
                self.setRowZero(matrix, 0)
            if firstCol:
                self.setColZero(matrix, 0)
        def setColZero(self, matrix, col):
            m = len(matrix)
            for i in range(m):
                matrix[i][col] = 0
        def setRowZero(self, matrix, row):
            n = len(matrix[0])
            for j in range(n):
                matrix[row][j] = 0
    View Code

     74.Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
    
    Integers in each row are sorted from left to right.
    The first integer of each row is greater than the last integer of the previous row.
    

    二分。

    def searchMatrix(self, matrix, target):
            """
            :type matrix: List[List[int]]
            :type target: int
            :rtype: bool
            """
            if not matrix:
                return False
            m = len(matrix)
            n = len(matrix[0])
            if m == 0 or n == 0:
                return False
            start = 0
            end = m * n - 1
            while start + 1 < end:
                mid = (start + end) / 2
                num = matrix[mid / n][mid % n]
                if num == target:
                    return True
                elif num < target:
                    start = mid
                else:
                    end = mid
            return matrix[start / n][start % n] == target or matrix[end / n][end % n] == target
    View Code

    75.Sort Colors

    Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.
    
    Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
    

    两边两个指针控制,中间index移动。注意的是,左边换过去的时候,index也要+1,如代码Attention所示

    def sortColors(self, nums):
            """
            :type nums: List[int]
            :rtype: void Do not return anything, modify nums in-place instead.
            """
            if not nums:
                return
            n = len(nums)
            left = 0
            right = n - 1
            index = 0
            while index <= right:
                if nums[index] == 0:
                    temp = nums[left]
                    nums[left] = nums[index]
                    nums[index] = temp
                    left += 1
                    index += 1 # Attention!
                elif nums[index] == 2:
                    temp = nums[right]
                    nums[right] = nums[index]
                    nums[index] = temp
                    right -= 1
                else:
                    index += 1
    View Code

     76.Minimum Window Substring

    Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
    
    For example,
    S = "ADOBECODEBANC"
    T = "ABC"
    Minimum window is "BANC".
    

    和第30题比较接近,区别是这里允许有无关字符的出现。

    用一个map记录tLen中字符的出现。然后遍历sLen,二话不说,map对应位置先减,如果减了之后大于等于0,表明这是一个“有用的”,更新count。当count为0的时候,更新结果。并且二话不说先加,如果加完后map[start] > 0,表明这是一个有用的,更新count。

    def minWindow(self, s, t):
            """
            :type s: str
            :type t: str
            :rtype: str
            """
            if not s or not t:
                return ""
            sLen = len(s)
            tLen = len(t)
            if sLen < tLen:
                return ""
            map = [0] * 128
            for c in t:
                map[ord(c)] += 1
            minStart = 0
            minEnd = sLen
            start = 0
            count = tLen
            for i in xrange(sLen):
                map[ord(s[i])] -= 1
                if map[ord(s[i])] >= 0:
                    count -= 1
                while count == 0:
                    if i - start < minEnd - minStart:
                        minStart = start
                        minEnd = i
                    map[ord(s[start])] += 1
                    if map[ord(s[start])] > 0:
                        count += 1
                    start += 1
                    if start + tLen > sLen:
                        break
            if minStart == 0 and minEnd == sLen:
                return ""
            else:
                return s[minStart:minEnd + 1]
    View Code

     77.Combinations

    Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
    
    For example,
    If n = 4 and k = 2, a solution is:
    
    [
      [2,4],
      [3,4],
      [2,3],
      [1,2],
      [1,3],
      [1,4],
    ]
    

    注意代码中Attention部分的处理。当剩余的个数加起来达不到k个的时候,就不需要再深搜下去,这可以节约很多时间。否则TLE了

    def combine(self, n, k):
            """
            :type n: int
            :type k: int
            :rtype: List[List[int]]
            """
            res = []
            if n < k:
                return res
            self.dfs(n, k, res, [], 1)
            return res
        def dfs(self, n, k, res, cur, index):
            if len(cur) == k:
                res.append(cur[:])
                return
            for i in xrange(index, n + 1):
                if (n - i + 1 + len(cur) < k): # Attention!
                    break;
                cur.append(i)
                self.dfs(n, k, res, cur, i + 1)
                cur.pop()
    View Code

    78.Subsets

    Given a set of distinct integers, nums, return all possible subsets.
    

    DFS

    def subsets(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            res = []
            if not nums:
                return res
            self.dfs(nums, 0, res, [])
            return res
        def dfs(self, nums, index, res, cur):
            res.append(cur[:])
            n = len(nums)
            for i in xrange(index, n):
                cur.append(nums[i])
                self.dfs(nums, i + 1, res, cur)
                cur.pop()
    View Code

    79.Word Search

    Given a 2D board and a word, find if the word exists in the grid.
    
    The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
    

    DFS.

     def exist(self, board, word):
            """
            :type board: List[List[str]]
            :type word: str
            :rtype: bool
            """
            if not board or not word:
                return False
            m = len(board)
            n = len(board[0])
            if m * n < len(word):
                return False
            for i in xrange(m):
                for j in xrange(n):
                    if self.dfs(board, word, i, j, 0):
                        return True;
            return False
        def dfs(self, board, word, i, j, index):
            m = len(board)
            n = len(board[0])
            if index == len(word):
                return True
            if i < 0 or i >= m:
                return False
            if j < 0 or j >= n:
                return False
            if board[i][j] != word[index]:
                return False
            temp = board[i][j]
            board[i][j] = '.'
            res =  self.dfs(board, word, i + 1, j, index + 1) 
                or self.dfs(board, word, i - 1, j, index + 1) 
                or self.dfs(board, word, i, j + 1, index + 1) 
                or self.dfs(board, word, i, j - 1, index + 1)
            board[i][j] = temp
            return res
    View Code

    80.Remove Duplicates from Sorted Array II

    Follow up for "Remove Duplicates":
    What if duplicates are allowed at most twice?
    
    For example,
    Given sorted array nums = [1,1,1,2,2,3],
    
    Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length.
    

    times记录次数,首先start = 0 times = 1,start位置表示已经满足了。然后遍历数组,如果nums[i] == nums[start] and times >= 2表明不可加进来,否则可以加进来。加进来要看nums[i]和nums[start]的关系控制times的取值变化。然后start + 1后值换过来。

    def removeDuplicates(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            if not nums:
                return 0
            n = len(nums)
            start = 0
            times = 1
            for i in xrange(1, n):
                if nums[i] == nums[start] and times >= 2:
                    continue
                else:
                    if nums[i] == nums[start]:
                        times += 1
                    else:
                        times = 1
                    start += 1
                    nums[start] = nums[i]
            return start + 1
    View Code

    81.Search in Rotated Sorted Array II

    Follow up for "Search in Rotated Sorted Array":
    What if duplicates are allowed?
    
    Would this affect the run-time complexity? How and why?
    

    允许重复了,那么其实最坏的复杂度就会达到O(n)了。这里首先移动start,让nums[start] != nums[end]是为了保证:如果nums[start] <= nums[mid],那么[start, mid]一定是单增的,然后分段来考虑. 1 3 1 1 1

    def search(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: bool
            """
            if not nums:
                return False
            n = len(nums)
            start = 0
            end = n - 1
            while start < end and nums[start] == nums[end]: # 保证start到mid一定是单增的
                start += 1
            while start + 1 < end:
                mid = (start + end) / 2
                if nums[start] <= nums[mid]:
                    if nums[start] <= target and target <= nums[mid]:
                        end = mid
                    else:
                        start = mid
                else:
                    if nums[mid] <= target and target <= nums[end]:
                        start = mid
                    else:
                        end = mid
            return nums[start] == target or nums[end] == target
    View Code

     82.Remove Duplicates from Sorted List II

    Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
    
    For example,
    Given 1->2->3->3->4->4->5, return 1->2->5.
    Given 1->1->1->2->3, return 2->3.
    

    有重复往后走,最后看tail.next是否等于head,等的话表明head位置这个值满足条件,不等的话不满足。

     def deleteDuplicates(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            if not head:
                return head
            dummyHead = ListNode(0)
            dummyHead.next = head
            tail = dummyHead
            while head:
                while head.next and head.val == head.next.val:
                    head = head.next
                if tail.next == head:
                    tail = head
                    head = head.next
                else:
                    head = head.next
                    tail.next = head
            return dummyHead.next
    View Code

    83.Remove Duplicates from Sorted List

    Given a sorted linked list, delete all duplicates such that each element appear only once.
    
    For example,
    Given 1->1->2, return 1->2.
    Given 1->1->2->3->3, return 1->2->3.
    

    现在允许重复的出现一次就更好办了。如果cur.val == cur.next.val 那么 cur.next = cur.next.next

    def deleteDuplicates(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            if not head:
                return head
            cur = head
            while cur:
                tmp = cur.val
                while cur.next and cur.next.val == tmp:
                    cur.next = cur.next.next
                cur = cur.next
            return head
    View Code

     84.Largest Rectangle in Histogram

    Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
    

    方法一:最大直方图面积,递增栈。新来的元素如果大于栈顶元素,那么压入栈,小于等于栈顶元素,表明此时栈顶元素的右边界已经找到,弹出后的新栈顶就是之前栈顶的左边界。注意栈中存储的是下标,最后需要一个统一弹出,计算下标区间长度的时候不包含端点。

    def largestRectangleArea(self, heights):
            """
            :type heights: List[int]
            :rtype: int
            """
            if not heights:
                return 0
            s = []
            n = len(heights)
            res = 0
            s.append(-1)
            for i in xrange(n + 1):
                cur = (-1 << 31) if i == n else heights[i]
                if len(s) == 1 or heights[s[-1]] < cur:
                    s.append(i)
                else:
                    while len(s) > 1 and heights[s[-1]] >= cur:
                        index = s.pop()
                        res = max(res, (i - s[-1] - 1) * heights[index])
                    s.append(i)
            return res
    View Code

     方法二:DP.left[i] right[i]分别表示往左边和往右边可以扩展多少

    def largestRectangleArea(self, heights):
            """
            :type heights: List[int]
            :rtype: int
            """
            if not heights:
                return 0
            n = len(heights)
            left = [0] * n # 高度扩张的最左边
            right = [0] * n # 高度扩张的最右边
            for i in xrange(1, n):
                index = i - 1
                while index >= 0 and heights[index] >= heights[i]:
                    index = left[index] - 1
                left[i] = index + 1
            right[-1] = n - 1
            res = (right[-1] - left[-1] + 1) * heights[-1]
            for i in xrange(n - 1, -1, -1):
                index = i + 1
                while index < n and heights[index] >= heights[i]:
                    index = right[index] + 1
                right[i] = index - 1
                res = max(res, (right[i] - left[i] + 1) * heights[i])
            return res
    View Code

    85.Maximal Rectangle

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
    
    For example, given the following matrix:
    
    1 0 1 0 0
    1 0 1 1 1
    1 1 1 1 1
    1 0 0 1 0
    Return 6.
    

    当然,第一种思路可以考虑以每一行为底的最大矩形,就相当于做了n次的Largest Rectangle in Histogram,用左右扩的方法的话最坏的时间复杂度是O(n * m ^ 2),用递增栈的话最坏的时间复杂度是O(n * m)

    这里不直接的转化为一维,而是直接操作。引入一个curLeft记录当前往左扩和当前往右扩,最后时间复杂度优化到O(n * m)

    def maximalRectangle(self, matrix):
            """
            :type matrix: List[List[str]]
            :rtype: int
            """
            if not matrix:
                return 0
            m = len(matrix)
            n = len(matrix[0])
            heights = [0] * n
            left = [0] * n
            right = [n] * n
            res = 0
            for i in xrange(m):
                curLeft = 0
                curRight = n
                for j in xrange(n):
                    if matrix[i][j] == '1':
                        heights[j] += 1
                        left[j] = max(left[j], curLeft)
                    else:
                        heights[j] = 0
                        left[j] = 0
                        curLeft = j + 1
                for j in xrange(n - 1, -1, -1):
                    if matrix[i][j] == '1':
                        right[j] = min(right[j], curRight)
                        res = max(res, (right[j] - left[j]) * heights[j])
                    else:
                        right[j] = n
                        curRight = j
            return res
    View Code

     86.Partition List

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
    
    You should preserve the original relative order of the nodes in each of the two partitions.
    
    For example,
    Given 1->4->3->2->5->2 and x = 3,
    return 1->2->2->4->3->5.
    

    dummySmall

    dummyBigger

    tailSmall

    tailBigger

    需要注意的是最后把tailBigger.next = None

    def partition(self, head, x):
            """
            :type head: ListNode
            :type x: int
            :rtype: ListNode
            """
            if not head:
                return head
            dummySmall = ListNode(0)
            tailSmall = dummySmall
            dummyBigger = ListNode(0)
            tailBigger = dummyBigger
            while head:
                if head.val < x:
                    tailSmall.next = head
                    tailSmall = head
                    head = head.next
                else:
                    tailBigger.next = head
                    tailBigger = head
                    head = head.next
            tailSmall.next = dummyBigger.next
            tailBigger.next = None #Attention!
            return dummySmall.next
    View Code

    87.Scramble String

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
    
    Below is one possible representation of s1 = "great":
    
        great
       /    
      gr    eat
     /     /  
    g   r  e   at
               / 
              a   t
    To scramble the string, we may choose any non-leaf node and swap its two children.
    
    For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat".
    
        rgeat
       /    
      rg    eat
     /     /  
    r   g  e   at
               / 
              a   t
    We say that "rgeat" is a scrambled string of "great".
    
    Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".
    
        rgtae
       /    
      rg    tae
     /     /  
    r   g  ta  e
           / 
          t   a
    We say that "rgtae" is a scrambled string of "great".
    
    Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
    

    递归。检测字符出现的是不是一样,然后左右取,左右等去判断

    def isScramble(self, s1, s2):
            """
            :type s1: str
            :type s2: str
            :rtype: bool
            """
            if s1 == s2:
                return True
            if not s1 or not s2:
                return False
            m = len(s1)
            n = len(s2)
            if m != n:
                return False
            map = [0] * 128
            for c in s1:
                map[ord(c)] += 1
            for c in s2:
                if map[ord(c)] == 0:
                    return False
                map[ord(c)] -= 1
            for i in range(1, m):
                if self.isScramble(s1[i:], s2[i:]) and self.isScramble(s1[:i], s2[:i]):
                    return True
                if self.isScramble(s1[i:], s2[:n - i]) and self.isScramble(s1[:i], s2[n - i:]):
                    return True
            return False
    View Code

     88.Merge Sorted Array

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
    
    Note:
    You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.
    

    三个指针控制移动即可。

    def merge(self, nums1, m, nums2, n):
            """
            :type nums1: List[int]
            :type m: int
            :type nums2: List[int]
            :type n: int
            :rtype: void Do not return anything, modify nums1 in-place instead.
            """
            index = m + n - 1
            m -= 1
            n -= 1
            while m >= 0 and n >= 0:
                if nums1[m] > nums2[n]:
                    nums1[index] = nums1[m]
                    m -= 1
                    index -= 1
                else:
                    nums1[index]= nums2[n]
                    n -= 1
                    index -= 1
            while n >= 0:
                nums1[index] = nums2[n]
                index -= 1
                n -= 1
    View Code

    89.Gray Code

    The gray code is a binary numeral system where two successive values differ in only one bit.
    
    Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
    
    For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
    
    00 - 0
    01 - 1
    11 - 3
    10 - 2
    

    n + 1是n的数,再加上n的数的倒序加上当前增长值

     def grayCode(self, n):
            """
            :type n: int
            :rtype: List[int]
            """
            if n <= 0:
                return [0]
            res = [0, 1]
            temp = 2
            for i in xrange(1, n):
                size = len(res)
                for j in xrange(size - 1, -1, -1):
                    res.append(res[j] + temp)
                temp *= 2
            return res
    View Code

    90.Subsets II

    Given a collection of integers that might contain duplicates, nums, return all possible subsets.
    
    Note: The solution set must not contain duplicate subsets.
    
    For example,
    If nums = [1,2,2], a solution is:
    
    [
      [2],
      [1],
      [1,2,2],
      [2,2],
      [1,2],
      []
    ]
    

    DFS

    def subsetsWithDup(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            res = []
            if not nums:
                return res
            nums.sort()
            self.dfs(nums, res, [], 0)
            return res
        def dfs(self, nums, res, cur, index):
            res.append(cur[:])
            n = len(nums)
            for i in xrange(index, n):
                if i != index and nums[i] == nums[i - 1]:
                    continue
                cur.append(nums[i])
                self.dfs(nums, res, cur, i + 1)
                cur.pop()
    View Code

    91.Decode Ways --- not nug free

    A message containing letters from A-Z is being encoded to numbers using the following mapping:
    
    'A' -> 1
    'B' -> 2
    ...
    'Z' -> 26
    Given an encoded message containing digits, determine the total number of ways to decode it.
    
    For example,
    Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).
    
    The number of ways decoding "12" is 2.
    

    dp[i]表示必须以i结尾的译码方案数

    遍历原字符串,首先以s[i- 1]是否为‘0’划分,为‘0’的很简单;不为‘0’的话,获取前一位结合的数num,分num>26与否,大于26很简单,小于的话,以s[i]是否为‘0’来划分。

     def numDecodings(self, s):
            """
            :type s: str
            :rtype: int
            """
            if not s:
                return 0
            if s[0] == '0':
                return 0
            n = len(s)
            dp = [0] * n
            dp[0] = 1
            for i in xrange(1, n):
                if s[i - 1] == '0':
                    if s[i] == '0':
                        return 0
                    else:
                        dp[i] = dp[i - 1]
                else:
                    num = int(s[i - 1]) * 10 + int(s[i])
                    if num > 26:
                        if s[i] == '0':
                            return 0
                        else:
                            dp[i] = dp[i - 1]
                    else:
                        if s[i] == '0':
                            dp[i] = dp[i - 2] if i >= 2 else 1
                        else:
                            dp[i] = dp[i - 1] + dp[i - 2] if i >= 2 else 2
            return dp[-1]
    View Code

     92.Reverse Linked List II

    Reverse a linked list from position m to n. Do it in-place and in one-pass.
    
    For example:
    Given 1->2->3->4->5->NULL, m = 2 and n = 4,
    
    return 1->4->3->2->5->NULL.
    
    Note:
    Given m, n satisfy the following condition:
    1 ≤ m ≤ n ≤ length of list.
    

    首先找到第m个结点的上一个结点prev,然后prev1.next = 后边的逆序,逆序部分也要和后边接上。

    def reverseBetween(self, head, m, n):
            """
            :type head: ListNode
            :type m: int
            :type n: int
            :rtype: ListNode
            """
            if not head:
                return head
            dummyHead = ListNode(0)
            dummyHead.next = head
            prev1 = dummyHead
            for i in xrange(1, m):
                # if not prev1:
                #     return None
                prev1= prev1.next
            prev1.next = self.reverse(prev1.next, m, n)
            return dummyHead.next
        def reverse(self, head, m, n):
            temp1 = head
            prev = None
            n += 1
            for i in xrange(m, n):
                # if not head:
                #     return None
                temp = head.next
                head.next = prev
                prev = head
                head = temp
            temp1.next = head
            return prev
    View Code

    93.Restore IP Addresses --- not nug free

    Given a string containing only digits, restore it by returning all possible valid IP address combinations.
    
    For example:
    Given "25525511135",
    
    return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)
    

    backtracking.

    start记录ip的这一位的开始点,然后遍历其往后的三为看可不可以构成一个0-255的数,深搜下去。

    注意python的 if else 三目运算语句的优先级比算数运算符优先级高。

     def restoreIpAddresses(self, s):
            """
            :type s: str
            :rtype: List[str]
            """
            if not s or len(s) < 4 or len(s) > 12:
                return []
            res = []
            self.dfs(s, res, 0, 0, '')
            return res
        def dfs(self, s, res, start, count, ip):
            if count > 4:
                return
            if count == 4 and start == len(s):
                res.append(ip[:])
                return
            for i in xrange(1, 4):
                if start + i > len(s):
                    break
                temp = s[start:start + i]
                if temp[0] == '0' and i != 1:
                    break
                if i == 3 and int(temp) > 255:
                    break
                self.dfs(s, res, start + i, count + 1, ip + temp + ('' if count == 3 else '.'))
    View Code

    94.Binary Tree Inorder Traversal

    递归:

    def inorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            res = []
            self.inorderTraverse(root, res)
            return res
        def inorderTraverse(self, root, res):
            if not root:
                return
            self.inorderTraverse(root.left, res)
            res.append(root.val)
            self.inorderTraverse(root.right, res)
    View Code

    非递归:

    def inorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            res = []
            if not root:
                return res
            stack = []
            while stack or root:
                while root:
                    stack.append(root)
                    root = root.left
                root = stack.pop()
                res.append(root.val)
                root = root.right
            return res
    View Code

    95.Unique Binary Search Trees II --- not nug free

    Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n.
    
    For example,
    Given n = 3, your program should return all 5 unique BST's shown below.
    
       1         3     3      2      1
               /     /      /       
         3     2     1      1   3      2
        /     /                        
       2     1         2                 3
    

    分治。分治程序求解[start, end]的所有树,可以以这区间的任何一个为根节点,左右分治。注意代码中Attention!

    def generateTrees(self, n):
            """
            :type n: int
            :rtype: List[TreeNode]
            """
            if n < 1:
                return []
            return self.help(1, n)
        def help(self, start, end):
            res = []
            if start > end:
                res.append(None) #Attention!
                return res
            if start == end:
                res.append(TreeNode(start))
                return res
            for i in xrange(start, end + 1):
                left = self.help(start, i - 1)
                right = self.help(i + 1, end)
                for l in left:
                    for r in right:
                        root = TreeNode(i) # Attnetion!
                        root.left = l
                        root.right = r
                        res.append(root)
            return res
    View Code

    dp。方法一中涉及许多重复计算,所以这里使用dp。dp[i]表示[1,i]的所有树

    def generateTrees(self, n):
            """
            :type n: int
            :rtype: List[TreeNode]
            """
            if n < 1:
                return []
            dp = []
            dp.append([])
            dp[0].append(None)
            for i in xrange(1, (n + 1)):
                dp.append([])
                for j in xrange(i):
                    left = dp[j]
                    right = dp[i - j - 1]
                    for l in left:
                        for r in right:
                            root = TreeNode(j + 1)
                            root.left = l
                            root.right = self.clone(r, j + 1)
                            dp[i].append(root)
            return dp[n]
        def clone(self, root, num):
            if not root:
                return None
            newRoot = TreeNode(root.val + num)
            newRoot.left = self.clone(root.left, num)
            newRoot.right = self.clone(root.right, num)
            return newRoot
    View Code

     96. Unique Binary Search Trees

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
    
    For example,
    Given n = 3, there are a total of 5 unique BST's.
    
       1         3     3      2      1
               /     /      /       
         3     2     1      1   3      2
        /     /                        
       2     1         2                 3
    

    dp.dp[i]表示[1, i]的方案数。

    def numTrees(self, n):
            """
            :type n: int
            :rtype: int
            """
            if n < 1:
                return 0
            dp = [0] * (n + 1)
            dp[0] = 1
            for i in xrange(1, n + 1):
                for j in xrange(i):
                    dp[i] += dp[j] * dp[i - 1 - j]
            return dp[n]
    View Code

    97.Interleaving String

    Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
    
    For example,
    Given:
    s1 = "aabcc",
    s2 = "dbbca",
    
    When s3 = "aadbbcbcac", return true.
    When s3 = "aadbbbaccc", return false.
    

    dp.dp[i][j]表示s1的前i个字符,s2的前j个字符是否能够与s3的前i + j个字符匹配

    def isInterleave(self, s1, s2, s3):
            """
            :type s1: str
            :type s2: str
            :type s3: str
            :rtype: bool
            """
            m = len(s1)
            n = len(s2)
            if m + n != len(s3):
                return False
            dp = [[False for j in xrange(n + 1)] for i in xrange(m + 1)] # dp[i][j]表示s1的前i个字符,s2的前j个字符是否能够与s3的前i + j个字符匹配
            dp[0][0] = True
            for j in xrange(1, (n + 1)):
                if s2[j - 1] == s3[j - 1]:
                    dp[0][j] = True
                else:
                    break
            for i in xrange(1, (m + 1)):
                if (s1[i - 1] == s3[i - 1]):
                    dp[i][0] = True
                else:
                    break
            for i in xrange(1, (m + 1)):
                for j in xrange(1, (n + 1)):
                    if s1[i - 1] == s3[i + j - 1]:
                        dp[i][j] |= dp[i - 1][j]
                    if s2[j - 1] == s3[i + j - 1]:
                        dp[i][j] |= dp[i][j - 1]
            return dp[m][n]
    View Code

    98.Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST).
    
    Assume a BST is defined as follows:
    
    The left subtree of a node contains only nodes with keys less than the node's key.
    The right subtree of a node contains only nodes with keys greater than the node's key.
    Both the left and right subtrees must also be binary search trees.
    Example 1:
        2
       / 
      1   3
    Binary tree [2,1,3], return true.
    Example 2:
        1
       / 
      2   3
    Binary tree [1,2,3], return false.
    

    递归。递归程序控制一个最大值和最小值,注意最开始的这个最大值和最小值的初始化问题。

    def isValidBST(self, root):
            """
            :type root: TreeNode
            :rtype: bool
            """
            return self.help(root, (1 << 31), (-1 << 31) - 1)
        def help(self, root, maxNum, minNum):
            if not root:
                return True
            if minNum < root.val < maxNum:
                return self.help(root.left, root.val, minNum) and self.help(root.right, maxNum, root.val) 
            else:
                return False
    View Code

     99.Recover Binary Search Tree

    wo elements of a binary search tree (BST) are swapped by mistake.
    
    Recover the tree without changing its structure.
    
    Note:
    A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

    中序遍历变形。找到prev.val > root.val的。

    非递归:

    def recoverTree(self, root):
            """
            :type root: TreeNode
            :rtype: void Do not return anything, modify root in-place instead.
            """
            first = None
            second = None
            prev = None
            stack = []
            while stack or root:
                while root:
                    stack.append(root)
                    root = root.left
                root = stack.pop()
                if prev and prev.val > root.val:
                    if first:
                        second = root
                        break
                    else:
                        first = prev
                        second = root
                prev = root
                root = root.right
            if first:
                temp = first.val
                first.val = second.val
                second.val = temp
    View Code

    递归:

    first = None
        second = None
        prev = None
        def recoverTree(self, root):
            """
            :type root: TreeNode
            :rtype: void Do not return anything, modify root in-place instead.
            """
            global first
            global second
            self.inorderHelp(root)
            if self.first:
                temp = self.first.val
                self.first.val = self.second.val
                self.second.val = temp
        def inorderHelp(self, root):
            global first
            global second
            global prev
            if not root:
                return
            self.inorderHelp(root.left)
            if self.prev and self.prev.val > root.val:
                if self.first:
                    self.second = root
                    return
                else:
                    self.first = self.prev
                    self.second = root
            self.prev = root
            self.inorderHelp(root.right)
    View Code

     100.Same Tree

    Given two binary trees, write a function to check if they are equal or not.
    
    Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

     分治。

    def isSameTree(self, p, q):
            """
            :type p: TreeNode
            :type q: TreeNode
            :rtype: bool
            """
            if not p and not q:
                return True
            if not p:
                return False
            if not q:
                return False
            if p.val != q.val:
                return False
            return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
    View Code

    101.Symmetric Tree

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
    
    For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
    
        1
       / 
      2   2
     /  / 
    3  4 4  3
    But the following [1,2,2,null,3,null,3] is not:
        1
       / 
      2   2
          
       3    3  

    分治。

    def isSymmetric(self, root):
            """
            :type root: TreeNode
            :rtype: bool
            """
            if not root:
                return True
            return self.isSame(root.left, root.right)
        def isSame(self, root1, root2):
            if not root1 and not root2:
                return True
            if not root1 or not root2:
                return False
            if root1.val != root2.val:
                return False
            return self.isSame(root1.left, root2.right) and self.isSame(root1.right, root2.left)
    View Code

    102.Binary Tree Level Order Traversal

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
    
    For example:
    Given binary tree [3,9,20,null,null,15,7],
        3
       / 
      9  20
        /  
       15   7
    return its level order traversal as:
    [
      [3],
      [9,20],
      [15,7]
    ]

    队列。

    def levelOrder(self, root):
            """
            :type root: TreeNode
            :rtype: List[List[int]]
            """
            res = []
            if not root:
                return res
            queue = []
            queue.append(root)
            while queue:
                size = len(queue)
                cur = []
                for i in xrange(size):
                    root = queue.pop(0)
                    cur.append(root.val)
                    if root.left:
                        queue.append(root.left)
                    if root.right:
                        queue.append(root.right)
                res.append(cur[:])
            return res
    View Code

    103.Binary Tree Zigzag Level Order Traversal

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
    
    For example:
    Given binary tree [3,9,20,null,null,15,7],
        3
       / 
      9  20
        /  
       15   7
    return its zigzag level order traversal as:
    [
      [3],
      [20,9],
      [15,7]
    ]
    

    Z字形遍历。flag记录。队列

    def zigzagLevelOrder(self, root):
            """
            :type root: TreeNode
            :rtype: List[List[int]]
            """
            res = []
            if not root:
                return res
            queue = []
            queue.append(root)
            flag = True
            while queue:
                size = len(queue)
                cur = []
                for i in xrange(size):
                    root = queue.pop(0)
                    if flag:
                        cur.append(root.val)
                    else:
                        cur.insert(0, root.val)
                    if root.left:
                        queue.append(root.left)
                    if  root.right:
                        queue.append(root.right)
                flag = not flag
                res.append(cur[:])
            return res
    View Code

     104.Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth.
    
    The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

    分治。

    def maxDepth(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
            if not root:
                return 0
            return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
    View Code

    105.Construct Binary Tree from Preorder and Inorder Traversal

    Given preorder and inorder traversal of a tree, construct the binary tree.  

    分治。

    def buildTree(self, preorder, inorder):
            """
            :type preorder: List[int]
            :type inorder: List[int]
            :rtype: TreeNode
            """
            if not preorder or not inorder or not len(preorder) == len(inorder):
                return None
            map = {}
            n = len(preorder)
            for i in xrange(n):
                map[inorder[i]] = i    
            return self.help(preorder, inorder, 0, len(preorder) - 1, 0, len(inorder) - 1, map)
        def help(self, preorder, inorder, prestart, preend, instart, inend, map):
            if prestart > preend:
                return None
            if prestart == preend:
                return TreeNode(preorder[prestart])
            root = TreeNode(preorder[prestart])
            index = map[preorder[prestart]]
            root.left = self.help(preorder, inorder, prestart + 1, index - instart + prestart, instart, index - 1, map)
            root.right = self.help(preorder, inorder, index - instart + prestart + 1, preend, index + 1, inend, map)
            return root
    View Code

     106.Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree.  

    分治。

    def buildTree(self, inorder, postorder):
            """
            :type inorder: List[int]
            :type postorder: List[int]
            :rtype: TreeNode
            """
            if not inorder or not postorder:
                return None
            if len(inorder) != len(postorder):
                return None
            map = {}
            n = len(inorder)
            for i in xrange(n):
                map[inorder[i]] = i
            return self.help(inorder, 0, n - 1, postorder, 0, n - 1, map)
        def help(self, inorder, instart, inend, postorder, poststart, postend, map):
            if instart > inend:
                return None
            if instart == inend:
                return TreeNode(inorder[instart])
            root = TreeNode(postorder[postend])
            index = map[postorder[postend]]
            root.left = self.help(inorder, instart, index - 1, postorder, poststart, poststart + index - instart - 1, map)
            root.right = self.help(inorder, index + 1, inend, postorder, poststart + index - instart, postend - 1, map)
            return root
    View Code

    107.Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
    
    For example:
    Given binary tree [3,9,20,null,null,15,7],
        3
       / 
      9  20
        /  
       15   7
    return its bottom-up level order traversal as:
    [
      [15,7],
      [9,20],
      [3]
    ]

    层序遍历。

    def levelOrderBottom(self, root):
            """
            :type root: TreeNode
            :rtype: List[List[int]]
            """
            res = []
            if not root:
                return res
            queue = []
            queue.append(root)
            while queue:
                size = len(queue)
                cur = []
                for i in xrange(size):
                    root = queue.pop(0)
                    cur.append(root.val)
                    if root.left:
                        queue.append(root.left)
                    if root.right:
                        queue.append(root.right)
                res.insert(0, cur[:])
            return res
    View Code

    108.Convert Sorted Array to Binary Search Tree

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST.  

    分治。

    def sortedArrayToBST(self, nums):
            """
            :type nums: List[int]
            :rtype: TreeNode
            """
            if not nums:
                return None
            return self.help(nums, 0, len(nums) - 1)
        def help(self, nums, start, end):
            if start > end:
                return None
            if start == end:
                return TreeNode(nums[start])
            mid = (start + end) / 2
            root = TreeNode(nums[mid])
            root.left = self.help(nums, start, mid - 1)
            root.right = self.help(nums, mid + 1, end)
            return root
    View Code

    109.Convert Sorted List to Binary Search Tree --- not bug free

    Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.  

    首先求出节点个数,start, end控制递归。外部使用temp控制遍历到哪儿了。

    temp = None
        def sortedListToBST(self, head):
            """
            :type head: ListNode
            :rtype: TreeNode
            """
            if not head:
                return None
            global temp
            self.temp = head
            n = 0
            cur = head
            while cur:
                n += 1
                cur = cur.next
            return self.help(0, n - 1)
        def help(self, start, end):
            if start > end:
                return None
            if start == end:
                val = self.temp.val
                self.temp = self.temp.next
                return TreeNode(val)
            mid = (start + end) / 2
            global temp
            left = self.help(start, mid - 1)
            root = TreeNode(self.temp.val)
            self.temp = self.temp.next
            right = self.help(mid + 1, end)
            root.left = left
            root.right = right
            return root
    View Code

     110.Balanced Binary Tree

    Given a binary tree, determine if it is height-balanced.
    
    For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 

    分治。-1 表示不平衡。

    def isBalanced(self, root):
            """
            :type root: TreeNode
            :rtype: bool
            """
            if not root:
                return True
            return not self.height(root) == -1
        def height(self, root):
            if not root:
                return 0
            left = self.height(root.left)
            right = self.height(root.right)
            if left == -1 or right == -1:
                return -1
            if abs(left - right) > 1:
                return -1
            return max(left, right) + 1
    View Code

     111.Minimum Depth of Binary Tree

    Given a binary tree, find its minimum depth.
    
    The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
    

    层序遍历。

    def minDepth(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
            if not root:
                return 0
            queue = []
            queue.append(root)
            res = 1
            while queue:
                size = len(queue)
                for i in xrange(size):
                    cur = queue.pop(0)
                    if not cur.left and not cur.right:
                        return res
                    if cur.left:
                        queue.append(cur.left)
                    if cur.right:
                        queue.append(cur.right)
                res += 1
            return res
    View Code

     112.Path Sum ---not bug free

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
    
    For example:
    Given the below binary tree and sum = 22,
                  5
                 / 
                4   8
               /   / 
              11  13  4
             /        
            7    2      1
    return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.  

    有个坑,不好描述的坑,仔细思考。

    def hasPathSum(self, root, sum):
            """
            :type root: TreeNode
            :type sum: int
            :rtype: bool
            """
            return self.help(root, sum)
        def help(self, root, target):
            if not root:
                return False
            if not root.left and not root.right: 
                if target == root.val:
                    return True
                else:
                    return False
            return self.help(root.left, target - root.val) or self.help(root.right, target - root.val)
    View Code

    113.Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
    
    For example:
    Given the below binary tree and sum = 22,
                  5
                 / 
                4   8
               /   / 
              11  13  4
             /      / 
            7    2  5   1
    return
    [
       [5,4,11,2],
       [5,8,4,5]
    ]
    

     backtracking.注意cur.pop()

    def pathSum(self, root, sum):
            """
            :type root: TreeNode
            :type sum: int
            :rtype: List[List[int]]
            """
            res = []
            self.help(root, sum, res, [])
            return res
        def help(self, root, target, res, cur):
            if not root:
                return
            if not root.left and not root.right:
                if target == root.val:
                    cur.append(root.val)
                    res.append(cur[:])
                    cur.pop()
                return
            else:
                cur.append(root.val)
                self.help(root.left, target - root.val, res, cur)
                self.help(root.right, target - root.val, res ,cur)
                cur.pop()
    View Code

     114.Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place.
    
    For example,
    Given
    
             1
            / 
           2   5
          /    
         3   4   6
    The flattened tree should look like:
       1
        
         2
          
           3
            
             4
              
               5
                
                 6  

    先序遍历。每次节点任务完成后,更新左右节点。注意左二子为None的更新。右儿子为栈顶。

    def flatten(self, root):
            """
            :type root: TreeNode
            :rtype: void Do not return anything, modify root in-place instead.
            """
            if not root:
                return root
            stack = []
            stack.append(root)
            while stack:
                root = stack.pop()
                if root.right:
                    stack.append(root.right)
                if root.left:
                    stack.append(root.left)
                root.left = None # Attention!
                if stack:
                    root.right = stack[-1]
    View Code

    115.Distinct Subsequences --- not bug free

    Given a string S and a string T, count the number of distinct subsequences of T in S.
    
    A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).
    
    Here is an example:
    S = "rabbbit", T = "rabbit"
    
    Return 3.
    

    dp.dp[i][j]表示s前i个字符的字串和t前j个字符的字串,有多少种方案。

    考虑s[i - 1]是否等于t[j - 1],这会影响是否使用s的当前字符s[i - 1].

    def numDistinct(self, s, t):
            """
            :type s: str
            :type t: str
            :rtype: int
            """
            if s == None or t == None:
                return 0
            if len(s) < len(t):
                return 0
            m = len(s)
            n = len(t)
            dp = [[0 for i in xrange(n + 1)] for j in xrange(m + 1)]
            for i in xrange(m + 1):
                dp[i][0] = 1
            for i in xrange(1, m + 1):
                for j in xrange(1, n + 1):
                    if s[i - 1] == t[j - 1]:
                        dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
                    else:
                        dp[i][j] = dp[i - 1][j]
            return dp[m][n]
    View Code

     116.Populating Next Right Pointers in Each Node

     

    Given a binary tree
    
        struct TreeLinkNode {
          TreeLinkNode *left;
          TreeLinkNode *right;
          TreeLinkNode *next;
        }
    Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.
    
    Initially, all next pointers are set to NULL.
    
    Note:
    
    You may only use constant extra space.
    You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
    For example,
    Given the following perfect binary tree,
             1
           /  
          2    3
         /   / 
        4  5  6  7
    After calling your function, the tree should look like:
             1 -> NULL
           /  
          2 -> 3 -> NULL
         /   / 
        4->5->6->7 -> NULL  

    层序遍历。

    def connect(self, root):
            if not root:
                return
            queue = []
            queue.append(root)
            while queue:
                size = len(queue)
                for i in xrange(size):
                    cur = queue.pop(0)
                    cur.next = queue[0] if i != size - 1 else None
                    if cur.left:
                        queue.append(cur.left)
                    if cur.right:
                        queue.append(cur.right)
    View Code

    父亲层处理儿子层的下一节点。也是一层一层的遍历。

     1 def connect(self, root):
     2         if not root:
     3             return
     4         while root.left:
     5             cur = root
     6             while cur:
     7                 cur.left.next = cur.right
     8                 if cur.next:
     9                     cur.right.next = cur.next.left
    10                 cur = cur.next
    11             root = root.left
    View Code

    117.Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node".
    
    What if the given tree could be any binary tree? Would your previous solution still work?
    
    Note:
    
    You may only use constant extra space.
    For example,
    Given the following binary tree,
             1
           /  
          2    3
         /     
        4   5    7
    After calling your function, the tree should look like:
             1 -> NULL
           /  
          2 -> 3 -> NULL
         /     
        4-> 5 -> 7 -> NULL  

    并不是完全二叉树,则上述方法二不适用,层序遍历仍然有效。

    def connect(self, root):
            if not root:
                return
            queue = []
            queue.append(root)
            while queue:
                size = len(queue)
                for i in xrange(size):
                    cur = queue.pop(0)
                    cur.next = queue[0] if i != size - 1 else None
                    if cur.left:
                        queue.append(cur.left)
                    if cur.right:
                        queue.append(cur.right)
    View Code

     118.Pascal's Triangle

    Given numRows, generate the first numRows of Pascal's triangle.
    
    For example, given numRows = 5,
    Return
    
    [
         [1],
        [1,1],
       [1,2,1],
      [1,3,3,1],
     [1,4,6,4,1]
    ]  

    从第二行开始,出去左右两边的,都等于上一行的相加。

    def generate(self, numRows):
            """
            :type numRows: int
            :rtype: List[List[int]]
            """
            res = []
            if numRows < 1:
                return res
            res.append([1])
            for i in xrange(1, numRows):
                cur = [1]
                for j in xrange(i - 1):
                    cur.append(res[i - 1][j] + res[i - 1][j + 1])
                cur.append(1)
                res.append(cur[:])
            return res
    View Code

    119.Pascal's Triangle II

    Given an index k, return the kth row of the Pascal's triangle.
    
    For example, given k = 3,
    Return [1,3,3,1].
    

    res 和 cur,由res求cur,求得cur之后更新res

    def getRow(self, rowIndex):
            """
            :type rowIndex: int
            :rtype: List[int]
            """
            if rowIndex < 0:
                return []
            res = [1]
            for i in xrange(1, rowIndex + 1):
                cur = [1]
                for j in xrange(1, i):
                    cur.append(res[j - 1] + res[j])
                cur.append(1)
                res = cur
            return res
    View Code

     120.Triangle

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
    
    For example, given the following triangle
    [
         [2],
        [3,4],
       [6,5,7],
      [4,1,8,3]
    ]
    The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). 

    自底向上的DP.

    def minimumTotal(self, triangle):
            """
            :type triangle: List[List[int]]
            :rtype: int
            """
            if not triangle:
                return 0
            m = len(triangle)
            dp = [[0 for i in  xrange(m)] for j in xrange(m)]
            for j in xrange(m):
                dp[m - 1][j] = triangle[m - 1][j]
            for i in xrange(m - 2, -1, -1):
                for j in xrange(i + 1):
                    dp[i][j] = min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j]
            return dp[0][0]
    View Code

    121.Best Time to Buy and Sell Stock

    Say you have an array for which the ith element is the price of a given stock on day i.
    
    If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.  

     记录最小值,比最小值小则更新最小值,否则计算收益更新res

    def maxProfit(self, prices):
            """
            :type prices: List[int]
            :rtype: int
            """
            if not prices:
                return 0
            res = 0
            min = prices[0]
            n = len(prices)
            for i in xrange(1, n):
                if prices[i] < min:
                    min = prices[i]
                else:
                    res = max(res, prices[i] - min)
            return res
    View Code

     122.Best Time to Buy and Sell Stock II

    Say you have an array for which the ith element is the price of a given stock on day i.
    
    Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
    

     后一天价格比前一天高就加上差价。

     def maxProfit(self, prices):
            """
            :type prices: List[int]
            :rtype: int
            """
            if not prices:
                return 0
            res = 0
            n = len(prices)
            for i in xrange(1, n):
                if prices[i] > prices[i - 1]:
                    res += prices[i] - prices[i - 1]
            return res
    View Code

    123.Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i.
    Design an algorithm to find the maximum profit. You may complete at most two transactions.
    

     dp.left[i]表示前i个一次交易的最大,right[i]表示后i个一次交易的最大。left[i] + right[i]更新res.

    def maxProfit(self, prices):
            """
            :type prices: List[int]
            :rtype: int
            """
            if not prices:
                return 0
            n = len(prices)
            left = [0] * n
            right = [0] * n
            minNum = prices[0]
            for i in xrange(1, n):
                if prices[i] < minNum:
                    left[i] = left[i - 1]
                    minNum = prices[i]
                else:
                    left[i] = max(left[i - 1], prices[i] - minNum)
            maxNum = prices[n - 1]
            res = left[n - 1]
            for i in xrange(n - 2, -1, -1):
                if prices[i] > maxNum:
                    right[i] = right[i + 1]
                    maxNum = prices[i]
                else:
                    right[i] = max(right[i + 1], maxNum - prices[i])
                res = max(res, left[i] + right[i])
            return res
    View Code

    124.Binary Tree Maximum Path Sum

    Given a binary tree, find the maximum path sum.
    
    For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
    
    For example:
    Given the below binary tree,
    
           1
          / 
         2   3
    Return 6.
    

      递归。注意为None的时候的返回值。

    class Solution(object):
        def maxPathSum(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
            return self.help(root).any2any
        def help(self, root):
            if not root:
                return ResultType(-1 << 32, -1 << 32)
            left = self.help(root.left)
            right = self.help(root.right)
            root2any = max(max(0, left.root2any), max(0, right.root2any)) + root.val
            any2any = max(0, left.root2any) + max(0, right.root2any) + root.val
            any2any = max(any2any, left.any2any, right.any2any)
            return ResultType(root2any, any2any)
    class ResultType(object):
        def __init__(self, root2any, any2any):
            self.root2any = root2any
            self.any2any = any2any
    View Code

    125.Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
    
    For example,
    "A man, a plan, a canal: Panama" is a palindrome.
    "race a car" is not a palindrome.
    

     两个指针。

    def isPalindrome(self, s):
            """
            :type s: str
            :rtype: bool
            """
            if not s:
                return True
            left = 0
            right = len(s) - 1
            while left < right:
                while left < right and not s[left].isalnum():
                    left += 1
                while left < right and not s[right].isalnum():
                    right -= 1
                if s[left].lower() != s[right].lower() :
                    return False
                left += 1
                right -= 1
            return True
    View Code

     126.Word Ladder II --- not bug free

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
    
    Only one letter can be changed at a time
    Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
    For example,
    
    Given:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log","cog"]
    Return
      [
        ["hit","hot","dot","dog","cog"],
        ["hit","hot","lot","log","cog"]
      ]
    Note:
    Return an empty list if there is no such transformation sequence.
    All words have the same length.
    All words contain only lowercase alphabetic characters.
    You may assume no duplicates in the word list.
    You may assume beginWord and endWord are non-empty and are not the same.
    

      这个题花了好长时间才ac。主要原因:1.题目要求和之前的不同了,wordList中必须包含endWord;2.python中字典如果不包含key,去获取key的value的时候是会报错的,而java中不会报错,会得到null。所以java中去获取之后看为不为null返回,python中需要去看包不包含这个key。

    解题思路:

    1.首先是需要获取adjMap.具体做法是去除每一个位置的那个字母得到rep,把相同rep的放到一个list中,然后list中两两互为adj

    2.然后需要获取previousMap,由于需要找所有最短路径,所以需要使用记录具体的distanceMap。使用一个queue实现

    3.然后回溯即可。

    def findLadders(self, beginWord, endWord, wordList):
            """
            :type beginWord: str
            :type endWord: str
            :type wordList: List[str]
            :rtype: List[List[str]]
            """
            if not beginWord or not endWord or not wordList:
                return []
            adjMap = {}
            wordList = set(wordList)
            if endWord not in wordList:
                return []
            wordList.add(beginWord)
            self.getAdjMap(wordList, adjMap, len(beginWord))
            # print adjMap
            previousMap = self.getPreviousMap(adjMap, beginWord, endWord)
            # print previousMap
            res = []
            cur = [endWord]
            self.dfs(previousMap, beginWord, endWord, res, cur)
            return res
        def dfs(self, previousMap, beginWord, endWord, res, cur):
            if beginWord == endWord:
                res.append(cur[:])
                return
            if endWord not in previousMap:
                return
            prevList = previousMap[endWord]
            for prev in prevList:
                cur.insert(0, prev)
                self.dfs(previousMap, beginWord, prev, res, cur)
                cur.pop(0)
        def getPreviousMap(self, adjMap, beginWord, endWord):
            previousMap = {}
            distanceMap = {}
            previousMap[beginWord] = None
            distanceMap[beginWord] = 0
            queue = []
            queue.append(beginWord)
            while queue:
                word = queue.pop(0)
                if word not in  adjMap:
                    continue
                adjList = adjMap[word]
                for adj in adjList:
                    if  adj not in previousMap:
                        previousMap[adj] = [word]
                        distanceMap[adj] = distanceMap[word] + 1
                        queue.append(adj)
                    elif distanceMap[word] + 1 == distanceMap[adj]:
                        previousMap[adj].append(word)
            return previousMap
        
        def getAdjMap(self, wordList, adjMap, n):
            for i in xrange(n):
                repToWord = {}
                for word in wordList:
                    rep = word[0:i] + word[(i + 1) : n]
                    self.update(rep, word, repToWord)
                for rep in repToWord:
                    if len(repToWord[rep]) < 2:
                        continue
                    list = repToWord[rep]
                    for str1 in list:
                        for str2 in list:
                            if str1 != str2:
                                self.update(str1, str2, adjMap)
        def update(self, rep, word, repToWord):
            if not rep in repToWord:
                repToWord[rep] = []
            repToWord[rep].append(word)
    View Code

     127.Word Ladder

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
    
    Only one letter can be changed at a time.
    Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
    For example,
    
    Given:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log","cog"]
    As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
    return its length 5.
    
    Note:
    Return 0 if there is no such transformation sequence.
    All words have the same length.
    All words contain only lowercase alphabetic characters.
    You may assume no duplicates in the word list.
    You may assume beginWord and endWord are non-empty and are not the same.
    

      和上题主要思路一样,只求最短路径,所以只需要找到一条路径即可,不在需要distanceMap,previousMap的value也不再是一个list。

    def ladderLength(self, beginWord, endWord, wordList):
            """
            :type beginWord: str
            :type endWord: str
            :type wordList: List[str]
            :rtype: int
            """
            if not beginWord or not endWord or not wordList:
                return 0
            mset = set(wordList)
            if endWord not in mset:
                return 0
            mset.add(beginWord)
            adjMap = {}
            self.getAdjMap(mset, adjMap, len(beginWord))
            previousMap = self.getPreviousMap(beginWord, endWord, adjMap)
            return self.getLength(beginWord, endWord, previousMap)    
        def getPreviousMap(self, beginWord, endWord, adjMap):
            previousMap = {}
            previousMap[beginWord] = None
            queue = [beginWord]
            while queue:
                word = queue.pop(0)
                if word not in adjMap:
                    continue
                list = adjMap[word]
                for str in list:
                    if str in previousMap:
                        continue
                    previousMap[str] = word
                    queue.append(str)
                    if str == endWord:
                        return previousMap
            return previousMap
        def getLength(self, beginWord, endWord, previousMap):
            length = 0
            while endWord:
                length += 1
                if endWord not in previousMap:
                    return 0
                endWord = previousMap[endWord]
            return length
        def getAdjMap(self, wordList, adjMap, n):
            for i in xrange(n):
                repToWord = {}
                for word in wordList:
                    rep = word[0 : i] + word[(i + 1) : n]
                    self.update(rep, word, repToWord)
                for rep in repToWord.keys():
                    list = repToWord.get(rep)
                    if len(list) < 2:
                        continue
                    for str1 in list:
                        for str2 in list:
                            if str1 != str2:
                                self.update(str1, str2, adjMap)
        def update(self, str1, str2, map):
            if str1 not in map:
                map[str1] = []
            map[str1].append(str2)
    View Code

     128.Longest Consecutive Sequence --- not bug free

    Total Accepted: 100920
    Total Submissions: 278863
    Difficulty: Hard
    Contributor: LeetCode
    Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
    
    For example,
    Given [100, 4, 200, 1, 3, 2],
    The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.
    
    Your algorithm should run in O(n) complexity.
    

      首先当然有一种很直观的想法就是排序之后遍历一边,但是这是O(nlogn)的复杂度,需要O(n)的复杂度的话,使用一个set,首先加入所有的元素,然后遍历原来的数组,对于每个数往两边扩展(如果在set中的话,注意扩展之后需要删除这个元素,以免后边又扩进去了。)

    def longestConsecutive(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            if not nums:
                return 0
            mset = set(nums)
            res = 0
            for num in nums:
                down = num - 1
                while down in mset:
                    mset.remove(down)
                    down -= 1
                up = num + 1
                while up in mset:
                    mset.remove(up)
                    up += 1
                res = max(res, up - down - 1)
            return res
    View Code

    129.Sum Root to Leaf Numbers

    Total Accepted: 108165
    Total Submissions: 300355
    Difficulty: Medium
    Contributor: LeetCode
    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
    
    An example is the root-to-leaf path 1->2->3 which represents the number 123.
    
    Find the total sum of all root-to-leaf numbers.
    
    For example,
    
        1
       / 
      2   3
    The root-to-leaf path 1->2 represents the number 12.
    The root-to-leaf path 1->3 represents the number 13.
    
    Return the sum = 12 + 13 = 25.
    View Code

     分治。

    res = 0
        def sumNumbers(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
            global res
            if not root:
                return 0
            self.help(root, root.val)
            return self.res
        def help(self, root, cur):
            global res
            if not root.left and not root.right:
                self.res += cur
            if root.left:
                self.help(root.left, cur * 10 + root.left.val)
            if root.right:
                self.help(root.right, cur * 10 + root.right.val)
    View Code

     130.Surrounded Regions

    Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.
    
    A region is captured by flipping all 'O's into 'X's in that surrounded region.
    
    For example,
    X X X X
    X O O X
    X X O X
    X O X X
    After running your function, the board should be:
    
    X X X X
    X X X X
    X X X X
    X O X X
    View Code

    DFS。容易stack溢出,加了最后的if 判断

    def solve(self, board):
            """
            :type board: List[List[str]]
            :rtype: void Do not return anything, modify board in-place instead.
            """
            if not board:
                return
            m = len(board)
            n = len(board[0])
            for i in range(m):
                self.dfs(board, i, 0)
                self.dfs(board, i , n - 1)
            for j in range(n):
                self.dfs(board, 0, j)
                self.dfs(board, m - 1, j)
            for i in range(m):
                for j in range(n):
                    if board[i][j] == '1':
                        board[i][j] = 'O'
                    else:
                        board[i][j] = 'X'
        def dfs(self, board, i, j):
            m = len(board)
            n = len(board[0])
            if i < 0 or i >= m or j < 0 or j >= n:
                return
            if board[i][j] != 'O':
                return
            board[i][j] = '1'
            self.dfs(board, i + 1, j)
            self.dfs(board, i - 1, j)
            self.dfs(board, i, j + 1)
            if j > 1:
                self.dfs(board, i, j - 1)    
    View Code

     UnionFind。

    class Solution(object):
        def solve(self, board):
            """
            :type board: List[List[str]]
            :rtype: void Do not return anything, modify board in-place instead.
            """
            if not board:
                return
            m = len(board)
            n = len(board[0])
            uf = UnionFind(m * n + 1)
            dummyNode = m * n
            for j in range(n):
                if board[0][j] == 'O':
                    uf.union(self.node(0, j, n), dummyNode)
                if board[m - 1][j] == 'O':
                    uf.union(self.node(m - 1, j, n), dummyNode)
            for i in range(m):
                if board[i][0] == 'O':
                    uf.union(self.node(i, 0, n), dummyNode)
                if board[i][n - 1] == 'O':
                    uf.union(self.node(i, n - 1, n), dummyNode)
            for i in range(1, m - 1):
                for j in range(1, n - 1):
                    if board[i][j] != 'O':
                        continue
                    if board[i - 1][j] == 'O':
                        uf.union(self.node(i - 1, j, n), self.node(i, j, n))
                    if board[i + 1][j] == 'O':
                        uf.union(self.node(i + 1, j, n), self.node(i, j, n))
                    if board[i][j - 1] == 'O':
                        uf.union(self.node(i, j - 1, n), self.node(i, j, n))
                    if board[i][j + 1] == 'O':
                        uf.union(self.node(i, j + 1, n), self.node(i, j, n))
            for i in range(m):
                for j in range(n):
                    if uf.find(self.node(i, j, n)) == uf.find(dummyNode):
                        board[i][j] = 'O'
                    else:
                        board[i][j] = 'X'
        def node(self, i, j, n):
            return i * n + j;
    class UnionFind(object):
        def __init__(self, n):
            self.count = n
            self.ids = [i for i in range(n)]
            self.sz = [1 for i in range(n)]
        def union(self, p, q):
            i = self.find(p)
            j = self.find(q)
            if i == j:
                return
            elif self.sz[i] < self.sz[j]:
                self.ids[i] = j
                self.sz[j] += self.sz[i]
                self.count -= 1
            else:
                self.ids[j] = i
                self.sz[i] += self.sz[j]
                self.count -= 1
        def find(self, p):
            while self.ids[p] != p:
                self.ids[p] = self.ids[self.ids[p]]
                p = self.ids[p]
            return p
    
        def count(self):
            return self.count
    View Code

     

  • 相关阅读:
    UC将发布高性能HTML5游戏引擎XCanvas
    一台晚会3.15拯救不了这些高科技公司
    4G时代更有利于TDD的发展
    【leetcode】Binary Tree Zigzag Level Order Traversal
    四月电商价格战火重燃 服务为决胜之道
    linux sysfs(3)
    ubuntu gedit 中文显示乱码解决方法
    研究人员将Windows Phone 7和Windows Azure推广到平流层的大气污染研究中
    迁移周系列II/II: On Premises 迁移视频
    玩Rock, Paper, Azure Challenge,赢取免费Kinect和Xbox 360!
  • 原文地址:https://www.cnblogs.com/futurehau/p/6564471.html
Copyright © 2020-2023  润新知