diff --git a/PARTICIPANTS.md b/PARTICIPANTS.md index 5a2e2f4..c1f14c9 100644 --- a/PARTICIPANTS.md +++ b/PARTICIPANTS.md @@ -141,4 +141,15 @@ - šŸ“« Reach me: **rajpiyush100@gmail.com** - šŸ”­ Connect with me: **[Piyushjar](https://github.com/piyushjar))** +--- + + ### Connect with me: + + Vaishnvee Shinde + +- šŸ‘Øā€šŸ’» My name is **Vaishnvee Shinde** +- 🌱 I’m a Full Stack Developer Developer. +- šŸ“« Reach me: **vaishnvee.s.shinde@gmail.com** +- šŸ”­ Connect with me: **[Piyushjar](https://github.com/Vaishnvee-Shinde))** + --- diff --git a/python/101_Symmetric_Tree.py b/python/101_Symmetric_Tree.py new file mode 100644 index 0000000..8c4b1f4 --- /dev/null +++ b/python/101_Symmetric_Tree.py @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSymmetric(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + if root is None: + return True + return self.mirrorVisit(root.left, root.right) + + def mirrorVisit(self, left, right): + if left is None and right is None: + return True + try: + if left.val == right.val: + if self.mirrorVisit(left.left, right.right) and self.mirrorVisit(left.right, right.left): + return True + return False + except: + return False \ No newline at end of file diff --git a/python/python/001_Two_Sum.py b/python/python/001_Two_Sum.py new file mode 100644 index 0000000..e4bd58a --- /dev/null +++ b/python/python/001_Two_Sum.py @@ -0,0 +1,66 @@ +class Solution(object): + # def twoSum(self, nums, target): + # """ + # :type nums: List[int] + # :type target: int + # :rtype: List[int] + # """ + # #n^2 + # ls = len(nums) + # for i in range(ls): + # for j in range(i + 1, ls): + # if nums[i] + nums[j] == target: + # return [i, j] + + # def twoSum(self, nums, target): + # # hash 1 + # hash_nums = {} + # for index, num in enumerate(nums): + # try: + # hash_nums[num].append(index) + # except KeyError: + # hash_nums[num] = [index] + # for index, num in enumerate(nums): + # another = target - num + # try: + # candicate = hash_nums[another] + # if another == num: + # if len(candicate) > 1: + # return candicate + # else: + # continue + # else: + # return [index, candicate[0]] + # except KeyError: + # pass + + # def twoSum(self, nums, target): + # # hash 2 + # hash_nums = {} + # for index, num in enumerate(nums): + # another = target - num + # try: + # hash_nums[another] + # return [hash_nums[another], index] + # except KeyError: + # hash_nums[num] = index + + def twoSum(self, nums, target): + # two point + nums_index = [(v, index) for index, v in enumerate(nums)] + nums_index.sort() + begin, end = 0, len(nums) - 1 + while begin < end: + curr = nums_index[begin][0] + nums_index[end][0] + if curr == target: + return [nums_index[begin][1], nums_index[end][1]] + elif curr < target: + begin += 1 + else: + end -= 1 + + +if __name__ == '__main__': + # begin + s = Solution() + print s.twoSum([3, 2, 4], 6) diff --git a/python/python/002_Add_Two_Numbers.py b/python/python/002_Add_Two_Numbers.py new file mode 100644 index 0000000..0e91587 --- /dev/null +++ b/python/python/002_Add_Two_Numbers.py @@ -0,0 +1,57 @@ +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + + +class Solution(object): + # def addTwoNumbers(self, l1, l2): + # """ + # :type l1: ListNode + # :type l2: ListNode + # :rtype: ListNode + # """ + # last = 0 + # head = prev = None + # while True: + # if l2 is None and l1 is None and last == 0: + # break + # val = last + # if l2 is not None: + # val += l2.val + # l2 = l2.next + # if l1 is not None: + # val += l1.val + # l1 = l1.next + # if val >= 10: + # val = val % 10 + # last = 1 + # else: + # last = 0 + # current = ListNode(val) + # if prev is None: + # head = current + # else: + # prev.next = current + # prev = current + # return head + + def addTwoNumbers(self, l1, l2): + carry = 0 + # dummy head + head = curr = ListNode(0) + while l1 or l2: + val = carry + if l1: + val += l1.val + l1 = l1.next + if l2: + val += l2.val + l2 = l2.next + curr.next = ListNode(val % 10) + curr = curr.next + carry = int(val / 10) + if carry > 0: + curr.next = ListNode(carry) + return head.next diff --git a/python/python/003_Longest_Substring_Without_Repeating_Characters.py b/python/python/003_Longest_Substring_Without_Repeating_Characters.py new file mode 100644 index 0000000..e6977c5 --- /dev/null +++ b/python/python/003_Longest_Substring_Without_Repeating_Characters.py @@ -0,0 +1,71 @@ +class Solution(object): + # def lengthOfLongestSubstring(self, s): + # """ + # :type s: str + # :rtype: int + # """ + # sls = len(set(s)) + # ls = len(s) + # if ls >= 1: + # max_l = 1 + # else: + # return 0 + # for i in range(ls): + # for j in range(i + max_l + 1, i + sls + 1): + # curr = s[i:j] + # c_ls = len(curr) + # if len(set(curr)) != c_ls: + # break + # else: + # if c_ls > max_l: + # max_l = c_ls + # if max_l == sls: + # return sls + # return max_l + + # def lengthOfLongestSubstring(self, s): + # sls = len(set(s)) + # ls = len(s) + # if ls >= 1: + # max_l = 1 + # else: + # return 0 + # for i in range(ls): + # for j in reversed(range(i + max_l + 1, i + sls + 1)): + # curr = s[i:j] + # c_ls = len(curr) + # if len(set(curr)) == c_ls: + # if c_ls > max_l: + # max_l = c_ls + # if max_l == sls: + # return sls + # break + # return max_l + + # def lengthOfLongestSubstring(self, s): + # exist = [False] * 256 + # ls = len(s) + # max_len = i = 0 + # for j in range(ls): + # while(exist[ord(s[j])]): + # exist[ord(s[i])] = False + # i += 1 + # exist[ord(s[j)] = True + # max_len = max(max_len, j - i + 1) + # return max_len + + def lengthOfLongestSubstring(self, s): + # https://leetcode.com/articles/longest-substring-without-repeating-characters/ + charMap = {} + for i in range(256): + charMap[i] = -1 + ls = len(s) + i = max_len = 0 + for j in range(ls): + # Note that when charMap[ord(s[j])] >= i, it means that there are + # duplicate character in current i,j. So we need to update i. + if charMap[ord(s[j])] >= i: + i = charMap[ord(s[j])] + 1 + charMap[ord(s[j])] = j + max_len = max(max_len, j - i + 1) + return max_len diff --git a/python/python/004_Median_of_Two_Sorted_Arrays.py b/python/python/004_Median_of_Two_Sorted_Arrays.py new file mode 100644 index 0000000..ef7de82 --- /dev/null +++ b/python/python/004_Median_of_Two_Sorted_Arrays.py @@ -0,0 +1,60 @@ +class Solution(object): + # def findMedianSortedArrays(self, nums1, nums2): + # """ + # :type nums1: List[int] + # :type nums2: List[int] + # :rtype: float + # """ + # p1 = p2 = 0 + # ls1 = len(nums1) + # ls2 = len(nums2) + # all_nums = [] + # median = 0.0 + # while p1 < ls1 and p2 < ls2: + # if nums1[p1] < nums2[p2]: + # all_nums.append(nums1[p1]) + # p1 += 1 + # else: + # all_nums.append(nums2[p2]) + # p2 += 1 + # if p1 < ls1: + # while p1 < ls1: + # all_nums.append(nums1[p1]) + # p1 += 1 + # if p2 < ls2: + # while p2 < ls2: + # all_nums.append(nums2[p2]) + # p2 += 1 + # # print all_nums + # if (ls1 + ls2) % 2 == 1: + # median = all_nums[(ls1 + ls2) / 2] + # else: + # median = 1.0 * (all_nums[(ls1 + ls2) / 2] + all_nums[(ls1 + ls2) / 2 - 1]) / 2 + # return median + + def findMedianSortedArrays(self, nums1, nums2): + # https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation + # https://discuss.leetcode.com/topic/16797/very-concise-o-log-min-m-n-iterative-solution-with-detailed-explanation + ls1, ls2 = len(nums1), len(nums2) + if ls1 < ls2: + return self.findMedianSortedArrays(nums2, nums1) + l, r = 0, ls2 * 2 + while l <= r: + mid2 = (l + r) >> 1 + mid1 = ls1 + ls2 - mid2 + L1 = -sys.maxint - 1 if mid1 == 0 else nums1[(mid1 - 1) >> 1] + L2 = -sys.maxint - 1 if mid2 == 0 else nums2[(mid2 - 1) >> 1] + R1 = sys.maxint if mid1 == 2 * ls1 else nums1[mid1 >> 1] + R2 = sys.maxint if mid2 == 2 * ls2 else nums2[mid2 >> 1] + if L1 > R2: + l = mid2 + 1 + elif L2 > R1: + r = mid2 - 1 + else: + return (max(L1, L2) + min(R1, R2)) / 2.0 + + +if __name__ == '__main__': + # begin + s = Solution() + print s.findMedianSortedArrays([1, 1], [1, 2]) diff --git a/python/python/005_Longest_Palindromic_Substring.py b/python/python/005_Longest_Palindromic_Substring.py new file mode 100644 index 0000000..5086547 --- /dev/null +++ b/python/python/005_Longest_Palindromic_Substring.py @@ -0,0 +1,88 @@ +class Solution(object): + def longestPalindrome(self, s): + """ + :type s: str + :rtype: str + """ + # my solution + # expand string according to Manacher algorithm + # but extend radius step by step + ls = len(s) + if ls <= 1 or len(set(s)) == 1: + return s + # create a new list like this: "abc"->"a#b#c" + temp_s = '#'.join('{}'.format(s)) + # print temp_s + tls = len(temp_s) + seed = range(1, tls - 1) + # this table stores the max length palindrome + len_table = [0] * tls + for step in range(1, tls / 2 + 1): + final = [] + for pos in seed: + if pos - step < 0 or pos + step >= tls: + continue + if temp_s[pos - step] != temp_s[pos + step]: + continue + final.append(pos) + if temp_s[pos - step] == '#': + continue + len_table[pos] = step + seed = final + max_pos, max_step = 0, 0 + for i, s in enumerate(len_table): + if s >= max_step: + max_step = s + max_pos = i + return temp_s[max_pos - max_step:max_pos + max_step + 1].translate(None, '#') + + # def longestPalindrome(self, s): + # # example in leetcode book + # max_left, max_right = 0, 0 + # ls = len(s) + # for i in range(ls): + # len1 = self.expandAroundCenter(s, i, i) + # len2 = self.expandAroundCenter(s, i, i + 1) + # max_len = max(len1, len2) + # if (max_len > max_right - max_left): + # max_left = i - (max_len - 1) / 2 + # max_right = i + max_len / 2 + # return s[max_left:max_right + 1] + # + # def expandAroundCenter(self, s, left, right): + # ls = len(s) + # while (left >= 0 and right < ls and s[left] == s[right]): + # left -= 1 + # right += 1 + # return right - left - 1 + + # def longestPalindrome(self, s): + # #Manacher algorithm + # #http://en.wikipedia.org/wiki/Longest_palindromic_substring + # # Transform S into T. + # # For example, S = "abba", T = "^#a#b#b#a#$". + # # ^ and $ signs are sentinels appended to each end to avoid bounds checking + # T = '#'.join('^{}$'.format(s)) + # n = len(T) + # P = [0] * n + # C = R = 0 + # for i in range (1, n-1): + # P[i] = (R > i) and min(R - i, P[2*C - i]) # equals to i' = C - (i-C) + # # Attempt to expand palindrome centered at i + # while T[i + 1 + P[i]] == T[i - 1 - P[i]]: + # P[i] += 1 + # + # # If palindrome centered at i expand past R, + # # adjust center based on expanded palindrome. + # if i + P[i] > R: + # C, R = i, i + P[i] + # + # # Find the maximum element in P. + # maxLen, centerIndex = max((n, i) for i, n in enumerate(P)) + # return s[(centerIndex - maxLen)//2: (centerIndex + maxLen)//2] + + +if __name__ == '__main__': + # begin + s = Solution() + print(s.longestPalindrome("abcbe")) diff --git a/python/python/006_ZigZag_Conversion.py b/python/python/006_ZigZag_Conversion.py new file mode 100644 index 0000000..ae3c418 --- /dev/null +++ b/python/python/006_ZigZag_Conversion.py @@ -0,0 +1,53 @@ +class Solution(object): + # def convert(self, s, numRows): + # """ + # :type s: str + # :type numRows: int + # :rtype: str + # """ + # ls = len(s) + # if ls <= 1 or numRows == 1: + # return s + # temp_s = [] + # for i in range(numRows): + # temp_s.append(['']*(ls / 2)) + # inter = numRows - 1 + # col, row = 0, 0 + # for i, ch in enumerate(s): + # flag = True + # if (i / inter) % 2 == 1: + # # print i + # flag = False + # if flag: + # temp_s[row][col] = ch + # row += 1 + # else: + # temp_s[row][col] = ch + # col += 1 + # row -= 1 + # result = '' + # for i in range(numRows): + # result += ''.join(temp_s[i]) + # return result + + def convert(self, s, numRows): + # https://leetcode.com/discuss/90908/easy-python-o-n-solution-94%25-with-explanations + if numRows == 1: + return s + # calculate period + p = 2 * (numRows - 1) + result = [""] * numRows + for i in xrange(len(s)): + floor = i % p + if floor >= p//2: + floor = p - floor + result[floor] += s[i] + return "".join(result) + + +if __name__ == '__main__': + # begin + s = Solution() + print s.convert("PAYPALISHIRING", 3) + + diff --git a/python/python/007_Reverse_Integer.py b/python/python/007_Reverse_Integer.py new file mode 100644 index 0000000..a125d47 --- /dev/null +++ b/python/python/007_Reverse_Integer.py @@ -0,0 +1,39 @@ +class Solution: + # @return an integer + + # def reverse(self, x): + # max_int = 2147483647 + # if x == 0: + # return 0 + # isPos = True + # if x < 0: + # x *= (-1) + # isPos = False + # ltemp = [] + # while x != 0: + # temp = x % 10 + # ltemp.append(temp) + # x /= 10 + # result = 0 + # # the main solution + # for t in ltemp: + # result = result * 10 + t + # if result > max_int: + # result = 0 + # if isPos: + # return result + # else: + # return -1 * result + + def reverse(self, x): + # Note that in Python -1 / 10 = -1 + res, isPos = 0, 1 + if x < 0: + isPos = -1 + x = -1 * x + while x != 0: + res = res * 10 + x % 10 + if res > 2147483647: + return 0 + x /= 10 + return res * isPos \ No newline at end of file diff --git a/python/python/008_String_to_Integer(atoi).py b/python/python/008_String_to_Integer(atoi).py new file mode 100644 index 0000000..ac167ad --- /dev/null +++ b/python/python/008_String_to_Integer(atoi).py @@ -0,0 +1,43 @@ +class Solution(object): + def myAtoi(self, str): + """ + :type str: str + :rtype: int + """ + sign = 1 + max_int, min_int = 2147483647, -2147483648 + result, pos = 0, 0 + ls = len(str) + while pos < ls and str[pos] == ' ': + pos += 1 + if pos < ls and str[pos] == '-': + sign = -1 + pos += 1 + elif pos < ls and str[pos] == '+': + pos += 1 + while pos < ls and ord(str[pos]) >= ord('0') and ord(str[pos]) <= ord('9'): + num = ord(str[pos]) - ord('0') + if result > max_int / 10 or ( result == max_int / 10 and num >= 8): + if sign == -1: + return min_int + return max_int + result = result * 10 + num + pos += 1 + return sign * result + + # def myAtoi(self, s): + # #https://leetcode.com/discuss/83626/line-python-solution-eafp-instead-lbyl-easier-logic-beats-24%25 + # try: + # s = s.lstrip() + '$' # remove leading spaces and append an end mark + # for i, ch in enumerate(s): + # if not (ch in '+-' or '0' <= ch <= '9'): + # result = int(s[:i]) + # return -2 ** 31 if result < -2 ** 31 else 2 ** 31 - 1 if result > 2 ** 31 - 1 else result + # except: + # return 0 + + +if __name__ == '__main__': + # begin + s = Solution() + print s.myAtoi("+-2") \ No newline at end of file diff --git a/python/python/009_Palindrome_Number.py b/python/python/009_Palindrome_Number.py new file mode 100644 index 0000000..8dc7ce5 --- /dev/null +++ b/python/python/009_Palindrome_Number.py @@ -0,0 +1,67 @@ +# class Solution(object): +# def isPalindrome(self, x): +# """ +# :type x: int +# :rtype: bool +# """ + +class Solution(object): + def isPalindrome(self, x: int) -> bool: + x = str(x) + if (x == x[::-1]): + return True + return False + + + # def isPalindrome(self, x): + # if x < 0: + # return False + # ls = len(str(x)) + # tmp = x + # for i in range(int(ls/2)): + # right = int(tmp % 10) + # left = tmp / (10 ** (ls - 2 * i - 1)) + # left = int(left % 10) + # if left != right: + # return False + # tmp = tmp // 10 + # return True + + + # def isPalindrome(self, x): + # #leetcode book + # if x < 0: + # return False + # div = 1 + # while x / div >= 10: + # div *= 10 + # while x != 0: + # left = x / div + # right = x % 10 + # if left != right: + # return False + # x = (x % div) / 10 + # div /= 100 + # return True + + + # def isPalindrome(self, x): + # # reverse number + # if x < 0: + # return False + # rev_x = 0 + # temp = x + # while temp != 0: + # curr = temp % 10 + # rev_x = rev_x * 10 + curr + # temp = temp // 10 + # if rev_x == x: + # return True + # else: + # return False + + +if __name__ == '__main__': + # begin + s = Solution() + print s.isPalindrome(1001) diff --git a/python/python/010_Regular_Expression_Matching.py b/python/python/010_Regular_Expression_Matching.py new file mode 100644 index 0000000..8a708a9 --- /dev/null +++ b/python/python/010_Regular_Expression_Matching.py @@ -0,0 +1,36 @@ +class Solution(object): + def isMatch(self, s, p): + """ + :type s: str + :type p: str + :rtype: bool + """ + # bottom up o(m*n) + # https://leetcode.com/discuss/93024/easy-dp-java-solution-with-detailed-explanation + if s == p: + return True + m, n = len(s), len(p) + dp = [[False] * (n + 1) for _ in range(m + 1)] + dp[0][0] = True + for j in range(1, n): + if p[j] == '*' and dp[0][j - 1]: + dp[0][j + 1] = True + # print dp + for i in range(m): + for j in range(n): + if p[j] == '.' or p[j] == s[i]: + dp[i + 1][j + 1] = dp[i][j] + elif p[j] == '*': + if p[j - 1] != s[i] and p[j - 1] != '.': + dp[i + 1][j + 1] = dp[i + 1][j - 1] + else: + dp[i + 1][j + 1] = dp[i + 1][j] or dp[i][j + 1] or dp[i + 1][j - 1] + return dp[m][n] + + +if __name__ == '__main__': + # begin + s = Solution() + print s.isMatch("", ".*") + + diff --git a/python/python/011_Container_With_Most_Water.py b/python/python/011_Container_With_Most_Water.py new file mode 100644 index 0000000..e49e40a --- /dev/null +++ b/python/python/011_Container_With_Most_Water.py @@ -0,0 +1,14 @@ +class Solution: + def maxArea(self, height: List[int]) -> int: + # Two points + left, right = 0, len(height) - 1 + result = 0 + while left < right: + result = max(min(height[left], height[right]) * (right - left), result) + if height[left] > height[right]: + # remove right + right -= 1 + else: + # remove left + left += 1 + return result diff --git a/python/python/012_Integer_to_Roman.py b/python/python/012_Integer_to_Roman.py new file mode 100644 index 0000000..5181c73 --- /dev/null +++ b/python/python/012_Integer_to_Roman.py @@ -0,0 +1,47 @@ +# class Solution(object): +# def intToRoman(self, num: int) -> str: +# """ +# :type num: int +# :rtype: str +# """ +# +class Solution(object): + # def intToRoman(self, num: int) -> str: + ## http://www.rapidtables.com/convert/number/how-number-to-roman-numerals.htm + # roman_dim = [[1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'], + # [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'], [10, 'X'], + # [9,'IX'], [5, 'V'], [4, 'IV'], [1, 'I']] + # if num == 0: + # return '' + # roman_str = '' + # current, dim = num, 0 + # while current != 0: + # while current // roman_dim[dim][0] == 0: + # dim += 1 + # while current - roman_dim[dim][0] >= 0: + # current -= roman_dim[dim][0] + # roman_str += roman_dim[dim][1] + # return roman_str + + def intToRoman(self, num: int) -> str: + values = [1000, 900, 500, 400, + 100, 90, 50, 40, + 10, 9, 5, 4, 1] + symbols = ["M", "CM", "D", "CD", + "C", "XC", "L", "XL", + "X", "IX", "V", "IV", + "I"] + roman = '' + i = 0 + while num > 0: + k = num // values[i] + for j in range(k): + roman += symbols[i] + num -= values[i] + i += 1 + return roman + +if __name__ == '__main__': + # begin + s = Solution() + print s.intToRoman(90) \ No newline at end of file diff --git a/python/python/013_Roman_to_Integer.py b/python/python/013_Roman_to_Integer.py new file mode 100644 index 0000000..f73fc74 --- /dev/null +++ b/python/python/013_Roman_to_Integer.py @@ -0,0 +1,35 @@ +class Solution: + # def romanToInt(self, s): + # """ + # :type s: str + # :rtype: int + # """ + # roman = {'I': 1, 'V': 5, 'X': 10, + # 'L': 50, 'C': 100, 'D': 500, 'M': 1000} + # result = 0 + # last = s[-1] + # for t in reversed(s): + # if t == 'C' and last in ['D', 'M']: + # result -= roman[t] + # elif t == 'X' and last in ['L', 'C']: + # result -= roman[t] + # elif t == 'I' and last in ['V', 'X']: + # result -= roman[t] + # else: + # result += roman[t] + # last = t + # return result + + def romanToInt(self, s): + roman = {'I': 1, 'V': 5, 'X': 10, + 'L': 50, 'C': 100, 'D': 500, 'M': 1000} + prev, total = 0, 0 + for c in s: + curr = roman[c] + total += curr + # need to subtract + if curr > prev: + total -= 2 * prev + prev = curr + return total + diff --git a/python/python/014_Longest_Common_Prefix.py b/python/python/014_Longest_Common_Prefix.py new file mode 100644 index 0000000..600e663 --- /dev/null +++ b/python/python/014_Longest_Common_Prefix.py @@ -0,0 +1,44 @@ +# class Solution(object): +# def longestCommonPrefix(self, strs): +# """ +# :type strs: List[str] +# :rtype: str +# """ + +class Solution(object): + def longestCommonPrefix(self, strs): + ls = len(strs) + if ls == 1: + return strs[0] + prefix = '' + pos = 0 + while True: + try: + current = strs[0][pos] + except IndexError: + break + index = 1 + while index < ls: + try: + if strs[index][pos] != current: + break + except IndexError: + break + index += 1 + if index == ls: + prefix = prefix + current + else: + break + pos += 1 + return prefix + + # def longestCommonPrefix(self, strs): + # # https://leetcode.com/discuss/89987/one-line-solution-using-itertools-takewhile + # return reduce(lambda s1, s2: ''.join(y[0] for y in itertools.takewhile(lambda x: x[0] == x[1], zip(s1, s2))), strs or ['']) + + + +if __name__ == '__main__': + # begin + s = Solution() + print s.longestCommonPrefix(["aca","cba"]) \ No newline at end of file diff --git a/python/python/015_3Sum.py b/python/python/015_3Sum.py new file mode 100644 index 0000000..0d9914a --- /dev/null +++ b/python/python/015_3Sum.py @@ -0,0 +1,76 @@ + +class Solution(object): + # def threeSum(self, nums): + # # skip duplicate + # # O(n^3) + # if len(nums) < 3: + # return [] + # nums.sort() + # ls = len(nums) + # result = [] + # for i in range(0, ls - 2): + # if nums[i] > 0: + # break + # if i > 0 and nums[i] == nums[i - 1]: + # continue + # j = i + 1 + # k = ls - 1 + # while(j < k): + # temp = [nums[i], nums[j], nums[k]] + # s = sum(temp) + # jtemp = nums[j] + # ktemp = nums[k] + # if s <= 0: + # j += 1 + # while(j < k and jtemp == nums[j]): + # j += 1 + # if s == 0: + # result.append(temp) + # else: + # k -= 1 + # while(j < k and ktemp == nums[k]): + # k -= 1 + # return result + # def threeSum(self, nums): + # """ + # :type nums: List[int] + # :rtype: List[List[int]] + # """ + # # using multiple 2 sum + # nums.sort() + # result, visited = set(), {} + # for i in xrange(len(nums) - 2): + # table, target = {}, -nums[i] + # if nums[i] not in visited: + # for j in xrange(i + 1, len(nums)): + # if nums[j] not in table: + # table[target - nums[j]] = j + # else: + # result.add((nums[i], target - nums[j], nums[j])) + # visited[nums[i]] = 1 + # return list(result) + + def threeSum(self, nums): + res = [] + nums.sort() + ls = len(nums) + for i in range(ls - 2): + if i > 0 and nums[i] == nums[i - 1]: + continue + j = i + 1 + k = ls - 1 + while j < k: + curr = nums[i] + nums[j] + nums[k] + if curr == 0: + res.append([nums[i], nums[j], nums[k]]) + while j < k and nums[j] == nums[j + 1]: + j += 1 + while j < k and nums[k] == nums[k - 1]: + k -= 1 + j += 1 + k -= 1 + elif curr < 0: + j += 1 + else: + k -= 1 + return res diff --git a/python/python/016_3Sum_Closest.py b/python/python/016_3Sum_Closest.py new file mode 100644 index 0000000..dcae265 --- /dev/null +++ b/python/python/016_3Sum_Closest.py @@ -0,0 +1,25 @@ +# class Solution(object): +# def threeSumClosest(self, nums, target): +# """ +# :type nums: List[int] +# :type target: int +# :rtype: int +# """ +class Solution(object): + def threeSumClosest(self, nums, target): + ls = len(nums) + sort_nums = sorted(nums) + res = nums[0] + nums[1] + nums[2] + for i in range(ls - 2): + j, k = i + 1, ls - 1 + while j < k: + temp = sort_nums[i] + sort_nums[j] + sort_nums[k] + if abs(target - temp) < abs(target - res): + res = temp + if temp < target: + j += 1 + else: + k -= 1 + return res + + diff --git a/python/python/017_Letter_Combinations_of_a_Phone_Number.py b/python/python/017_Letter_Combinations_of_a_Phone_Number.py new file mode 100644 index 0000000..4a43033 --- /dev/null +++ b/python/python/017_Letter_Combinations_of_a_Phone_Number.py @@ -0,0 +1,36 @@ +# class Solution(object): +# def letterCombinations(self, digits): +# """ +# :type digits: str +# :rtype: List[str] +# """ +dmap = {'2': 'abc', + '3': 'def', + '4': 'ghi', + '5': 'jkl', + '6': 'mno', + '7': 'pqrs', + '8': 'tuv', + '9': 'wxyz', + '0': ' ', + None: None} + +class Solution(object): + def letterCombinations(self, digits): + # DFS + result = [] + ls = len(digits) + if ls == 0: + return result + current = digits[0] + posfix = self.letterCombinations(digits[1:]) + for t in dmap[current]: + if len(posfix) > 0: + for p in posfix: + temp = t + p + result.append(temp) + else: + result.append(t) + return result + + diff --git a/python/python/018_4Sum.py b/python/python/018_4Sum.py new file mode 100644 index 0000000..adbd653 --- /dev/null +++ b/python/python/018_4Sum.py @@ -0,0 +1,61 @@ +# class Solution(object): +# def fourSum(self, nums, target): +# """ +# :type nums: List[int] +# :type target: int +# :rtype: List[List[int]] +# """ + + +class Solution(object): + def fourSum(self, nums, target): + sort_nums = sorted(nums) + ls = len(nums) + res = {} + pairs = {} + for i in range(ls - 3): + for j in range(i + 1, ls - 2): + res_2 = sort_nums[i] + sort_nums[j] + try: + pairs[target - res_2].append([i, j]) + except KeyError: + pairs[target - res_2] = [[i, j]] + for key, temp in pairs.items(): + for pair in temp: + j = pair[1] + 1 + k = ls - 1 + while j < k: + current = sort_nums[j] + sort_nums[k] + if current == key: + result = (sort_nums[pair[0]], sort_nums[pair[1]], sort_nums[j], sort_nums[k]) + res[result] = True + j += 1 + elif current < key: + j += 1 + else: + k -= 1 + return res.keys() + + # def fourSum(self, nums, target): + # # https://leetcode.com/discuss/89989/why-is-python-o-n-3-tle + # index_pairs = dict() + # combos = dict() + # n = len(nums) + # for i in range(0,n): + # for j in range(i+1,n): + # sum = nums[i] + nums[j] + # if index_pairs.get(target - sum) is not None: + # for pair in index_pairs[target - sum]: + # if i != pair[0] and i != pair[1] and j != pair[0] and j != pair[1]: # Avoid overuse + # combo = sorted((nums[i], nums[j], nums[pair[0]], nums[pair[1]])) # Avoid duplicate + # combos[tuple(combo)] = True + # if index_pairs.get(sum) is not None: + # index_pairs[sum].append((i,j)) + # else: + # index_pairs[sum] = [(i,j)] + # return combos.keys() + +if __name__ == '__main__': + # begin + s = Solution() + print s.fourSum([0, 0, 0, 0], 0) \ No newline at end of file diff --git a/python/python/019_Remove_Nth_Node_From_End_of_List.py b/python/python/019_Remove_Nth_Node_From_End_of_List.py new file mode 100644 index 0000000..cfd327c --- /dev/null +++ b/python/python/019_Remove_Nth_Node_From_End_of_List.py @@ -0,0 +1,60 @@ +# Given a linked list, remove the n-th node from the end of list and return its head. +# +# 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. +# +# Note: +# Given n will always be valid. +# +# Follow up: +# Could you do this in one pass? + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +# class Solution(object): +# def removeNthFromEnd(self, head, n): +# """ +# :type head: ListNode +# :type n: int +# :rtype: ListNode +# """ +class Solution(object): + # def removeNthFromEnd(self, head, n): + # # with O(n) space + # index = [] + # pos = head + # while pos is not None: + # index.append(pos) + # pos = pos.next + # ls = len(index) + # if n == ls: + # if ls > 1: + # return index[1] + # else: + # return None + # else: + # index_pos = ls - n - 1 + # index[index_pos].next = index[index_pos + 1].next + # return head + + def removeNthFromEnd(self, head, n): + # https://leetcode.com/discuss/86721/o-n-solution-in-java + if head is None: + return None + slow = fast = head + for i in range(n): + fast = fast.next + if fast is None: + head = head.next + return head + while fast.next is not None: + fast = fast.next + slow = slow.next + curr = slow.next + slow.next = curr.next + return head diff --git a/python/python/020_Valid_Parentheses.py b/python/python/020_Valid_Parentheses.py new file mode 100644 index 0000000..a9e65bf --- /dev/null +++ b/python/python/020_Valid_Parentheses.py @@ -0,0 +1,59 @@ +# class Solution(object): +# def isValid(self, s): + +# +class Solution: + def isValid(self, s): + """ + :type s: str + :rtype: bool + """ + if s is None: + return True + stack = [] + for t in s: + if t == ')': + try: + current = stack.pop() + if current != '(': + return False + except: + return False + elif t == '}': + try: + current = stack.pop() + if current != '{': + return False + except: + return False + elif t == ']': + try: + current = stack.pop() + if current != '[': + return False + except: + return False + else: + stack.append(t) + if len(stack) == 0: + return True + else: + return False + + + # def isValid(self, s): + # # python replace + # n = len(s) + # if n == 0: + # return True + # + # if n % 2 != 0: + # return False + # + # while '()' in s or '{}' in s or '[]' in s: + # s = s.replace('{}', '').replace('()', '').replace('[]', '') + # + # if s == '': + # return True + # else: + # return False diff --git a/python/python/021_Merge_Two_Sorted_Lists.py b/python/python/021_Merge_Two_Sorted_Lists.py new file mode 100644 index 0000000..a084914 --- /dev/null +++ b/python/python/021_Merge_Two_Sorted_Lists.py @@ -0,0 +1,47 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +# class Solution(object): +# def mergeTwoLists(self, l1, l2): +# """ +# :type l1: ListNode +# :type l2: ListNode +# :rtype: ListNode +# """ +class Solution(object): + def mergeTwoLists(self, l1, l2): + # dummy head + pos = dummyHead = ListNode(-1) + while l1 is not None and l2 is not None: + if l1.val <= l2.val: + pos.next = l1 + l1 = l1.next + else: + pos.next = l2 + l2 = l2.next + pos = pos.next + # merge residual l1 + if l1 is not None: + pos.next = l1 + # merge residual l2 + if l2 is not None: + pos.next = l2 + return dummyHead.next + + + # def mergeTwoLists(self, l1, l2): + # # recursive + # if l1 is None: + # return l2 + # elif l2 is None: + # return l1 + # if l1.val <= l2.val: + # l1.next = self.mergeTwoLists(l1.next, l2) + # return l1 + # else: + # l2.next = self.mergeTwoLists(l1, l2.next) + # return l2 + diff --git a/python/python/022_Generate_Parentheses.py b/python/python/022_Generate_Parentheses.py new file mode 100644 index 0000000..ed907dc --- /dev/null +++ b/python/python/022_Generate_Parentheses.py @@ -0,0 +1,33 @@ +# class Solution(object): +# def generateParenthesis(self, n): +# """ +# :type n: int +# :rtype: List[str] +# """ +class Solution(object): + def generateParenthesis(self, n): + if n == 1: + return ['()'] + last_list = self.generateParenthesis(n - 1) + res = [] + for t in last_list: + curr = t + ')' + for index in range(len(curr)): + if curr[index] == ')': + res.append(curr[:index] + '(' + curr[index:]) + return list(set(res)) + + + # def generateParenthesis(self, n): + # def generate(leftnum, rightnum, s, result): + # if leftnum == 0 and rightnum == 0: + # result.append(s) + # if leftnum > 0: + # generate(leftnum - 1, rightnum, s + '(', result) + # if rightnum > 0 and leftnum < rightnum: + # generate(leftnum, rightnum - 1, s + ')', result) + # + # result = [] + # s = '' + # generate(n, n, s, result) + # return result diff --git a/python/python/023_Merge_k_Sorted_Lists.py b/python/python/023_Merge_k_Sorted_Lists.py new file mode 100644 index 0000000..5d38110 --- /dev/null +++ b/python/python/023_Merge_k_Sorted_Lists.py @@ -0,0 +1,89 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + # def mergeKLists(self, lists): + # # Priority queue + # from Queue import PriorityQueue + # queue = PriorityQueue() + # for l in lists: + # while l is not None: + # queue.put((l.val, l)) + # l = l.next + # p = dummyHead = ListNode(-1) + # while queue.qsize() > 0: + # p.next = queue.get()[1] + # p = p.next + # p.next = None + # return dummyHead.next + + + # def mergeKLists(self, lists): + # """ + # :type lists: List[ListNode] + # :rtype: ListNode + # """ + # # sort + # v_map = {} + # # hash + # for l in lists: + # while l is not None: + # try: + # v_map[l.val].append(l) + # except KeyError: + # v_map[l.val] = [l] + # l = l.next + # head = last = ListNode(-1) + # # sort and connect + # for k in sorted(v_map.keys()): + # for t in v_map[k]: + # last.next = t + # last = t + # last.next = None + # return head.next + + + + + def mergeKLists(self, lists): + # recursive + if lists is None: + return None + elif len(lists) == 0: + return None + return self.mergeK(lists, 0, len(lists) - 1) + + def mergeK(self, lists, low, high): + if low == high: + return lists[low] + elif low + 1 == high: + return self.mergeTwolists(lists[low], lists[high]) + mid = (low + high) / 2 + return self.mergeTwolists(self.mergeK(lists, low, mid), self.mergeK(lists, mid + 1, high)) + + def mergeTwolists(self, l1, l2): + if l1 is None: + return l2 + if l2 is None: + return l1 + head = curr = ListNode(-1) + while l1 is not None and l2 is not None: + if l1.val <= l2.val: + curr.next = l1 + l1 = l1.next + else: + curr.next = l2 + l2 = l2.next + curr = curr.next + if l1 is not None: + curr.next = l1 + if l2 is not None: + curr.next = l2 + return head.next + + + + diff --git a/python/python/024_Swap_Nodes_in_Pairs.py b/python/python/024_Swap_Nodes_in_Pairs.py new file mode 100644 index 0000000..cb860ef --- /dev/null +++ b/python/python/024_Swap_Nodes_in_Pairs.py @@ -0,0 +1,42 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +# class Solution(object): +# def swapPairs(self, head): +# """ +# :type head: ListNode +# :rtype: ListNode +# """ +class Solution(object): + # def swapPairs(self, head): + # current = last = last2 = head + # while current is not None: + # nex = current.next + # if current == last.next: + # last.next = nex + # current.next = last + # if last == head: + # head = current + # else: + # last2.next = current + # last2 = last + # last = nex + # current = nex + # return head + + def swapPairs(self, head): + dummyHead = ListNode(-1) + dummyHead.next = head + prev, p = dummyHead, head + while p != None and p.next != None: + q, r = p.next, p.next.next + prev.next = q + q.next = p + p.next = r + prev = p + p = r + return dummyHead.next + \ No newline at end of file diff --git a/python/python/025_Reverse_Nodes_i_ k-Group.py b/python/python/025_Reverse_Nodes_i_ k-Group.py new file mode 100644 index 0000000..f6b511f --- /dev/null +++ b/python/python/025_Reverse_Nodes_i_ k-Group.py @@ -0,0 +1,46 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +# class Solution(object): +# def reverseKGroup(self, head, k): +# """ +# :type head: ListNode +# :type k: int +# :rtype: ListNode +# """ +class Solution(object): + def reverseKGroup(self, head, k): + if head is None: + return None + index = 0 + lead, last = 0, 0 + pos = head + temp = ListNode(-1) + temp.next = head + head = temp + start = head + while pos is not None: + if index % k == k - 1: + last = pos.next + start = self.reverseList(start, last) + pos = start + pos = pos.next + index += 1 + return head.next + + def reverseList(self, head, end): + pos = head.next + last = end + next_start = pos + while pos != end: + head.next = pos + last_pos = pos + pos = pos.next + last_pos.next = last + last = last_pos + return next_start + + diff --git a/python/python/026_Remove_Duplicates_from_Sorted_Array.py b/python/python/026_Remove_Duplicates_from_Sorted_Array.py new file mode 100644 index 0000000..6876ac6 --- /dev/null +++ b/python/python/026_Remove_Duplicates_from_Sorted_Array.py @@ -0,0 +1,33 @@ +class Solution(object): + # def removeDuplicates(self, nums): + # """ + # :type nums: List[int] + # :rtype: int + # """ + # ls = len(nums) + # if ls <= 1: + # return ls + # last = nums[0] + # pos = 1 + # for t in nums[1:]: + # if t == last: + # continue + # else: + # nums[pos] = t + # pos += 1 + # last = t + # return pos + + # https://leetcode.com/articles/remove-duplicates-sorted-array/ + def removeDuplicates(self, nums): + if len(nums) == 0: + return 0 + left = 0 + for i in range(1, len(nums)): + if nums[left] == nums[i]: + continue + else: + left += 1 + nums[left] = nums[i] + return left + 1 + diff --git a/python/python/027_Remove_Element.py b/python/python/027_Remove_Element.py new file mode 100644 index 0000000..3266ad3 --- /dev/null +++ b/python/python/027_Remove_Element.py @@ -0,0 +1,41 @@ +# class Solution(object): +# def removeElement(self, nums, val): +# """ +# :type nums: List[int] +# :type val: int +# :rtype: int +# """ +class Solution(object): + # def removeElement(self, nums, val): + # ls = len(nums) + # if ls == 0: + # return ls + # pos = 0 + # for i in range(ls): + # if nums[i] == val: + # continue + # else: + # nums[pos] = nums[i] + # pos += 1 + # # del nums[pos:] + # return pos + + def removeElement(self, nums, val): + ls = len(nums) + if ls == 0: + return ls + count = 0 + index = 0 + while index < ls - count: + if nums[index] == val: + nums[index] = nums[ls - 1 - count] + count += 1 + else: + index += 1 + return ls - count + +if __name__ == '__main__': + # begin + s = Solution() + print s.removeElement([1], 1) + diff --git a/python/python/028_Implement_strStr().py b/python/python/028_Implement_strStr().py new file mode 100644 index 0000000..eece835 --- /dev/null +++ b/python/python/028_Implement_strStr().py @@ -0,0 +1,70 @@ +class Solution(object): + # def strStr(self, haystack, needle): + # """ + # :type haystack: str + # :type needle: str + # :rtype: int + # """ + # lsh, lsn = len(haystack), len(needle) + # if lsn == 0: + # return 0 + # pos, index = 0, 0 + # while index <= lsh - lsn: + # if haystack[index] == needle[pos]: + # backup = index + # while index < lsh and pos < lsn and haystack[index] == needle[pos]: + # pos += 1 + # index += 1 + # if pos == len(needle): + # return index - pos + # index = backup + # index += 1 + # pos = 0 + # return -1 + + # def strStr(self, haystack, needle): + # lsh, lsn = len(haystack), len(needle) + # if lsn == 0: + # return 0 + # pos, index = 0, 0 + # while index <= lsh - lsn: + # if haystack[index] == needle[0]: + # # slice index:index + lsn + # if haystack[index:index + lsn] == needle: + # return index + # index += 1 + # return -1 + + # KMP + # https://discuss.leetcode.com/topic/3576/accepted-kmp-solution-in-java-for-reference/2 + def strStr(self, haystack, needle): + lsh, lsn = len(haystack), len(needle) + if lsn == 0: + return 0 + next = self.makeNext(needle) + i = j = 0 + while i < lsh: + if j == -1 or haystack[i] == needle[j]: + i += 1 + j += 1 + if j == lsn: + return i - lsn + if i < lsh and haystack[i] != needle[j]: + j = next[j] + return -1 + + def makeNext(self, needle): + ls = len(needle) + next = [0] * ls + next[0], i, j = -1, 0, -1 + while i < ls - 1: + if j == -1 or needle[i] == needle[j]: + next[i + 1] = j + 1 + if needle[i + 1] == needle[j + 1]: + next[i + 1] = next[j + 1] + i += 1 + j += 1 + if needle[i] != needle[j]: + j = next[j] + return next + diff --git a/python/python/029_Divide_Two_Integers.py b/python/python/029_Divide_Two_Integers.py new file mode 100644 index 0000000..15cedbe --- /dev/null +++ b/python/python/029_Divide_Two_Integers.py @@ -0,0 +1,45 @@ +# class Solution(object): +# def divide(self, dividend, divisor): +# """ +# :type dividend: int +# :type divisor: int +# :rtype: int +# """ + +import math + +class Solution(object): + def divide(self, dividend, divisor): + if divisor == 0: + return MAX_INT + if dividend == 0: + return 0 + isPositive = (dividend < 0) == (divisor < 0) + m = abs(dividend) + n = abs(divisor) + # ln and exp + res = math.log(m) - math.log(n) + res = int(math.exp(res)) + if isPositive: + return min(res, 2147483647) + return max(0 - res, -2147483648) + + # def divide(self, dividend, divisor): + # # (dividend >= 0) ^ (divisor < 0) + # isPositive = (dividend < 0) == (divisor < 0) + # dividend, divisor, result = abs(dividend), abs(divisor), 0 + # while dividend >= divisor: + # n, nb = 1, divisor + # # fast minus + # while dividend >= nb: + # dividend, result = dividend - nb, result + n + # n, nb = n << 1, nb << 1 + # if isPositive: + # return min(result, 2147483647) + # return max(-result, -2147483648) + +if __name__ == '__main__': + s = Solution() + print s.divide(1, 1) + + diff --git a/python/python/030_Substring_with_Concatenation_of_All_Words.py b/python/python/030_Substring_with_Concatenation_of_All_Words.py new file mode 100644 index 0000000..910a87b --- /dev/null +++ b/python/python/030_Substring_with_Concatenation_of_All_Words.py @@ -0,0 +1,51 @@ +class Solution(object): + def findSubstring(self, s, words): + """ + :type s: str + :type words: List[str] + :rtype: List[int] + """ + ls = len(s) + word_ls = len(words[0]) + target_dict = {} + # create a targe dict for match + for word in words: + try: + target_dict[word] += 1 + except KeyError: + target_dict[word] = 1 + res = [] + for start in range(ls - word_ls * len(words) + 1): + curr_dict = target_dict.copy() + for pos in range(start, start + word_ls * len(words), word_ls): + curr = s[pos:pos + word_ls] + try: + curr_dict[curr] -= 1 + # word appears more than target + if curr_dict[curr] < 0: + break + except KeyError: + # word not in words + break + else: + # all word in target dict + res.append(start) + return res + + # def findSubstring(self, s, words): + # # https://leetcode.com/discuss/87745/3-line-python-solution-sorted-hash-112ms + # wLen, wtLen, wSet, sortHash, sLen = len(words[0]), len(words[0]) * len(words), set(words), sorted( + # [hash(w) for w in words]), len(s) + # h = [hash(s[i:i + wLen]) if s[i:i + wLen] in wSet else None for i in xrange(sLen - wLen + 1)] + # return [i for i in xrange(sLen - wtLen + 1) if h[i] and sorted(h[i: i + wtLen: wLen]) == sortHash] + +if __name__ == '__main__': + s = Solution() + # print s.longestValidParentheses(")(((((()())()()))()(()))(") + print s.findSubstring('wordgoodgoodgoodbestword', ["word", "good", "best", "good"]) + + # [6,9,12] + + + + diff --git a/python/python/031_Next_Permutation.py b/python/python/031_Next_Permutation.py new file mode 100644 index 0000000..cf7aca3 --- /dev/null +++ b/python/python/031_Next_Permutation.py @@ -0,0 +1,54 @@ +class Solution(object): + def nextPermutation(self, nums): + """ + :type nums: List[int] + :rtype: void Do not return anything, modify nums in-place instead. + """ + ls = len(nums) + if ls <= 1: + return + pair = [] + for i in range(ls): + for j in range(i + 1, ls): + # append ascending order pair + if nums[i] < nums[j]: + pair.append([i,j]) + pos = 0 + if len(pair) > 0: + self.swap(nums, pair[-1][0], pair[-1][1]) + pos = pair[-1][0] + 1 + # sort from pos + for i in range(pos, ls): + for j in range(i + 1, ls): + if nums[i] > nums[j]: + self.swap(nums, i, j) + + def swap(self, nums, index1, index2): + if index1 == index2: + return + nums[index1], nums[index2] = nums[index2], nums[index1] + + # def nextPermutation(self, nums): + # # https://leetcode.com/discuss/86630/fast-and-easy-python-solution-beaten-79%25 + # pos = -1 + # ls = len(nums) + # for i in range(ls - 1, 0, -1): + # if nums[i] > nums[i - 1]: + # pos = i - 1 + # break + # if pos == -1: + # self.re_order(nums, 0, ls - 1) + # return + # for i in range(ls - 1, -1, -1): + # if nums[pos] < nums[i]: + # nums[pos], nums[i] = nums[i], nums[pos] + # self.re_order(nums, pos + 1, ls - 1) + # break + # + # def re_order(self, a, start, end): + # for i in range(0, (end - start + 1) // 2): + # a[start + i], a[end - i] = a[end - i], a[start + i] + + + + diff --git a/python/python/032_Longest_Valid_Parentheses.py b/python/python/032_Longest_Valid_Parentheses.py new file mode 100644 index 0000000..0a23760 --- /dev/null +++ b/python/python/032_Longest_Valid_Parentheses.py @@ -0,0 +1,47 @@ +import pdb +class Solution(object): + # def longestValidParentheses(self, s): + # """ + # :type s: str + # :rtype: int + # """ + # ls = len(s) + # start = [0] * (ls + 1) + # all = [0] * (ls + 1) + # for i in reversed(range(ls - 1)): + # if s[i] == '(': + # if s[i + 1] == ')': + # start[i] = 2 + # if start[i + 1] + i + 1 < ls and s[start[i + 1] + i + 1] == ')': + # start[i] = 2 + start[i + 1] + # if start[start[i] + i] > 0: + # start[i] += start[start[i] + i] + # all[i] = max(start[i], all[i + 1]) + # return all[0] + + def longestValidParentheses(self, s): + # https://leetcode.com/discuss/87988/my-easy-o-n-java-solution-with-explanation + ls = len(s) + stack = [] + data = [0] * ls + for i in range(ls): + curr = s[i] + if curr == '(': + stack.append(i) + else: + if len(stack) > 0: + data[i] = 1 + data[stack.pop(-1)] = 1 + tep, res = 0, 0 + for t in data: + if t == 1: + tep += 1 + else: + res = max(tep, res) + tep = 0 + return max(tep, res) + +if __name__ == '__main__': + s = Solution() + # print s.longestValidParentheses(")(((((()())()()))()(()))(") + print s.longestValidParentheses(')()())') diff --git a/python/python/033_Search_in_Rotated_Sorted_Array.py b/python/python/033_Search_in_Rotated_Sorted_Array.py new file mode 100644 index 0000000..9f87344 --- /dev/null +++ b/python/python/033_Search_in_Rotated_Sorted_Array.py @@ -0,0 +1,27 @@ +class Solution: + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: int + """ + # binary search + # if start < mid, then left part is sorted + # if mid < end, then right part is sorted + def get(start, end): + if start > end: + return -1 + mid = (start + end) / 2 + if nums[mid] == target: + return mid + elif nums[mid] >= nums[start]: # First half is sorted + if target >= nums[start] and target < nums[mid]: + return get(start, mid - 1) + else: + return get(mid + 1, end) + elif nums[mid] <= nums[end]: # Second half is sorted + if target > nums[mid] and target <= nums[end]: + return get(mid + 1, end) + else: + return get(start, mid - 1) + return get(0, len(nums) - 1) \ No newline at end of file diff --git a/python/python/034_Search_for_a_Range.py b/python/python/034_Search_for_a_Range.py new file mode 100644 index 0000000..9053b2b --- /dev/null +++ b/python/python/034_Search_for_a_Range.py @@ -0,0 +1,28 @@ +class Solution(object): + def searchRange(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + length = len(nums) + if length == 0: + return [-1, -1] + min = 0 + max = length - 1 + while min <= max: + pos = (min + max) / 2 + if nums[pos] > target: + max = pos - 1 + elif nums[pos] < target: + min = pos + 1 + else: + # when nums[pos] == target + # find the min and max + for i in range(min, max + 1): + if nums[i] == target: + if min < i and nums[min] != nums[i]: + min = i + max = i + return [min, max] + return [-1, -1] \ No newline at end of file diff --git a/python/python/035_Search_Insert_Position.py b/python/python/035_Search_Insert_Position.py new file mode 100644 index 0000000..9e6abd0 --- /dev/null +++ b/python/python/035_Search_Insert_Position.py @@ -0,0 +1,43 @@ +class Solution: + # def searchInsert(self, nums, target): + # """ + # :type nums: List[int] + # :type target: int + # :rtype: int + # """ + # min, pos = 0, 0 + # max = len(nums) - 1 + # while min <= max: + # # binary search + # pos = (max + min) / 2 + # if nums[pos] == target: + # return pos + # elif nums[pos] > target: + # max = pos - 1 + # else: + # min = pos + 1 + # if min > pos: + # # this means that target is great than pos, and target + # # is not in nums + # return pos + 1 + # return pos + + def searchInsert(self, nums, target): + l, r = int(0), len(nums) - 1 + while l < r: + mid = int((l + r) / 2) + if nums[mid] < target: + l = mid + 1 + else: + r = mid + if nums[l] < target: + return l + 1 + return l + + + +if __name__ == '__main__': + # begin + s = Solution() + print (s.searchInsert([1,3,5,6],5)) + diff --git a/python/python/036_Valid Sudoku.py b/python/python/036_Valid Sudoku.py new file mode 100644 index 0000000..a2c6b84 --- /dev/null +++ b/python/python/036_Valid Sudoku.py @@ -0,0 +1,68 @@ +# class Solution(object): +# def isValidSudoku(self, board): +# """ +# :type board: List[List[str]] +# :rtype: bool +# """ +class Solution(object): + def isValidSudoku(self, board): + vset = [0] * 9 + hset = [0] * 9 + bset = [0] * 9 + for i in range(9): + for j in range(9): + curr = board[i][j] + if curr != '.': + index = 1 << (ord(curr) - ord('0')) + if (hset[i] & index) > 0 or\ + (vset[j] & index) > 0 or\ + (bset[(i / 3) * 3 + j / 3] & index) > 0: + return False + hset[i] |= index + vset[j] |= index + bset[(i / 3) * 3 + j / 3] |= index + return True + + # def isValidSudoku(self, board): + # if board is None: + # return True + # for i in range(9): + # table = {} + # for j in range(9): + # curr = board[i][j] + # if curr == '.': + # continue + # else: + # try: + # table[curr] += 1 + # return False + # except KeyError: + # table[curr] = 1 + # for j in range(9): + # table = {} + # for i in range(9): + # curr = board[i][j] + # if curr == '.': + # continue + # else: + # try: + # table[curr] += 1 + # return False + # except KeyError: + # table[curr] = 1 + # for i in range(3): + # for j in range(3): + # table = {} + # for k in range(9): + # curr = board[i * 3 + k / 3][j * 3 + k % 3] + # if curr == '.': + # continue + # else: + # try: + # table[curr] += 1 + # return False + # except KeyError: + # table[curr] = 1 + # return True + + diff --git a/python/python/037_Sudoku_Solver.py b/python/python/037_Sudoku_Solver.py new file mode 100644 index 0000000..4b60c04 --- /dev/null +++ b/python/python/037_Sudoku_Solver.py @@ -0,0 +1,43 @@ +class Solution(object): + def solveSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: void Do not return anything, modify board in-place instead. + """ + #https://leetcode.com/discuss/84831/java-backtracking-stack-20ms + empty = [] + for i in range(9): + for j in range(9): + if board[i][j] == '.': + empty.append(9 * i + j) + self.solve(board, empty) + + def solve(self, board, empty): + if len(empty) == 0: + return True + first_value = empty[-1] + row, col = first_value / 9, first_value % 9 + for k in range(1, 10): + if self.is_safe(board, row, col, str(k)): + board[row][col] = str(k) + empty.pop() + if self.solve(board, empty): + return True + board[row][col] = '.' + empty.append(first_value) + return False + + def is_safe(self, board, row, col, ch): + for k in range(9): + if board[k][col] == ch: + return False + if board[row][k] == ch: + return False + start_row, start_col = 3 * (row / 3), 3 * (col / 3) + for i in range(start_row, start_row + 3): + for j in range(start_col, start_col + 3): + if board[i][j] == ch: + return False + return True + + diff --git a/python/python/038_Count_and_Say.py b/python/python/038_Count_and_Say.py new file mode 100644 index 0000000..a0ea1a8 --- /dev/null +++ b/python/python/038_Count_and_Say.py @@ -0,0 +1,27 @@ +class Solution: + def countAndSay(self, n): + """ + :type n: int + :rtype: str + """ + if n == 1: + return '1' + x = '1' + while n > 1: + # each round, read itself + x = self.count(x) + n -= 1 + return x + + def count(self, x): + m = list(x) + res = [] + m.append(None) + i , j = 0 , 0 + while i < len(m) - 1: + j += 1 + if m[j] != m[i]: + # note j - i is the count of m[i] + res += [j - i, m[i]] + i = j + return ''.join(str(s) for s in res) \ No newline at end of file diff --git a/python/python/039_Combination_Sum.py b/python/python/039_Combination_Sum.py new file mode 100644 index 0000000..91111c1 --- /dev/null +++ b/python/python/039_Combination_Sum.py @@ -0,0 +1,52 @@ +class Solution(object): + # def combinationSum(self, candidates, target): + # """ + # :type candidates: List[int] + # :type target: int + # :rtype: List[List[int]] + # """ + # candidates.sort() + # return self.getcombinationSum(candidates, [], 0, target) + # + # + # def getcombinationSum(self, candidates, prefix, curr, target): + # if len(prefix) == 0: + # max_value = candidates[0] + # else: + # max_value = prefix[-1] + # res = [] + # for i in range(len(candidates)): + # if candidates[i] >= max_value: + # if curr + candidates[i] == target: + # res.append(prefix+[candidates[i]]) + # elif curr + candidates[i] < target: + # res.extend(self.getcombinationSum(candidates, prefix+[candidates[i]], curr + candidates[i], target)) + # else: + # pass + # return res + + + def combinationSum(self, candidates, target): + candidates.sort() + dp = [[] for _ in range(target + 1)] + dp[0].append([]) + for i in range(1, target + 1): + for j in range(len(candidates)): + if candidates[j] > i: + break + for k in range(len(dp[i - candidates[j]])): + temp = dp[i - candidates[j]][k][:] + if len(temp) > 0 and temp[-1] > candidates[j]: + continue + temp.append(candidates[j]) + dp[i].append(temp) + return dp[target] + + +if __name__ == '__main__': + s = Solution() + print s.combinationSum([8,7,4,3], 11) + + + + diff --git a/python/python/040_Combination_Sum_II.py b/python/python/040_Combination_Sum_II.py new file mode 100644 index 0000000..9ef4ce7 --- /dev/null +++ b/python/python/040_Combination_Sum_II.py @@ -0,0 +1,32 @@ +class Solution(object): + def combinationSum2(self, candidates, target): + """ + :type candidates: List[int] + :type target: int + :rtype: List[List[int]] + """ + candidates.sort() + dp = [[] for _ in range(target + 1)] + dp[0].append([]) + for i in range(1, target + 1): + for j in range(len(candidates)): + if candidates[j] > i: + break + for k in range(len(dp[i - candidates[j]])): + temp = dp[i - candidates[j]][k][:] + # check if this number is used + if len(temp) > 0 and temp[-1] >= j: + continue + # store index + temp.append(j) + dp[i].append(temp) + res = [] + check = {} + for temp in dp[target]: + value = [candidates[t] for t in temp] + try: + check[str(value)] += 1 + except KeyError: + check[str(value)] = 1 + res.append(value) + return res \ No newline at end of file diff --git a/python/python/041_First_Missing_Positive.py b/python/python/041_First_Missing_Positive.py new file mode 100644 index 0000000..2a08cdf --- /dev/null +++ b/python/python/041_First_Missing_Positive.py @@ -0,0 +1,21 @@ +class Solution(object): + def firstMissingPositive(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + # https://leetcode.com/discuss/86025/java-clean-o-n-solution-with-explanation + ls = len(nums) + index = 0 + while index < ls: + # nums[nums[index] - 1] == nums[index] means that the num is in right position + if nums[index] <= 0 or nums[index] > ls or nums[nums[index] - 1] == nums[index]: + index += 1 + else: + # swap current num to correct position + pos = nums[index] - 1 + nums[index], nums[pos] = nums[pos], nums[index] + res = 0 + while res < ls and nums[res] == res + 1: + res += 1 + return res + 1 diff --git a/python/python/042_Trapping_Rain_Water.py b/python/python/042_Trapping_Rain_Water.py new file mode 100644 index 0000000..6bf0d30 --- /dev/null +++ b/python/python/042_Trapping_Rain_Water.py @@ -0,0 +1,76 @@ +class Solution(object): + def trap(self, height): + """ + :type height: List[int] + :rtype: int + """ + ls = len(height) + if ls == 0: + return 0 + res, left = 0, 0 + while left < ls and height[left] == 0: + left += 1 + pos = left + 1 + while pos < ls: + if height[pos] >= height[left]: + # there is a right bar which is no less than left bar + res += self.rain_water(height, left, pos) + left = pos + pos += 1 + elif pos == ls - 1: + # left bar is higher than all right bar + max_value, max_index = 0, pos + for index in range(left + 1, ls): + if height[index] > max_value: + max_value = height[index] + max_index = index + res += self.rain_water(height, left, max_index) + left = max_index + pos = left + 1 + else: + pos += 1 + return res + + def rain_water(self, height, start, end): + # computer rain water + if end - start <= 1: + return 0 + min_m = min(height[start], height[end]) + res = min_m * (end - start - 1) + step = 0 + for index in range(start + 1, end): + if height[index] > 0: + step += height[index] + return res - step + + # def trap(self, height): + # ls = len(height) + # if ls == 0: + # return 0 + # height.append(0) + # height.insert(0, 0) + # left = [0] * ls + # right = [0] * ls + # cur_left, cur_right = 0, 0 + # for i in range(1, ls + 1): + # cur_left = max(cur_left, height[i - 1]) + # # left[i] store max bar from left + # left[i - 1] = cur_left + # for i in reversed(range(ls)): + # cur_right = max(cur_right, height[i + 1]) + # # right[i] store max bar from right + # right[i] = cur_right + # res = 0 + # for i in range(ls): + # curr = min(left[i], right[i]) + # if curr > height[i]: + # res += curr - height[i] + # return res + + +if __name__ == '__main__': + # begin + s = Solution() + print s.trap([2,6,3,8,2,7,2,5,0]) + + diff --git a/python/python/043_Multiply_Strings.py b/python/python/043_Multiply_Strings.py new file mode 100644 index 0000000..3f66e45 --- /dev/null +++ b/python/python/043_Multiply_Strings.py @@ -0,0 +1,79 @@ +class Solution(object): + # def multiply(self, num1, num2): + # """ + # :type num1: str + # :type num2: str + # :rtype: str + # """ + # res = '' + # curr, pos = 0, 0 + # if len(num1) > num2: + # num1, num2 = num2, num1 + # ls1, ls2 = len(num1), len(num2) + # mid = [] + # for i in reversed(range(ls1)): + # curr = 0 + # fact = '' + # for j in reversed(range(ls2)): + # curr = curr + int(num1[i]) * int(num2[j]) + # fact = str(curr % 10) + fact + # curr /= 10 + # if curr > 0: + # fact = str(curr) + fact + # if int(fact) == 0: + # pass + # else: + # print fact + # mid.append(fact + '0' * pos) + # pos += 1 + # res = self.add_strings(mid) + # return res + # + # + # def add_strings(self, s_list): + # if len(s_list) == 0: + # return '0' + # res = '' + # curr, pos = 0, 0 + # max_ls = max([len(t) for t in s_list]) + # while pos < max_ls: + # for s in s_list: + # if len(s) <= pos: + # continue + # curr += int(s[len(s) - pos - 1]) + # res = str(curr % 10) + res + # curr /= 10 + # pos += 1 + # if curr > 0: + # res = str(curr) + res + # return res + + def multiply(self, num1, num2): + if num1 == '0' or num2 == '0': + return '0' + res = '' + ls1, ls2, = len(num1), len(num2) + ls = ls1 + ls2 + # list stores int + arr = [0] * ls + for i in reversed(range(ls1)): + for j in reversed(range(ls2)): + # store the direct results of multiply two ints + arr[i + j + 1] += int(num1[i]) * int(num2[j]) + for i in reversed(range(1, ls)): + # digital plus + arr[i - 1] += arr[i] / 10 + arr[i] %= 10 + pos = 0 + # to string + if arr[pos] == 0: + pos += 1 + while pos < ls: + res = res + str(arr[pos]) + pos += 1 + return res + + +if __name__ == '__main__': + s = Solution() + print s.multiply("98", "9") diff --git a/python/python/044_Wildcard_Matching.py b/python/python/044_Wildcard_Matching.py new file mode 100644 index 0000000..1ba2eb5 --- /dev/null +++ b/python/python/044_Wildcard_Matching.py @@ -0,0 +1,79 @@ +class Solution(object): + # def isMatch(self, s, p): + # """ + # :type s: str + # :type p: str + # :rtype: bool + # """ + # return self.dfs(s, p, 0, 0) > 1 + # + # + # def dfs(self, s, p, s_index, p_index): + # if s_index == len(s) and p_index == len(p): + # return 2 + # if s_index == len(s) and p[p_index] != '*': + # return 0 + # if p_index == len(p): + # return 1 + # if p[p_index] == '*': + # if p_index + 1 < len(p) and p[p_index + 1] == '*': + # # skip duplicate * + # return self.dfs(s, p, s_index, p_index + 1) + # for i in range(len(s) - s_index + 1): + # res = self.dfs(s, p, s_index + i, p_index + 1) + # if res == 0 or res == 2: + # return res + # if p[p_index] == '?' or s[s_index] == p[p_index]: + # return self.dfs(s, p, s_index + 1, p_index + 1) + # return 1 + + # def isMatch(self, s, p): + # #TODO + # # O(m * n) LTE + # m, n = len(s), len(p) + # dp = [[False] * (n + 1) for _ in range(m + 1)] + # dp[0][0] = True + # for j in range(1, n): + # dp[0][j + 1] = dp[0][j] and p[j] == '*' + # for i in range(m): + # for j in range(n): + # if p[j] == '?' or p[j] == s[i]: + # dp[i + 1][j + 1] = dp[i][j] + # elif p[j] == '*': + # dp[i + 1][j + 1] = dp[i + 1][j] or dp[i][j + 1] + # return dp[m][n] + + def isMatch(self, s, p): + """ + :type s: str + :type p: str + :rtype: bool + """ + s_index, p_index = 0, 0 + star, s_star = -1, 0 + s_len, p_len = len(s), len(p) + while s_index < s_len: + if p_index < p_len and (s[s_index] == p[p_index] or p[p_index] == '?'): + s_index += 1 + p_index += 1 + elif p_index < p_len and p[p_index] == '*': + star = p_index + s_star = s_index + p_index += 1 + elif star != -1: + p_index = star + 1 + s_star += 1 + s_index = s_star + else: + return False + while p_index < p_len and p[p_index] == '*': + p_index += 1 + return p_index == p_len + + + +if __name__ == '__main__': + # begin + s = Solution() + print s.isMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*") \ No newline at end of file diff --git a/python/python/045_Jump_Game_II.py b/python/python/045_Jump_Game_II.py new file mode 100644 index 0000000..dc8e137 --- /dev/null +++ b/python/python/045_Jump_Game_II.py @@ -0,0 +1,20 @@ +class Solution: + def jump(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + if len(nums) <= 1: + return 0 + end = 0 + nums[0] + start = 0 + step = 1 + maxDis = 0 + nums[0] + while end < len(nums) - 1: + for i in range(start + 1, end + 1): + # greedy + maxDis = max(maxDis, nums[i] + i) + start = end + end = maxDis + step += 1 + return step diff --git a/python/python/046_Permutations.py b/python/python/046_Permutations.py new file mode 100644 index 0000000..3c21445 --- /dev/null +++ b/python/python/046_Permutations.py @@ -0,0 +1,44 @@ +class Solution: + # import itertools + # def permute(self, nums): + # """ + # :type nums: List[int] + # :rtype: List[List[int]] + # """ + # result = itertools.permutations(nums) + # result = [list(t) for t in result] + # return result + + def permute(self, nums): + # DPS with swapping + res = [] + if len(nums) == 0: + return res + self.get_permute(res, nums, 0) + return res + + def get_permute(self, res, nums, index): + if index == len(nums): + res.append(list(nums)) + return + for i in range(index, len(nums)): + nums[i], nums[index] = nums[index], nums[i] + # s(n) = 1 + s(n-1) + self.get_permute(res, nums, index + 1) + nums[i], nums[index] = nums[index], nums[i] + + # def permute(self, nums): + # # iterative solution + # res = [[]] + # for i in range(len(nums)): + # cache = set() + # while len(res[0]) == i: + # curr = res.pop(0) + # for j in range(len(curr) + 1): + # # generate new n permutations from n -1 permutations + # new_perm = curr[:j] + [nums[i]] + curr[j:] + # stemp = ''.join(map(str, new_perm)) + # if stemp not in cache: + # cache.add(stemp) + # res.append(new_perm) + # return res diff --git a/python/python/047_Permutations_II.py b/python/python/047_Permutations_II.py new file mode 100644 index 0000000..dac273c --- /dev/null +++ b/python/python/047_Permutations_II.py @@ -0,0 +1,67 @@ +class Solution(object): + # def __init__(self): + # self.result = {} + # + # def permuteUnique(self, num): + # """ + # :type nums: List[int] + # :rtype: List[List[int]] + # """ + # if num is None: + # return [] + # num.sort() + # self.getPermute([], num) + # return self.result.values() + # + # def getPermute(self, prefix, rest): + # ls = len(rest) + # if ls == 0: + # return + # elif ls == 1: + # temp = prefix + rest + # stemp = ''.join(str(t) for t in temp) + # self.result[stemp] = temp + # else: + # for i in range(ls): + # if i + 1 < ls and rest[i] == rest[i + 1]: + # continue + # temp = prefix[:] + # temp.append(rest[i]) + # self.getPermute(temp, rest[:i] + rest[i + 1:]) + + def permuteUnique(self, num): + res = [] + if len(num) == 0: + return res + self.permute(res, num, 0) + return res + + def permute(self, res, num, index): + if index == len(num): + res.append(list(num)) + return + appeared = set() + for i in range(index, len(num)): + if num[i] in appeared: + continue + appeared.add(num[i]) + num[i], num[index] = num[index], num[i] + self.permute(res, num, index + 1) + num[i], num[index] = num[index], num[i] + + def permuteUnique(self, num): + # iterative solution + res = [[]] + for i in range(len(nums)): + cache = set() + while len(res[0]) == i: + curr = res.pop(0) + for j in range(len(curr) + 1): + # generate new n permutations from n -1 permutations + new_perm = curr[:j] + [nums[i]] + curr[j:] + stemp = ''.join(map(str, new_perm)) + if stemp not in cache: + cache.add(stemp) + res.append(new_perm) + return res + diff --git a/python/python/048_Rotate_Image.py b/python/python/048_Rotate_Image.py new file mode 100644 index 0000000..85cf586 --- /dev/null +++ b/python/python/048_Rotate_Image.py @@ -0,0 +1,29 @@ +class Solution(object): + def rotate(self, matrix): + """ + :type matrix: List[List[int]] + :rtype: void Do not return anything, modify matrix in-place instead. + """ + # rotate from outside to inside + if matrix is None or len(matrix) == 1: + return + ls = len(matrix) + for i in range(ls / 2): + # border + begin, end = i, ls - 1 - i + for k in range(ls - 2 * i - 1): + temp = matrix[end - k][begin] + matrix[end - k][begin] = matrix[end][end - k] + matrix[end][end - k] = matrix[begin + k][end] + matrix[begin + k][end] = matrix[begin][begin + k] + matrix[begin][begin + k] = temp + return + +if __name__ == '__main__': + # begin + s = Solution() + s.rotate([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]) + + + + diff --git a/python/python/049_Group_Anagrams.py b/python/python/049_Group_Anagrams.py new file mode 100644 index 0000000..e48ca2f --- /dev/null +++ b/python/python/049_Group_Anagrams.py @@ -0,0 +1,45 @@ +class Solution(object): + # def groupAnagrams(self, strs): + # """ + # :type strs: List[str] + # :rtype: List[List[str]] + # """ + # hash = {} + # for s in strs: + # key = self.hash_key(s) + # try: + # hash[key].append(s) + # except KeyError: + # hash[key] = [s] + # for k, v in hash.items(): + # if len(v) > 1: + # # sort + # v.sort() + # return hash.values() + # + # def hash_key(self, s): + # # hash string with 26 length array + # table = [0] * 26 + # for ch in s: + # index = ord(ch) - ord('a') + # table[index] += 1 + # return str(table) + + def groupAnagrams(self, strs): + strs.sort() + hash = {} + for s in strs: + key = self.hash_key(s) + try: + hash[key].append(s) + except KeyError: + hash[key] = [s] + return hash.values() + + def hash_key(self, s): + # hash string with 26 length array + table = [0] * 26 + for ch in s: + index = ord(ch) - ord('a') + table[index] += 1 + return str(table) \ No newline at end of file diff --git a/python/python/050_Pow(x, n).py b/python/python/050_Pow(x, n).py new file mode 100644 index 0000000..b27e60f --- /dev/null +++ b/python/python/050_Pow(x, n).py @@ -0,0 +1,31 @@ +class Solution: + # def myPow(self, x, n): + # """ + # :type x: float + # :type n: int + # :rtype: float + # """ + # if n == 0: + # return 1 + # temp = pow(x, n / 2) + # if n % 2 == 0: + # return temp * temp + # else: + # return temp * temp * x + + def myPow(self, x, n): + # https://leetcode.com/discuss/93413/iterative-log-n-solution-with-clear-explanation + # 9 = 2^3 + 2^0 = 1001 + # x^9 = x^(2^3)*x(2^0) + # multiple x^i when i place is 1 + if n == 0: + return 1 + res ,curr = 1, abs(n) + while curr > 0: + if curr & 1 == 1: + res *= x + curr >>= 1 + x *= x + if n < 0: + return 1 / res + return res diff --git a/python/python/051_N-Queens.py b/python/python/051_N-Queens.py new file mode 100644 index 0000000..9a64e31 --- /dev/null +++ b/python/python/051_N-Queens.py @@ -0,0 +1,42 @@ +class Solution(object): + def solveNQueens(self, n): + """ + :type n: int + :rtype: List[List[str]] + """ + # recusive + if n == 0: + return 0 + res = [] + board = [['.'] * n for t in range(n)] + self.do_solveNQueens(res, board, n) + return res + + def do_solveNQueens(self, res, board, num): + if num == 0: + res.append([''.join(t) for t in board]) + return + ls = len(board) + pos = ls - num + check = [True] * ls + for i in range(pos): + for j in range(ls): + if board[i][j] == 'Q': + check[j] = False + step = pos - i + if j + step < ls: + check[j + step] = False + if j - step >= 0: + check[j - step] = False + break + for j in range(ls): + if check[j]: + board[pos][j] = 'Q' + self.do_solveNQueens(res, board, num - 1) + board[pos][j] = '.' + + +if __name__ == '__main__': + # begin + s = Solution() + print s.solveNQueens(4) \ No newline at end of file diff --git a/python/python/052_N-Queens II.py b/python/python/052_N-Queens II.py new file mode 100644 index 0000000..39f8112 --- /dev/null +++ b/python/python/052_N-Queens II.py @@ -0,0 +1,78 @@ +class Solution(object): + # def totalNQueens(self, n): + # """ + # :type n: int + # :rtype: int + # """ + # if n == 0: + # return 0 + # res = [0] + # board = [['.'] * n for t in range(n)] + # self.do_solveNQueens(res, board, n) + # return res[0] + # + # def do_solveNQueens(self, res, board, num): + # if num == 0: + # res[0] += 1 + # return + # ls = len(board) + # pos = ls - num + # check = [True] * ls + # for i in range(pos): + # for j in range(ls): + # if board[i][j] == 'Q': + # check[j] = False + # step = pos - i + # if j + step < ls: + # check[j + step] = False + # if j - step >= 0: + # check[j - step] = False + # break + # if pos == 0: + # # mirror on the first row + # for j in range(ls / 2): + # if check[j]: + # board[pos][j] = 'Q' + # self.do_solveNQueens(res, board, num - 1) + # board[pos][j] = '.' + # res[0] *= 2 + # if ls % 2 != 0: + # if check[ls / 2]: + # board[pos][ls / 2] = 'Q' + # self.do_solveNQueens(res, board, num - 1) + # board[pos][ls / 2] = '.' + # else: + # for j in range(ls): + # if check[j]: + # board[pos][j] = 'Q' + # self.do_solveNQueens(res, board, num - 1) + # board[pos][j] = '.' + + def __init__(self): + self.count = 0 + + def totalNQueens(self, n): + self.dfs(0, n, 0, 0, 0) + return self.count + + def dfs(self, row, n, column, diag, antiDiag): + # https://leetcode.com/discuss/89951/share-my-java-code-beats-97-83%25-run-times + if row == n: + self.count += 1 + return + for index in range(n): + # column check + isColSafe = (1 << index) & column == 0 + # diagonal, all nodes have the same n - 1 + row - index + isDigSafe = (1 << (n - 1 + row - index)) & diag == 0 + # anti diagonal, all nodes have the same row + index + isAntiDiagSafe = (1 << (row + index)) & antiDiag == 0 + if isAntiDiagSafe and isColSafe and isDigSafe: + self.dfs(row + 1, n, (1 << index) | column, + (1 << (n - 1 + row - index)) | diag, + (1 << (row + index)) | antiDiag) + +if __name__ == '__main__': + # begin + s = Solution() + print s.totalNQueens(4) \ No newline at end of file diff --git a/python/python/053_Maximum_Subarray.py b/python/python/053_Maximum_Subarray.py new file mode 100644 index 0000000..6a8977e --- /dev/null +++ b/python/python/053_Maximum_Subarray.py @@ -0,0 +1,48 @@ +class Solution(object): + # def maxSubArray(self, nums): + # return self.maxSubArrayHelper(nums, 0, len(nums) - 1) + # + # def maxSubArrayHelper(self, nums, l, r): + # if l > r: + # return -2147483647 + # mid = (l + r) / 2 + # leftAns = self.maxSubArrayHelper(nums, l, mid - 1) + # rightAns = self.maxSubArrayHelper(nums, mid + 1, r) + # lMaxSum = res = 0 + # for i in range(mid - 1, l -1, -1): + # res += nums[i] + # lMaxSum = max(res, lMaxSum) + # rMaxSum = res = 0 + # for i in range(mid + 1, r + 1): + # res += nums[i] + # rMaxSum = max(res, rMaxSum) + # return max(lMaxSum + nums[mid] + rMaxSum, max(leftAns, rightAns)) + + # def maxSubArray(self, nums): + # """ + # :type nums: List[int] + # :rtype: int + # """ + # ls = len(nums) + # start = [0] * ls + # all = [0] * ls + # start[-1], all[-1] = nums[-1], nums[-1] + # for i in reversed(range(ls - 1)): + # start[i] = max(nums[i], nums[i] + start[i + 1]) + # all[i] = max(start[i], all[i + 1]) + # return all[0] + + # def maxSubArray(self, nums): + # ls = len(nums) + # start, all = nums[-1], nums[-1] + # for i in reversed(range(ls - 1)): + # start = max(nums[i], nums[i] + start) + # all = max(start, all) + # return all + + def maxSubArray(self, nums): + maxEndingHere = maxSofFar = nums[0] + for i in range(1, len(nums)): + maxEndingHere = max(maxEndingHere + nums[i], nums[i]) + maxSofFar = max(maxEndingHere, maxSofFar) + return maxSofFar \ No newline at end of file diff --git a/python/python/054_Spiral_Matrix.py b/python/python/054_Spiral_Matrix.py new file mode 100644 index 0000000..7713542 --- /dev/null +++ b/python/python/054_Spiral_Matrix.py @@ -0,0 +1,47 @@ +class Solution(object): + def spiralOrder(self, matrix): + """ + :type matrix: List[List[int]] + :rtype: List[int] + """ + if matrix is None or len(matrix) == 0: + return matrix + m, n = len(matrix), len(matrix[0]) + return self.get_spiralOrder(matrix, 0, m - 1, 0, n - 1) + + def get_spiralOrder(self, matrix, r_start, r_end, c_start, c_end): + if r_start > r_end or c_start > c_end: + return [] + elif r_start == r_end: + return matrix[r_start][c_start:c_end + 1] + elif c_start == c_end: + return [matrix[j][c_end] for j in range(r_start, r_end + 1)] + curr = matrix[r_start][c_start:c_end + 1] + [matrix[j][c_end] for j in range(r_start + 1, r_end)] +\ + matrix[r_end][c_start:c_end + 1][::-1] +\ + [matrix[j][c_start] for j in reversed(range(r_start + 1, r_end))] + res = curr + self.get_spiralOrder(matrix, r_start + 1, r_end - 1, c_start + 1, c_end - 1) + return res + + + # def spiralOrder(self, matrix): + # res = [] + # if not matrix: + # return [] + # i, j, di, dj = 0, 0, 0, 1 + # m, n = len(matrix), len(matrix[0]) + # for v in xrange(m * n): + # res.append(matrix[i][j]) + # matrix[i][j] = '' + # if matrix[(i + di) % m][(j + dj) % n] == '': + # # (0, 1) -> (1, 0) -> (0, -1) -> (-1, 0) + # # then loop + # di, dj = dj, -di + # i += di + # j += dj + # return res + +if __name__ == '__main__': + # begin + s = Solution() + print s.spiralOrder([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]) + diff --git a/python/python/055_Jump_Game.py b/python/python/055_Jump_Game.py new file mode 100644 index 0000000..0e8b9ec --- /dev/null +++ b/python/python/055_Jump_Game.py @@ -0,0 +1,14 @@ +class Solution(object): + def canJump(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + # greedy + # https://leetcode.com/articles/jump-game/ + length = len(nums) + begin = length - 1 + for i in reversed(range(length - 1)): + if i + nums[i] >= begin: + begin = i + return not begin \ No newline at end of file diff --git a/python/python/056_Merge_Intervals.py b/python/python/056_Merge_Intervals.py new file mode 100644 index 0000000..f90b245 --- /dev/null +++ b/python/python/056_Merge_Intervals.py @@ -0,0 +1,36 @@ +# Definition for an interval. +# class Interval(object): +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution(object): + def merge(self, intervals): + """ + :type intervals: List[Interval] + :rtype: List[Interval] + """ + if intervals is None: + return + ls = len(intervals) + if ls <= 1: + return intervals + # sort by start + intervals.sort(key=lambda x: x.start) + pos = 0 + while pos < len(intervals) - 1: + # check overlap + if intervals[pos].end >= intervals[pos + 1].start: + next = intervals.pop(pos + 1) + # check next is overlap or totally covered by pos + if next.end > intervals[pos].end: + intervals[pos].end = next.end + # print [(t.start, t.end) for t in intervals], pos + else: + pos += 1 + return intervals + +if __name__ == '__main__': + # begin + s = Solution() + print s.merge([[1,3],[2,6],[8,10],[15,18]]) \ No newline at end of file diff --git a/python/python/057_Insert_Interval.py b/python/python/057_Insert_Interval.py new file mode 100644 index 0000000..480bdcb --- /dev/null +++ b/python/python/057_Insert_Interval.py @@ -0,0 +1,48 @@ +# Definition for an interval. +# class Interval(object): +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution(object): + def insert(self, intervals, newInterval): + """ + :type intervals: List[Interval] + :type newInterval: Interval + :rtype: List[Interval] + """ + if intervals is None or len(intervals) == 0: + return [newInterval] + intervals.sort(key=lambda x:x.start) + pos = 0 + while pos < len(intervals): + # left of pos + if newInterval.end < intervals[pos].start: + intervals.insert(pos, newInterval) + return intervals + # overlap with pos + if self.check_overlap(intervals[pos], newInterval): + temp = intervals.pop(pos) + newInterval = self.merge_intervals(temp, newInterval) + else: + pos += 1 + if len(intervals) == 0 or pos == len(intervals): + intervals.append(newInterval) + return intervals + + def check_overlap(self, curr_int, new_int): + if curr_int.start <= new_int.start: + if curr_int.end > new_int.start: + return True + else: + if curr_int.start <= new_int.end: + return True + return False + + def merge_intervals(self, int1, int2): + temp_int = Interval() + temp_int.start = min([int1.start, int2.start]) + temp_int.end = max([int1.end, int2.end]) + return temp_int + + diff --git a/python/python/058_Length_of_Last_Word.py b/python/python/058_Length_of_Last_Word.py new file mode 100644 index 0000000..40e835a --- /dev/null +++ b/python/python/058_Length_of_Last_Word.py @@ -0,0 +1,14 @@ +class Solution(object): + def lengthOfLastWord(self, s): + """ + :type s: str + :rtype: int + """ + if len(s) == 0: + return 0 + temp = s.split(' ') + temp = [t for t in temp if len(t) > 0] + if len(temp) == 0: + return 0 + else: + return len(temp[-1]) \ No newline at end of file diff --git a/python/python/059_Spiral_Matrix_II.py b/python/python/059_Spiral_Matrix_II.py new file mode 100644 index 0000000..45ea222 --- /dev/null +++ b/python/python/059_Spiral_Matrix_II.py @@ -0,0 +1,22 @@ +class Solution(object): + def generateMatrix(self, n): + """ + :type n: int + :rtype: List[List[int]] + """ + res = [[0] * n for _ in range(n)] + pos = [0, 0] + move = (0, 1) + for index in range(1, n * n + 1): + res[pos[0]][pos[1]] = index + if res[(pos[0] + move[0]) % n][(pos[1] + move[1]) % n] > 0: + # (0, 1) -> (1, 0) -> (0, -1) -> (-1, 0) + move = (move[1], -1 * move[0]) + pos[0] = pos[0] + move[0] + pos[1] = pos[1] + move[1] + return res + +if __name__ == '__main__': + # begin + s = Solution() + print s.generateMatrix(2) \ No newline at end of file diff --git a/python/python/060_Permutation_Sequence.py b/python/python/060_Permutation_Sequence.py new file mode 100644 index 0000000..e582b57 --- /dev/null +++ b/python/python/060_Permutation_Sequence.py @@ -0,0 +1,34 @@ +class Solution(object): + def getPermutation(self, n, k): + """ + :type n: int + :type k: int + :rtype: str + """ + # let permutations with first identical num be a block + # target in (k - 1) / (n - 1)! block + remain = range(1, n + 1) + if k <= 1: + return ''.join(str(t) for t in remain) + total = 1 + for num in remain[:-1]: + total *= num + res = self.do_getPermutation(remain, total, n - 1, k - 1) + return ''.join(str(t) for t in res) + + + def do_getPermutation(self, remain, curr, n, k): + if n == 0 or k <= 0 or curr == 0: + return remain + # which block + step = k / curr + # remain k value + k %= curr + curr /= n + res = [remain[step]] + self.do_getPermutation(remain[:step] + remain[step + 1:], curr, n - 1, k) + return res + +if __name__ == '__main__': + s = Solution() + print s.getPermutation(3, 2) + # print s.getPermutation(2, 2) \ No newline at end of file diff --git a/python/python/061_Rotate_List.py b/python/python/061_Rotate_List.py new file mode 100644 index 0000000..27941ae --- /dev/null +++ b/python/python/061_Rotate_List.py @@ -0,0 +1,38 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def rotateRight(self, head, k): + """ + :type head: ListNode + :type k: int + :rtype: ListNode + """ + if not head or k == 0: + return head + + slow = fast = head + length = 1 + + while k and fast.next: + fast = fast.next + length += 1 + k -= 1 + + if k != 0: + k = (k + length - 1) % length # original k % length + return self.rotateRight(head, k) + else: + while fast.next: + fast = fast.next + slow = slow.next + return self.rotate(head, fast, slow) + + def rotate(self, head, fast, slow): + fast.next = head + head = slow.next + slow.next = None + return head \ No newline at end of file diff --git a/python/python/062_Unique_Paths.py b/python/python/062_Unique_Paths.py new file mode 100644 index 0000000..acf44b2 --- /dev/null +++ b/python/python/062_Unique_Paths.py @@ -0,0 +1,21 @@ +class Solution: + def uniquePaths(self, m, n): + """ + :type m: int + :type n: int + :rtype: int + """ + dmap = [[0] * n for _ in range(m)] + for i in range(m): + dmap[i][0] = 1 + for j in range(n): + dmap[0][j] = 1 + for i in range(1, m): + for j in range(1, n): + l = u = 0 + if i-1 >= 0: + u = dmap[i-1][j] + if j-1>= 0: + l = dmap[i][j-1] + dmap[i][j] = l + u + return dmap[m-1][n-1] diff --git a/python/python/063_Unique_Paths_II.py b/python/python/063_Unique_Paths_II.py new file mode 100644 index 0000000..c6653f1 --- /dev/null +++ b/python/python/063_Unique_Paths_II.py @@ -0,0 +1,43 @@ +class Solution(object): + # def uniquePathsWithObstacles(self, obstacleGrid): + # """ + # :type obstacleGrid: List[List[int]] + # :rtype: int + # """ + # m, n = len(obstacleGrid), len(obstacleGrid[0]) + # dmap = [[0] * n for _ in range(m)] + # for i in range(m): + # if obstacleGrid[i][0] != 1: + # dmap[i][0] = 1 + # else: + # break + # for j in range(n): + # if obstacleGrid[0][j] != 1: + # dmap[0][j] = 1 + # else: + # break + # for i in range(1, m): + # for j in range(1, n): + # if obstacleGrid[i][j] == 1: + # continue + # l = u = 0 + # if i - 1 >= 0: + # u = dmap[i - 1][j] + # if j - 1 >= 0: + # l = dmap[i][j - 1] + # dmap[i][j] = l + u + # return dmap[m - 1][n - 1] + + def uniquePathsWithObstacles(self, obstacleGrid): + m, n = len(obstacleGrid), len(obstacleGrid[0]) + if m == 0: + return 0 + dmap = [[0] * (n + 1) for _ in range(m + 1)] + dmap[m - 1][n] = 1 + for i in range(m - 1, -1, -1): + for j in range(n - 1, -1, -1): + if obstacleGrid[i][j] == 1: + dmap[i][j] = 0 + else: + dmap[i][j] = dmap[i][j + 1] + dmap[i + 1][j] + return dmap[0][0] \ No newline at end of file diff --git a/python/python/064_Minimum_Path_Sum.py b/python/python/064_Minimum_Path_Sum.py new file mode 100644 index 0000000..5d56e6b --- /dev/null +++ b/python/python/064_Minimum_Path_Sum.py @@ -0,0 +1,24 @@ +class Solution(object): + def minPathSum(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + height = len(grid) + if height == 0: + return 0 + width = len(grid[0]) + pathmap = [] + for i in range(height): + pathmap.append([100000000000] * width) + pathmap[0][0] = grid[0][0] + for i in range(height): + for j in range(width): + compare = [pathmap[i][j]] + if i - 1 >= 0: + compare.append(pathmap[i - 1][j] + grid[i][j]) + if j - 1 >= 0: + compare.append(pathmap[i][j - 1] + grid[i][j]) + # min choice + pathmap[i][j] = min(compare) + return pathmap[-1][-1] \ No newline at end of file diff --git a/python/python/065_Valid_Number.py b/python/python/065_Valid_Number.py new file mode 100644 index 0000000..314422b --- /dev/null +++ b/python/python/065_Valid_Number.py @@ -0,0 +1,52 @@ +class Solution(object): + # def isNumber(self, s): + # """ + # :type s: str + # :rtype: bool + # """ + # # remove lead and tail space + # s = s.strip() + # try: + # float(s) + # return True + # except: + # if '.' in s or ' ' in s: + # return False + # temp = s.split('e') + # if len(temp) == 2: + # try: + # int(temp[0]) + # int(temp[1]) + # except: + # return False + # return True + # return False + + def isNumber(self, s): + s = s.strip() + ls, pos = len(s), 0 + if ls == 0: + return False + if s[pos] == '+' or s[pos] == '-': + pos += 1 + isNumeric = False + while pos < ls and s[pos].isdigit(): + pos += 1 + isNumeric = True + if pos < ls and s[pos] == '.': + pos += 1 + while pos < ls and s[pos].isdigit(): + pos += 1 + isNumeric = True + elif pos < ls and s[pos] == 'e' and isNumeric: + isNumeric = False + pos += 1 + if pos < ls and (s[pos] == '+' or s[pos] == '-'): + pos += 1 + while pos < ls and s[pos].isdigit(): + pos += 1 + isNumeric = True + print pos, ls, isNumeric + if pos == ls and isNumeric: + return True + return False diff --git a/python/python/066_Plus_One.py b/python/python/066_Plus_One.py new file mode 100644 index 0000000..3dbc4d0 --- /dev/null +++ b/python/python/066_Plus_One.py @@ -0,0 +1,35 @@ +class Solution(object): + # def plusOne(self, digits): + # """ + # :type digits: List[int] + # :rtype: List[int] + # """ + # ls = len(digits) + # curr, pos = 1, 0 + # while pos < ls: + # index = ls - pos - 1 + # curr += digits[index] + # digits[index] = curr % 10 + # curr /= 10 + # if curr == 0: + # # do not need to continue + # break + # pos += 1 + # if curr > 0: + # digits.insert(0, curr) + # return digits + + def plusOne(self, digits): + ls = len(digits) + for index in reversed(range(ls)): + if digits[index] < 9: + digits[index] += 1 + # do not need to continue + return digits + else: + # 10 + digits[index] = 0 + digits.insert(0, 1) + return digits + + diff --git a/python/python/067_Add_Binary.py b/python/python/067_Add_Binary.py new file mode 100644 index 0000000..70fd792 --- /dev/null +++ b/python/python/067_Add_Binary.py @@ -0,0 +1,60 @@ +class Solution(object): + # def addBinary(self, a, b): + # """ + # :type a: str + # :type b: str + # :rtype: str + # """ + # res = '' + # lsa, lsb = len(a), len(b) + # pos = -1 + # plus = 0 + # while (lsa + pos) >= 0 and (lsb + pos) >= 0: + # curr = int(a[pos]) + int(b[pos]) + plus + # if curr >= 2: + # plus = 1 + # curr %= 2 + # else: + # plus = 0 + # res = str(curr) + res + # pos -= 1 + # if lsa + pos >= 0: + # while (lsa + pos) >= 0: + # curr = int(a[pos]) + plus + # if curr >= 2: + # plus = 1 + # curr %= 2 + # else: + # plus = 0 + # res = str(curr) + res + # pos -= 1 + # if lsb + pos >= 0: + # while (lsb + pos) >= 0: + # curr = int(b[pos]) + plus + # if curr >= 2: + # plus = 1 + # curr %= 2 + # else: + # plus = 0 + # res = str(curr) + res + # pos -= 1 + # if plus == 1: + # res = '1' + res + # return res + + def addBinary(self, a, b): + res = '' + lsa, lsb = len(a), len(b) + pos, plus, curr = -1, 0, 0 + # plus a[pos], b[pos] and curr % 2 + while (lsa + pos) >= 0 or (lsb + pos) >= 0: + if (lsa + pos) >= 0: + curr += int(a[pos]) + if (lsb + pos) >= 0: + curr += int(b[pos]) + res = str(curr % 2) + res + curr //= 2 + pos -= 1 + if curr == 1: + res = '1' + res + return res diff --git a/python/python/068_Text_Justification.py b/python/python/068_Text_Justification.py new file mode 100644 index 0000000..2166c05 --- /dev/null +++ b/python/python/068_Text_Justification.py @@ -0,0 +1,73 @@ +class Solution(object): + def fullJustify(self, words, maxWidth): + """ + :type words: List[str] + :type maxWidth: int + :rtype: List[str] + """ + res = [] + res_list = [] + curr = [] + count, pos = 0, 0 + while pos < len(words): + word = words[pos] + if len(word) > maxWidth: + pos += 1 + if len(word) + count + len(curr)<= maxWidth: + count += len(word) + curr.append(word) + pos += 1 + else: + res_list.append(curr) + curr = [] + count = 0 + if len(curr) > 0: + res_list.append(curr) + # print res_list + for index, curr in enumerate(res_list): + text = '' + remain = sum([len(t) for t in curr]) + if len(curr) == 1: + # single word + text = curr[0] + ' ' * (maxWidth - remain) + elif index == len(res_list) - 1: + # last line + text = ' '.join(curr) + text += ' ' * (maxWidth - remain - len(curr) + 1) + else: + # multiple + step = (maxWidth - remain) / (len(curr) - 1 ) + extra = (maxWidth - remain) % (len(curr) - 1 ) + for index in range(len(curr) - 1): + text += curr[index] + ' ' * step + if extra > 0: + # assign from left + text += ' ' + extra -= 1 + text += curr[-1] + res.append(text) + return res + + # def fullJustify(self, words, maxWidth): + # i, N, result = 0, len(words), [] + # while i < N: + # # decide how many words to be put in one line + # oneLine, j, currWidth, positionNum, spaceNum = [words[i]], i + 1, len(words[i]), 0, maxWidth - len(words[i]) + # while j < N and currWidth + 1 + len(words[j]) <= maxWidth: + # oneLine.append(words[j]) + # currWidth += 1 + len(words[j]) + # spaceNum -= len(words[j]) + # positionNum, j = positionNum + 1, j + 1 + # i = j + # # decide the layout of one line + # if i < N and positionNum: + # spaces = [' ' * (spaceNum / positionNum + (k < spaceNum % positionNum)) for k in range(positionNum)] + [ + # ''] + # else: # last line or the line only has one word + # spaces = [' '] * positionNum + [' ' * (maxWidth - currWidth)] + # result.append(''.join([s for pair in zip(oneLine, spaces) for s in pair])) + # return result + +if __name__ == '__main__': + s = Solution() + print s.fullJustify(["Don't","go","around","saying","the","world","owes","you","a","living;","the","world","owes","you","nothing;","it","was","here","first."],30) diff --git a/python/python/069_Sqrt(x).py b/python/python/069_Sqrt(x).py new file mode 100644 index 0000000..a697a45 --- /dev/null +++ b/python/python/069_Sqrt(x).py @@ -0,0 +1,35 @@ +class Solution: + # def mySqrt(self, x): + # """ + # :type x: int + # :rtype: int + # """ + # if x == 0: + # return 0 + # low = 0 + # high = x + # last = x + # while high >= low: + # mid = (low + high) / 2 + # temp = mid * mid + # if temp == x: + # return mid + # elif temp < x: + # low = mid + 1 + # last = mid + # else: + # high = mid - 1 + # return last + + def mySqrt(self, x): + # sqrt(x) = 2 * sqrt(x / 4) for n % 4 == 0 + # sqrt(x) = 1 + 2 * sqrt(x / 4) for n % 4 != 0 + if x == 0: + return 0 + if x < 4: + return 1 + res = 2 * self.mySqrt(x / 4) + # (res + 1) * (res + 1) >= 0 for avoiding overflow + if (res + 1) * (res + 1) <= x and (res + 1) * (res + 1) >= 0: + return res + 1 + return res \ No newline at end of file diff --git a/python/python/070_Climbing_Stairs.py b/python/python/070_Climbing_Stairs.py new file mode 100644 index 0000000..fe7ae69 --- /dev/null +++ b/python/python/070_Climbing_Stairs.py @@ -0,0 +1,37 @@ +class Solution(object): + # def climbStairs(self, n): + # """ + # :type n: int + # :rtype: int + # """ + # dp = [0] * (n + 1) + # dp[0] = 1 + # dp[1] = 1 + # for i in range(2, n + 1): + # dp[i] = dp[i - 2] + dp[i- 1] + # return dp[n] + + def climbStairs(self, n): + if n <= 1: + return 1 + dp = [1] * 2 + for i in range(2, n + 1): + dp[1], dp[0] = dp[1] + dp[0], dp[1] + return dp[1] + + + + # C = {1: 1, 2: 2} + # def climbStairs(self, n): + # """ + # :type n: int + # :rtype: int + # """ + # if n in Solution.C: + # return Solution.C[n] + # else: + # result = Solution.C.get(n - 1, self.climbStairs(n - 1)) + \ + # Solution.C.get(n - 2, self.climbStairs(n - 2)) + # Solution.C[n] = result + # return result + diff --git a/python/python/071_Simplify_Path.py b/python/python/071_Simplify_Path.py new file mode 100644 index 0000000..39fa5e2 --- /dev/null +++ b/python/python/071_Simplify_Path.py @@ -0,0 +1,20 @@ +class Solution(object): + def simplifyPath(self, path): + """ + :type path: str + :rtype: str + """ + result = [] + plist = path.split('/') + for pos in plist: + if pos: + if pos == '..': + try: + # up one level + result.pop() + except: + # arrive top level + result = [] + elif pos != '.': + result.append(pos) + return '/'+'/'.join(result) \ No newline at end of file diff --git a/python/python/072_Edit_Distance.py b/python/python/072_Edit_Distance.py new file mode 100644 index 0000000..f1dd491 --- /dev/null +++ b/python/python/072_Edit_Distance.py @@ -0,0 +1,45 @@ +class Solution(object): + # https://discuss.leetcode.com/topic/17639/20ms-detailed-explained-c-solutions-o-n-space/2 + # def minDistance(self, word1, word2): + # """ + # :type word1: str + # :type word2: str + # :rtype: int + # """ + # ls_1, ls_2 = len(word1), len(word2) + # dp = [[0] * (ls_2 + 1) for _ in range(ls_1 + 1)] + # for i in range(1, ls_1 + 1): + # dp[i][0] = i + # for j in range(1, ls_2 + 1): + # dp[0][j] = j + # for i in range(1, ls_1 + 1): + # for j in range(1, ls_2 + 1): + # if word1[i - 1] == word2[j - 1]: + # dp[i][j] = dp[i - 1][j - 1] + # else: + # dp[i][j] = min(dp[i - 1][j - 1] + 1, + # dp[i][j - 1] + 1, + # dp[i - 1][j] + 1) + # return dp[ls_1][ls_2] + + def minDistance(self, word1, word2): + ls_1, ls_2 = len(word1), len(word2) + dp = list(range(ls_1 + 1)) + for j in range(1, ls_2 + 1): + pre = dp[0] + dp[0] = j + for i in range(1, ls_1 + 1): + temp = dp[i] + if word1[i - 1] == word2[j - 1]: + dp[i] = pre + else: + dp[i] = min(pre + 1, dp[i] + 1, dp[i - 1] + 1) + pre = temp + return dp[ls_1] + + + if __name__ == '__main__': + # begin + s = Solution() + print (s.minDistance("horse","ros")) + print (s.minDistance("intention","execution")) diff --git a/python/python/073_Set_Matrix_Zeroes.py b/python/python/073_Set_Matrix_Zeroes.py new file mode 100644 index 0000000..c0e6535 --- /dev/null +++ b/python/python/073_Set_Matrix_Zeroes.py @@ -0,0 +1,29 @@ +class Solution(object): + 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) + if m == 0: + return + r = [] + c = [] + n = len(matrix[0]) + for i in range(m): + for j in range(n): + if matrix[i][j] == 0: + r.append(i) + c.append(j) + # row with zero + r = set(r) + # column with zero + c = set(c) + for i in r: + for j in range(n): + matrix[i][j] = 0 + for i in range(m): + for j in c: + matrix[i][j] = 0 diff --git a/python/python/074_Search_a_2D_Matrix.py b/python/python/074_Search_a_2D_Matrix.py new file mode 100644 index 0000000..8666114 --- /dev/null +++ b/python/python/074_Search_a_2D_Matrix.py @@ -0,0 +1,62 @@ +class Solution(object): + # def searchMatrix(self, matrix, target): + # """ + # :type matrix: List[List[int]] + # :type target: int + # :rtype: bool + # """ + # try: + # ls_row, ls_col = len(matrix), len(matrix[0]) + # except: + # return False + # begin, end = 0, ls_row - 1 + # while begin <= end: + # mid = (begin + end) / 2 + # res = self.search_row(matrix, mid, target) + # if res == 0: + # return True + # elif res < 0: + # end = mid - 1 + # else: + # begin = mid + 1 + # return False + # + # + # def search_row(self, matrix, row, target): + # if target < matrix[row][0]: + # return -1 + # elif target > matrix[row][-1]: + # return 1 + # begin, end = 0, len(matrix[row]) - 1 + # while begin <= end: + # mid = (begin + end) / 2 + # if matrix[row][mid] == target: + # return 0 + # elif matrix[row][mid] < target: + # begin = mid + 1 + # else: + # end = mid - 1 + # return 1 + + + def searchMatrix(self, matrix, target): + # binary search + try: + ls_row, ls_col = len(matrix), len(matrix[0]) + except: + return False + if target < matrix[0][0] or target > matrix[-1][-1]: + return False + begin, end = 0, ls_row * ls_col - 1 + while begin <= end: + mid = (begin + end) / 2 + row, col = mid / ls_col, mid % ls_col + if matrix[row][col] == target: + return True + elif matrix[row][col] > target: + end = mid - 1 + else: + begin = mid + 1 + return False + + diff --git a/python/python/075_Sort_Colors.py b/python/python/075_Sort_Colors.py new file mode 100644 index 0000000..dcb73e5 --- /dev/null +++ b/python/python/075_Sort_Colors.py @@ -0,0 +1,34 @@ +class Solution(object): + # def sortColors(self, nums): + # """ + # :type nums: List[int] + # :rtype: void Do not return anything, modify nums in-place instead. + # """ + # # simple counting sort + # count = [0] * 3 + # for num in nums: + # count[num] += 1 + # pos = 0 + # for index in range(3): + # while count[index] > 0: + # nums[pos] = index + # pos += 1 + # count[index] -= 1 + # return + + def sortColors(self, nums): + # https://leetcode.com/discuss/85658/sharing-c-solution-with-good-explanation + low, mid, high = 0, 0, len(nums) - 1 + while mid <= high: + if nums[mid] == 0: + # swap low mid + nums[low], nums[mid] = nums[mid], nums[low] + low += 1 + mid += 1 + elif nums[mid] == 1: + mid += 1 + else: + # swap mid high + nums[high], nums[mid] = nums[mid], nums[high] + high -= 1 + return diff --git a/python/python/076_Minimum_Window_Substring.py b/python/python/076_Minimum_Window_Substring.py new file mode 100644 index 0000000..88df545 --- /dev/null +++ b/python/python/076_Minimum_Window_Substring.py @@ -0,0 +1,127 @@ +class Solution(object): + # def minWindow(self, s, t): + # """ + # :type s: str + # :type t: str + # :rtype: str + # """ + # letters = set(t) + # ls = len(s) + # + # # find the first substring that works + # first_match = self.first_match(s, t) + # if not first_match: + # return '' + # else: + # start, end, extra = first_match + # min_window = (end - start, start, end) + # + # # traverse the string and update start and end + # while start < end < ls: + # discard = s[start] + # + # # move start on to the next letter + # while start < end: + # start += 1 + # if s[start] in letters: + # break + # + # # if discarded letter has extra, no need update end + # if discard in extra: + # extra[discard] -= 1 + # if extra[discard] == 0: + # extra.pop(discard) + # min_window = min(min_window, (end - start, start, end)) + # continue + # + # # otherwise move end until it points to the discarded letter + # while end < ls: + # end += 1 + # if end == ls: + # continue + # + # letter = s[end] + # if letter == discard: + # min_window = min(min_window, (end - start, start, end)) + # break + # + # if letter in letters: + # extra[letter] += 1 + # + # _, start, end = min_window + # return s[start: end + 1] + # + # def first_match(self, s, t): + # letters = set(t) + # to_find = collections.defaultdict(lambda: 0) + # extra = collections.defaultdict(lambda: 0) + # + # # build hash table + # for i in t: + # to_find[i] += 1 + # + # # find the start position + # for index, letter in enumerate(s): + # if letter in to_find: + # start = index + # break + # else: + # return False + # + # # find the end position + # for index, letter in enumerate(s[start:], start): + # if letter not in letters: + # continue + # if letter in to_find: + # to_find[letter] -= 1 + # if to_find[letter] == 0: + # to_find.pop(letter) + # else: + # extra[letter] += 1 + # if not to_find: + # end = index + # break + # else: + # return False + # return start, end, extra + def minWindow(self, s, t): + # http://articles.leetcode.com/finding-minimum-window-in-s-which/ + ls_s, ls_t = len(s), len(t) + need_to_find = [0] * 256 + has_found = [0] * 256 + min_begin, min_end = 0, -1 + min_window = 100000000000000 + for index in range(ls_t): + need_to_find[ord(t[index])] += 1 + count, begin = 0, 0 + for end in range(ls_s): + end_index = ord(s[end]) + if need_to_find[end_index] == 0: + continue + has_found[end_index] += 1 + if has_found[end_index] <= need_to_find[end_index]: + count += 1 + if count == ls_t: + begin_index = ord(s[begin]) + while need_to_find[begin_index] == 0 or\ + has_found[begin_index] > need_to_find[begin_index]: + if has_found[begin_index] > need_to_find[begin_index]: + has_found[begin_index] -= 1 + begin += 1 + begin_index = ord(s[begin]) + window_ls = end - begin + 1 + if window_ls < min_window: + min_begin = begin + min_end = end + min_window = window_ls + # print min_begin, min_end + if count == ls_t: + return s[min_begin: min_end + 1] + else: + return '' + + +if __name__ == '__main__': + s = Solution() + print s.minWindow('a', 'a') + diff --git a/python/python/077_Combinations.py b/python/python/077_Combinations.py new file mode 100644 index 0000000..431b51a --- /dev/null +++ b/python/python/077_Combinations.py @@ -0,0 +1,43 @@ +class Solution(object): + # def combine(self, n, k): + # """ + # :type n: int + # :type k: int + # :rtype: List[List[int]] + # """ + # res = [] + # candidates = range(1, n + 1) + # self.get_combine(res, candidates, [], k, 0) + # return res + # + # def get_combine(self, res, candidates, prefix, k, start): + # # recursive + # if k == 0: + # res.append(prefix) + # for index in range(start, len(candidates)): + # self.get_combine(res, candidates, + # prefix + [candidates[index]], + # k - 1, index + 1) + + def combine(self, n, k): + res = [] + self.get_combine(res, [], n, k, 1) + return res + + def get_combine(self, res, prefix, n, k, start): + # recursive with only one array + if k == 0: + res.append(list(prefix)) + elif start <= n: + prefix.append(start) + self.get_combine(res, prefix, + n, k - 1, start + 1) + prefix.pop() + self.get_combine(res, prefix, + n, k, start + 1) + + + +if __name__ == "__main__": + s = Solution() + print s.combine(4, 2) \ No newline at end of file diff --git a/python/python/078_Subsets.py b/python/python/078_Subsets.py new file mode 100644 index 0000000..9e3dfc0 --- /dev/null +++ b/python/python/078_Subsets.py @@ -0,0 +1,58 @@ +class Solution(object): + # def subsets(self, nums): + # """ + # :type nums: List[int] + # :rtype: List[List[int]] + # """ + # nums.sort() + # res = [[]] + # res.append(list(nums)) + # for ls in range(1, len(nums)): + # self.get_subsets(res, nums, [], ls, 0) + # return res + # + # def get_subsets(self, res, nums, curr_set, ls, index): + # # recursive + # if ls == 0: + # res.append(list(curr_set)) + # elif index < len(nums): + # curr_set.append(nums[index]) + # self.get_subsets(res, nums, curr_set, ls - 1, index + 1) + # curr_set.pop() + # self.get_subsets(res, nums, curr_set, ls, index + 1) + + # def subsets(self, nums): + # # https://leetcode.com/discuss/89343/c-8-lines-bit-operation + # # doesn't work when len(nums) > 32 + # nums.sort() + # res = [] + # for i in range(1 << len(nums)): + # res.append(self.get_subsets(nums, i)) + # return res + # + # def get_subsets(self, nums, magic): + # res = [] + # for i in range(len(nums)): + # if (1 << i) & magic != 0: + # res.append(nums[i]) + # return res + + def subsets(self, nums): + # Sort and iteratively generate n subset with n-1 subset, O(n^2) and O(2^n) + nums.sort() + res = [[]] + for index in range(len(nums)): + size = len(res) + # use existing subsets to generate new subsets + for j in range(size): + curr = list(res[j]) + curr.append(nums[index]) + res.append(curr) + return res + + + + +if __name__ == "__main__": + s = Solution() + print s.subsets([1,2,3]) diff --git a/python/python/079_Word_Search.py b/python/python/079_Word_Search.py new file mode 100644 index 0000000..eaac7da --- /dev/null +++ b/python/python/079_Word_Search.py @@ -0,0 +1,39 @@ +class Solution(object): + def exist(self, board, word): + """ + :type board: List[List[str]] + :type word: str + :rtype: bool + """ + check_board = [[True] * len(board[0]) for _ in range(len(board))] + for i in range(len(board)): + for j in range(len(board[0])): + if board[i][j] == word[0] and check_board: + check_board[i][j] = False + res = self.check_exist(check_board, board, word, 1, len(word), i, j) + if res: + return True + check_board[i][j] = True + return False + + + def check_exist(self, check_board, board, word, index, ls, row, col): + if index == ls: + return True + for temp in [(0, 1),(0, -1),(1, 0),(-1, 0)]: + curr_row = row + temp[0] + curr_col = col + temp[1] + if curr_row >= 0 and curr_row < len(board) and curr_col >= 0 and curr_col < len(board[0]): + if check_board[curr_row][curr_col] and board[curr_row][curr_col] == word[index]: + check_board[curr_row][curr_col] = False + res = self.check_exist(check_board, board, word, index + 1, len(word), curr_row, curr_col) + if res: + return res + check_board[curr_row][curr_col] = True + return False + + + +if __name__ == "__main__": + s = Solution() + print s.exist(["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaab"], "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") \ No newline at end of file diff --git a/python/python/080_Remove_Duplicates_from_Sorted_Array_II.py b/python/python/080_Remove_Duplicates_from_Sorted_Array_II.py new file mode 100644 index 0000000..b54f7ed --- /dev/null +++ b/python/python/080_Remove_Duplicates_from_Sorted_Array_II.py @@ -0,0 +1,29 @@ +class Solution: + def removeDuplicates(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + if nums is None: + return 0 + length = len(nums) + result = 0 + i = j = 0 + while i < length: + j = i + while j < length: + if nums[j] != nums[i]: + break + j += 1 + if j-i > 2: + length -= j-i-2 + for k in range(j-i-2): + del nums[i] + result += 2 + j = i+2 + else: + result += (j-i) + i = j + return result + + diff --git a/python/python/081_Search_in_Rotated_Sorted_Array_II.py b/python/python/081_Search_in_Rotated_Sorted_Array_II.py new file mode 100644 index 0000000..b8861c3 --- /dev/null +++ b/python/python/081_Search_in_Rotated_Sorted_Array_II.py @@ -0,0 +1,35 @@ +class Solution(object): + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: bool + """ + def get(start, end): + if start > end: + return False + mid = (start + end) / 2 + # handle duplicate + while mid < end and nums[mid + 1] == nums[mid]: + mid += 1 + while start < mid and nums[start + 1] == nums[start]: + start += 1 + if nums[mid] == target: + return True + elif mid == end: + return get(start, mid - 1) + elif start == mid: + return get(mid + 1, end) + elif nums[mid] >= nums[start]: + # First half is sorted + if target >= nums[start] and target < nums[mid]: + return get(start, mid - 1) + else: + return get(mid + 1, end) + elif nums[mid] <= nums[end]: + # Second half is sorted + if target > nums[mid] and target <= nums[end]: + return get(mid + 1, end) + else: + return get(start, mid - 1) + return get(0, len(nums) - 1) \ No newline at end of file diff --git a/python/python/083_Remove_Duplicates_from_Sorted_List.py b/python/python/083_Remove_Duplicates_from_Sorted_List.py new file mode 100644 index 0000000..c64f069 --- /dev/null +++ b/python/python/083_Remove_Duplicates_from_Sorted_List.py @@ -0,0 +1,37 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + # def deleteDuplicates(self, head): + # """ + # :type head: ListNode + # :rtype: ListNode + # """ + # if head is None: + # return None + # temp = ListNode(2147483647) + # temp.next = head + # pos = head + # head = temp + # last = head + # while pos is not None: + # if last.val == pos.val: + # last.next = pos.next + # else: + # last = pos + # pos = pos.next + # return head.next + + def deleteDuplicates(self, head): + if head is None: + return None + pos = head + while pos is not None and pos.next is not None: + if pos.val == pos.next.val: + pos.next = pos.next.next + else: + pos = pos.next + return head diff --git a/python/python/084_Largest_Rectangle_in_Histogram.py b/python/python/084_Largest_Rectangle_in_Histogram.py new file mode 100644 index 0000000..3732ea9 --- /dev/null +++ b/python/python/084_Largest_Rectangle_in_Histogram.py @@ -0,0 +1,29 @@ +class Solution(object): + def largestRectangleArea(self, heights): + """ + :type heights: List[int] + :rtype: int + """ + # https://leetcode.com/discuss/70983/4ms-java-solution-using-o-n-stack-space-o-n-time + largest_rectangle = 0 + ls = len(heights) + # heights[stack[top]] > heights[pos] > heights[stack[top - 1]] + # keep the increase order + stack = [-1] + top, pos = 0, 0 + for pos in range(ls): + while top > 0 and heights[stack[top]] > heights[pos]: + largest_rectangle = max(largest_rectangle, heights[stack[top]] * (pos - stack[top - 1] - 1)) + top -= 1 + stack.pop() + stack.append(pos) + top += 1 + while top > 0: + largest_rectangle = max(largest_rectangle, heights[stack[top]] * (ls - stack[top - 1] - 1)) + top -= 1 + return largest_rectangle + + +if __name__ == "__main__": + s = Solution() + print s.largestRectangleArea([2,1,5,6,2,3]) diff --git a/python/python/085_Maximal_Rectangle.py b/python/python/085_Maximal_Rectangle.py new file mode 100644 index 0000000..90b1845 --- /dev/null +++ b/python/python/085_Maximal_Rectangle.py @@ -0,0 +1,35 @@ +class Solution(object): + def maximalRectangle(self, matrix): + """ + :type matrix: List[List[str]] + :rtype: int + """ + # https://discuss.leetcode.com/topic/6650/share-my-dp-solution/2 + if matrix is None or len(matrix) == 0: + return 0 + ls_row, ls_col = len(matrix), len(matrix[0]) + left, right, height = [0] * ls_col, [ls_col] * ls_col, [0] * ls_col + maxA = 0 + for i in range(ls_row): + curr_left, curr_right = 0, ls_col + for j in range(ls_col): + if matrix[i][j] == '1': + height[j] += 1 + else: + height[j] = 0 + for j in range(ls_col): + if matrix[i][j] == '1': + left[j] = max(left[j], curr_left) + else: + left[j], curr_left = 0, j + 1 + for j in range(ls_col - 1, -1, -1): + if matrix[i][j] == '1': + right[j] = min(right[j], curr_right) + else: + right[j], curr_right = ls_col, j + for j in range(ls_col): + maxA = max(maxA, (right[j] - left[j]) * height[j]) + return maxA + + + diff --git a/python/python/086_Partition_List.py b/python/python/086_Partition_List.py new file mode 100644 index 0000000..6d93341 --- /dev/null +++ b/python/python/086_Partition_List.py @@ -0,0 +1,36 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def partition(self, head, x): + """ + :type head: ListNode + :type x: int + :rtype: ListNode + """ + if head is None: + return None + less = lesshead = None + last = pos = head + while pos is not None: + if pos.val < x: + if lesshead is None: + lesshead = pos + else: + less.next = pos + less = pos + if head == pos: + last = head = pos.next + else: + last.next = pos.next + else: + last = pos + pos = pos.next + if lesshead is not None: + less.next = head + else: + lesshead = head + return lesshead \ No newline at end of file diff --git a/python/python/087_Scramble_String.py b/python/python/087_Scramble_String.py new file mode 100644 index 0000000..238beed --- /dev/null +++ b/python/python/087_Scramble_String.py @@ -0,0 +1,81 @@ +class Solution(object): + #https://discuss.leetcode.com/topic/20094/my-c-solutions-recursion-with-cache-dp-recursion-with-cache-and-pruning-with-explanation-4ms/2 + # def isScramble(self, s1, s2): + # """ + # :type s1: str + # :type s2: str + # :rtype: bool + # """ + # # recursive + # if s1 == s2: + # return True + # if len(s1) != len(s2): + # return False + # ls = len(s1) + # letters = [0] * 26 + # for i in range(ls): + # letters[ord(s1[i]) - ord('a')] += 1 + # letters[ord(s2[i]) - ord('a')] -= 1 + # for i in range(26): + # if letters[i] != 0: + # return False + # for i in range(1, ls): + # if self.isScramble(s1[0:i], s2[0:i]) and self.isScramble(s1[i:], s2[i:]): + # return True + # if self.isScramble(s1[0:i], s2[ls - i:]) and self.isScramble(s1[i:], s2[:ls - i]): + # return True + # return False + + def isScramble(self, s1, s2, memo={}): + # recursive with memo + # Check with sorted is fundamental, otherwise TLE + if len(s1) != len(s2) or sorted(s1) != sorted(s2): + return False + if len(s1) <= len(s2) <= 1: + return s1 == s2 + if s1 == s2: + return True + if (s1, s2) in memo: + return memo[s1, s2] + n = len(s1) + for i in range(1, n): + a = self.isScramble(s1[:i], s2[:i], memo) and self.isScramble(s1[i:], s2[i:], memo) + if not a: + b = self.isScramble(s1[:i], s2[-i:], memo) and self.isScramble(s1[i:], s2[:-i], memo) + if a or b: + memo[s1, s2] = True + return True + memo[s1, s2] = False + return False + + # def isScramble(self, s1, s2): + # # dp TLE + # if s1 == s2: + # return True + # if len(s1) != len(s2): + # return False + # ls = len(s1) + # letters = [0] * 26 + # for i in range(ls): + # letters[ord(s1[i]) - ord('a')] += 1 + # letters[ord(s2[i]) - ord('a')] -= 1 + # for i in range(26): + # if letters[i] != 0: + # return False + # dp = [[[False] * ls for i in range(ls)] for i in range(ls + 1)] + # for i in range(ls): + # for j in range(ls): + # dp[1][i][j] = (s1[i] == s2[j]) + # + # for cur_len in range(2, ls + 1): + # for i in range(ls - cur_len + 1): + # for j in range(ls - cur_len + 1): + # dp[cur_len][i][j] = False + # for k in range(1, cur_len): + # if dp[cur_len][i][j]: + # break + # dp[cur_len][i][j] = dp[cur_len][i][j] or (dp[k][i][j] and dp[cur_len - k][i + k][j + k]) + # dp[cur_len][i][j] = dp[cur_len][i][j] or (dp[k][i + cur_len - k][j] and dp[cur_len - k][i][j + k]) + # return dp[ls][0][0] + + diff --git a/python/python/088_Merge_Sorted_Array.py b/python/python/088_Merge_Sorted_Array.py new file mode 100644 index 0000000..3d650df --- /dev/null +++ b/python/python/088_Merge_Sorted_Array.py @@ -0,0 +1,38 @@ +class Solution(object): + 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. + """ + p1, p2 = m - 1, n - 1 + pos = m + n - 1 + while p1 >= 0 and p2 >= 0: + if nums1[p1] >= nums2[p2]: + nums1[pos] = nums1[p1] + p1 -= 1 + else: + nums1[pos] = nums2[p2] + p2 -= 1 + pos -= 1 + while p2 >= 0: + nums1[pos] = nums2[p2] + p2 -= 1 + pos -= 1 + + # def merge(self, nums1, m, nums2, n): + # # using slicing + # i, j, k = m - 1, n - 1, m + n - 1 + # while i >= 0 and j >= 0: + # if nums1[i] > nums2[j]: + # nums1[k] = nums1[i] + # i -= 1 + # else: + # nums1[k] = nums2[j] + # j -= 1 + # k -= 1 + # + # if j >= 0: + # nums1[:k + 1] = nums2[:j + 1] \ No newline at end of file diff --git a/python/python/089_Gray_Code.py b/python/python/089_Gray_Code.py new file mode 100644 index 0000000..09cff79 --- /dev/null +++ b/python/python/089_Gray_Code.py @@ -0,0 +1,25 @@ +class Solution(object): + def grayCode(self, n): + """ + :type n: int + :rtype: List[int] + """ + # https://leetcode.com/discuss/86617/6-line-java-solution-very-concise + res = [0] + for i in range(n): + for j in reversed(range(len(res))): + res.append(res[j] + (1 << i)) + return res + + + # def count_one(self, num): + # count = 0 + # while num: + # num &= (num - 1) + # count += 1 + # return count + +if __name__ == "__main__": + s = Solution() + print s.grayCode(2) + diff --git a/python/python/090_Subsets_II.py b/python/python/090_Subsets_II.py new file mode 100644 index 0000000..520727c --- /dev/null +++ b/python/python/090_Subsets_II.py @@ -0,0 +1,44 @@ +class Solution(object): + # def subsetsWithDup(self, nums): + # """ + # :type nums: List[int] + # :rtype: List[List[int]] + # """ + # nums.sort() + # res = [] + # for i in range(1 << len(nums)): + # res.append(self.get_subsets(nums, i)) + # # remove duplicate + # final_res = {} + # for subset in res: + # hash_key = ''.join([str(t) for t in subset]) + # try: + # final_res[hash_key] + # except: + # final_res[hash_key] = subset + # return final_res.values() + # + # def get_subsets(self, nums, magic): + # res = [] + # for i in range(len(nums)): + # if (1 << i) & magic != 0: + # res.append(nums[i]) + # return res + + def subsetsWithDup(self, nums): + nums.sort() + res = [[]] + begin = 0 + for index in range(len(nums)): + if index == 0 or nums[index] != nums[index - 1]: + # generate all + begin = 0 + size = len(res) + # use existing subsets to generate new subsets + for j in range(begin, size): + curr = list(res[j]) + curr.append(nums[index]) + res.append(curr) + # avoid duplicate subsets + begin = size + return res diff --git a/python/python/091_Decode_Ways.py b/python/python/091_Decode_Ways.py new file mode 100644 index 0000000..d1515dc --- /dev/null +++ b/python/python/091_Decode_Ways.py @@ -0,0 +1,24 @@ +class Solution(object): + def numDecodings(self, s): + """ + :type s: str + :rtype: int + """ + ls = len(s) + if ls == 0: + return 0 + dp = [0] * ls + for index in range(ls): + if index >= 1 and int(s[index - 1:index + 1]) < 27 and int(s[index - 1:index + 1]) >= 10: + if index == 1: + dp[index] = 1 + else: + # 11-26 + dp[index] += dp[index - 2] + if int(s[index]) != 0: + if index == 0: + dp[index] = 1 + else: + # 1-9 + dp[index] += dp[index - 1] + return dp[ls - 1] diff --git a/python/python/092_Reverse_Linked_Lis_ II.py b/python/python/092_Reverse_Linked_Lis_ II.py new file mode 100644 index 0000000..f66d929 --- /dev/null +++ b/python/python/092_Reverse_Linked_Lis_ II.py @@ -0,0 +1,40 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def reverseBetween(self, head, m, n): + """ + :type head: ListNode + :type m: int + :type n: int + :rtype: ListNode + """ + if m == n: + return head + split_node, prev, curr = None, None, head + count = 1 + while count <= m and curr is not None: + if count == m: + split_node = prev + prev = curr + curr = curr.next + count += 1 + tail, next_node = prev, None + while curr is not None and count <= n: + next_temp = curr.next + curr.next = prev + prev = curr + curr = next_temp + count += 1 + if split_node is not None: + split_node.next = prev + if tail is not None: + tail.next = curr + if m == 1: + return prev + return head + + \ No newline at end of file diff --git a/python/python/093_Restore_IP_Addresses.py b/python/python/093_Restore_IP_Addresses.py new file mode 100644 index 0000000..d6434b0 --- /dev/null +++ b/python/python/093_Restore_IP_Addresses.py @@ -0,0 +1,71 @@ +class Solution(object): + # def restoreIpAddresses(self, s): + # """ + # :type s: str + # :rtype: List[str] + # """ + # ls = len(s) + # if ls == 0 or ls > 12: + # return [] + # if s == '0000': + # return ['0.0.0.0'] + # return self.getremainIP(s, 0, 4) + # + # def getremainIP(self, s, pos, count): + # if count == 1: + # curr = s[pos:] + # if self.isNum(curr): + # return [curr] + # result = [] + # for i in range(pos, pos + 3): + # if i + 1 < len(s): + # prefix = s[pos:i + 1] + # if self.isNum(prefix): + # res = self.getremainIP(s, i + 1, count - 1) + # result.extend([prefix + '.' + t for t in res]) + # return result + # + # def isNum(self, prefix): + # curr = int(prefix) + # if curr > 255: + # return False + # if len(prefix) == 1: + # return True + # if prefix[0] == '0': + # return False + # return True + + def restoreIpAddresses(self, s): + ls = len(s) + if ls == 0 or ls > 12: + return [] + res = [] + for i in range(1, 4): + for j in range(1, 4): + for k in range(1, 4): + m = ls - i - j - k + if m > 0 and m <= 3: + add1 = s[0:i] + add2 = s[i:i + j] + add3 = s[i + j:i + j + k] + add4 = s[i + j + k:] + if self.isValid(add1) and self.isValid(add2) and \ + self.isValid(add3) and self.isValid(add4): + res.append(add1 + '.' + add2 + '.' + add3 + '.' + add4) + return res + + def isValid(self, add): + if len(add) == 1: + return True + if add[0] == '0': + return False + if int(add) <= 255: + return True + return False + + +if __name__ == '__main__': + s = Solution() + # print s.longestValidParentheses(")(((((()())()()))()(()))(") + print s.restoreIpAddresses('25525511135') + diff --git a/python/python/094_Binary_Tree_Inorder_Traversal.py b/python/python/094_Binary_Tree_Inorder_Traversal.py new file mode 100644 index 0000000..08c3aa8 --- /dev/null +++ b/python/python/094_Binary_Tree_Inorder_Traversal.py @@ -0,0 +1,79 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + # def inorderTraversal(self, root): + # """ + # :type root: TreeNode + # :rtype: List[int] + # """ + # # recursively + # res = [] + # self.do_inorderTraversal(res, root) + # return res + # + # def do_inorderTraversal(self, res, curr): + # if curr is None: + # return + # if curr.left is not None: + # self.do_inorderTraversal(res, curr.left) + # res.append(curr.val) + # if curr.right is not None: + # self.do_inorderTraversal(res, curr.right) + + # def inorderTraversal(self, root): + # # iteratively, but break the tree + # res = [] + # if root is None: + # return res + # queue = [root] + # while len(queue) > 0: + # curr = queue.pop(0) + # if curr.left is None and curr.right is None: + # res.append(curr.val) + # else: + # if curr.right is not None: + # queue.insert(0, curr.right) + # curr.right = None + # queue.insert(0, curr) + # if curr.left is not None: + # queue.insert(0, curr.left) + # curr.left = None + # return res + # def inorderTraversal(self, root): + # res = [] + # stack = [] + # while root is not None: + # stack.append(root) + # root = root.left + # while root is None: + # if len(stack) == 0: + # return res + # root = stack.pop() + # res.append(root.val) + # root = root.right + # return res + + def inorderTraversal(self, root): + if root is None: + return [] + res = [] + stack = [root] + while len(stack) > 0: + curr = stack.pop() + if not isinstance(curr, TreeNode): + res.append(curr) + continue + if curr.right is not None: + stack.append(curr.right) + stack.append(curr.val) + if curr.left is not None: + stack.append(curr.left) + return res + + + diff --git a/python/python/095_Unique_Binary_Search_Trees_II.py b/python/python/095_Unique_Binary_Search_Trees_II.py new file mode 100644 index 0000000..f27667f --- /dev/null +++ b/python/python/095_Unique_Binary_Search_Trees_II.py @@ -0,0 +1,36 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def generateTrees(self, n): + """ + :type n: int + :rtype: List[TreeNode] + """ + if n == 0: + return [] + return self.get_trees(1, n) + + def get_trees(self, start, end): + # recursive solve this problem + res = [] + if start > end: + res.append(None) + return res + for i in range(start, end + 1): + lefts = self.get_trees(start, i - 1) + rights = self.get_trees(i + 1, end) + for j in range(len(lefts)): + for k in range(len(rights)): + # root point + root = TreeNode(i) + root.left = lefts[j] + root.right = rights[k] + res.append(root) + return res + + diff --git a/python/python/096_Unique_Binary_Search_Trees.py b/python/python/096_Unique_Binary_Search_Trees.py new file mode 100644 index 0000000..1d288ce --- /dev/null +++ b/python/python/096_Unique_Binary_Search_Trees.py @@ -0,0 +1,14 @@ +class Solution(object): + def numTrees(self, n): + """ + :type n: int + :rtype: int + """ + # https://leetcode.com/discuss/86650/fantastic-clean-java-dp-solution-with-detail-explaination + dp = [0] * (n + 1) + dp[0] = 1 + dp[1] = 1 + for level in range(2, n + 1): + for root in range(1, level + 1): + dp[level] += dp[level - root] * dp[root - 1] + return dp[n] \ No newline at end of file diff --git a/python/python/097_Interleaving_String.py b/python/python/097_Interleaving_String.py new file mode 100644 index 0000000..75070ba --- /dev/null +++ b/python/python/097_Interleaving_String.py @@ -0,0 +1,32 @@ +class Solution(object): + def isInterleave(self, s1, s2, s3): + """ + :type s1: str + :type s2: str + :type s3: str + :rtype: bool + """ + if len(s1) + len(s2) != len(s3): + return False + queue = [(0, 0), (-1, -1)] + visited = set() + isSuccess = False + index = 0 + while len(queue) != 1 or queue[0][0] != -1: + p = queue.pop(0) + if p[0] == len(s1) and p[1] == len(s2): + return True + if p[0] == -1: + queue.append(p) + index += 1 + continue + if p in visited: + continue + visited.add(p) + if p[0] < len(s1): + if s1[p[0]] == s3[index]: + queue.append((p[0] + 1, p[1])) + if p[1] < len(s2): + if s2[p[1]] == s3[index]: + queue.append((p[0], p[1] + 1)) + return False diff --git a/python/python/098_Validate_Binary_Search_Tree.py b/python/python/098_Validate_Binary_Search_Tree.py new file mode 100644 index 0000000..bdb1777 --- /dev/null +++ b/python/python/098_Validate_Binary_Search_Tree.py @@ -0,0 +1,40 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +import sys +class Solution(object): + # def isValidBST(self, root): + # """ + # :type root: TreeNode + # :rtype: bool + # """ + # if root is None: + # return True + # order_list = self.getOrder(root) + # length = len(order_list) + # for i in range(length): + # if (i + 1) < length and order_list[i + 1] <= order_list[i]: + # return False + # return True + # + # def getOrder(self, node): + # result = [] + # if node is None: + # return result + # result.extend(self.getOrder(node.left)) + # result.append(node.val) + # result.extend(self.getOrder(node.right)) + # return result + + def isValidBST(self, root): + return self.isVaild_helper(root, -sys.maxint - 1, sys.maxint) + + def isVaild_helper(self, root, minVal, maxVal): + if root is None: + return True + if root.val >= maxVal or root.val <= minVal: + return False + return self.isVaild_helper(root.left, minVal, root.val) and self.isVaild_helper(root.right, root.val, maxVal) diff --git a/python/python/099_Recover_Binary_Search_Tree.py b/python/python/099_Recover_Binary_Search_Tree.py new file mode 100644 index 0000000..2ebef9e --- /dev/null +++ b/python/python/099_Recover_Binary_Search_Tree.py @@ -0,0 +1,67 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + # def recoverTree(self, root): + # """ + # :type root: TreeNode + # :rtype: void Do not return anything, modify root in-place instead. + # """ + # # https://discuss.leetcode.com/topic/9305/detail-explain-about-how-morris-traversal-finds-two-incorrect-pointer/2 + # pre = first = second = None + # while root is not None: + # if root.left is not None: + # temp = root.left + # while temp.right is not None and temp.right != root: + # temp = temp.right + # if temp.right is not None: + # if pre is not None and pre.val > root.val: + # if first is None: + # first = pre + # second = root + # pre = root + # temp.right = None + # root = root.right + # else: + # temp.right = root + # root = root.left + # else: + # if pre is not None and pre.val > root.val: + # if first is None: + # first = pre + # second = root + # pre = root + # root = root.right + # # only two elements are swapped + # if first is not None and second is not None: + # first.val, second.val = second.val, first.val + + + # https://discuss.leetcode.com/topic/3988/no-fancy-algorithm-just-simple-and-powerful-in-order-traversal/2 + def __init__(self): + self.first = self.second = None + self.pre = TreeNode(-sys.maxint - 1) + + + def recoverTree(self, root): + self.traverse(root) + self.first.val, self.second.val = self.second.val, self.first.val + + def traverse(self, root): + if root is None: + return + self.traverse(root.left) + if self.pre.val >= root.val: + if self.first is None: + self.first = self.pre + if self.first is not None: + self.second = root + self.pre = root + self.traverse(root.right) + + + diff --git a/python/python/100_Same_Tree.py b/python/python/100_Same_Tree.py new file mode 100644 index 0000000..a8d0d39 --- /dev/null +++ b/python/python/100_Same_Tree.py @@ -0,0 +1,25 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSameTree(self, p, q): + """ + :type p: TreeNode + :type q: TreeNode + :rtype: bool + """ + if p == q: + return True + try: + left = right = True + if p.val == q.val: + left = self.isSameTree(p.left, q.left) + right = self.isSameTree(p.right, q.right) + return (left and right) + except: + return False + return False \ No newline at end of file