├── .DS_Store ├── 01TwoSum.py ├── 02Add_Two_Numbers.py ├── 03_Without_Repeating_Characters.py ├── 04_median_two_sorted_arrays.py ├── 05LongestPalindrome.py ├── 06ZigZag.py ├── 07reverse_integer.py ├── 08string2int-2.py ├── 09palindrome_number.py ├── 10REM.py ├── 11water.py ├── 12Integer2Roman.py ├── 13Roman2Integer.py ├── 14Longest_Common_Prefix.py ├── 153Sum.py ├── 16 3SumClosest.py ├── 17lcp.py ├── 184sum.py ├── 19 Remove Nth Node.py ├── 20 Valid Parentheses.py ├── 21merge2sortedlists.py ├── 22GenerateParentheses.py ├── 23mergeksortedlists.py ├── 24swapnodesinpairs.py ├── 25ReverseNodesink-Group.py ├── 26RemoveDuplicatesFromSortedArray.py ├── 27RemoveElement.py ├── 28Implementstr.py ├── 29DivideTwoIntegers.py ├── 30SubstringWithConcatenationOfAllWords.py ├── 31NextPermutation.py ├── 32Longest Valid Parentheses-2.py ├── 32LongestValidParentheses.py ├── 33 SearchinRotated SortedArray.py ├── 34Find First and Last Position of Element in Sorted Array.py ├── 35SearchInsertPosition.py ├── 36ValidSudoku.py ├── 37SudokuSolver.py ├── 382_Linked_List_Random_Node.py ├── 38CountandSay.py ├── 398_Random_Pick_Index.py ├── 39CombinationSum.py ├── 40CombinationSum2.py ├── 41FirstMissingPositve.py ├── 42TrappingRainWater.py ├── 43MultiplyStrings.py ├── 44WildcardMatching.py ├── 45_Jump_Game_II.py ├── 45_explanation_Jump_Game_II .md ├── 470_explain.py ├── 470_implement_rand10_using_rand7.py ├── 478_Generate_Random_Point_in_a_Circle.py ├── 497Random_Point_in_Non-overlapping_Rectangles.py ├── 519_random_flip_matrix.py ├── 528_Random_Pick_with_Weight.py ├── 55_Jump_Game.py ├── 55_explanation_Jump_Game.md ├── 587_Erect_the_Fence.py ├── 710_Random_Pick_with_Blacklist.py ├── 892SurfaceAreaof3DShapes.py ├── 963_Minimum_Area_Rectangle_II.py ├── Exp_470_Expectation calculation.py └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JediXL/LeetCodeByPython/d375a1adb2eea65a44d5f26c1b039e96a1fe2639/.DS_Store -------------------------------------------------------------------------------- /01TwoSum.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution: 3 | def twoSum(self, nums, target): 4 | """ 5 | :type nums: List[int] 6 | :type target: int 7 | :rtype: List[int] 8 | """ 9 | i = 0 10 | while i < len(nums): 11 | if i == len(nums) - 1: 12 | return "No solution here!" 13 | r = target - nums[i] 14 | # Can't use a num twice 15 | num_follow = nums[i + 1:] 16 | if r in num_follow: 17 | return [i, num_follow.index(r) + i + 1] 18 | i = i + 1 19 | 20 | # Test 21 | s = Solution() 22 | output = s.twoSum([3, 3, 6, 0], 6) 23 | print(output) 24 | -------------------------------------------------------------------------------- /02Add_Two_Numbers.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addTwoNumbers(self, l1, l2): 3 | """ 4 | :type l1: ListNode 5 | :type l2: ListNode 6 | :rtype: ListNode 7 | """ 8 | 9 | n = l1 10 | i = 1 11 | num_l1 = 0 12 | # get num of l1 13 | while n: 14 | num_l1 = num_l1 + n.val * i 15 | i = i * 10 16 | n = n.next 17 | 18 | m = l2 19 | j = 1 20 | num_l2 = 0 21 | # get num of l2 22 | while m: 23 | num_l2 = num_l2 + m.val * j 24 | j = j * 10 25 | m = m.next 26 | 27 | str_num = str(num_l1 + num_l2) 28 | str_num = str_num[::-1] 29 | res = list_result = ListNode(0) 30 | 31 | for s in str_num: 32 | list_result.next = ListNode(int(s)) 33 | list_result = list_result.next 34 | return res.next -------------------------------------------------------------------------------- /03_Without_Repeating_Characters.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def lengthOfLongestSubstring(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | 8 | len_s = len(s) 9 | if len_s == 0: 10 | return 0 11 | set_s = set(s) 12 | # get the max_size of sild window 13 | max_len = len(set_s) 14 | max_sub_str = "" 15 | while max_len: 16 | if max_len == 1: 17 | return 1 18 | i = 0 19 | while i + max_len <= len_s: 20 | sub_s = s[i:i + max_len] 21 | set_sub = set(sub_s) 22 | # if there is no repeat in sub string 23 | if len(set_sub) == len(sub_s): 24 | max_sub_str = sub_s 25 | return(len(list(max_sub_str))) 26 | i = i + 1 27 | # adjust the size of window 28 | max_len = max_len - 1 29 | 30 | 31 | str_test = "nfpdmpi" 32 | s = Solution() 33 | len_s = s.lengthOfLongestSubstring(str_test) 34 | print(len_s) 35 | -------------------------------------------------------------------------------- /04_median_two_sorted_arrays.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findMedianSortedArrays(self, nums1, nums2): 3 | """ 4 | :type nums1: List[int] 5 | :type nums2: List[int] 6 | :rtype: float 7 | """ 8 | nums = nums1 + nums2 9 | nums.sort() 10 | size = len(nums) 11 | 12 | if size % 2 == 1: 13 | return nums[size // 2] 14 | 15 | if size % 2 == 0: 16 | return (nums[size // 2] + nums[size // 2 - 1]) / 2 17 | 18 | 19 | s = Solution() 20 | print(s.findMedianSortedArrays([1, 3], [2])) 21 | -------------------------------------------------------------------------------- /05LongestPalindrome.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestPalindrome(self, s): 3 | """ 4 | :type s: str 5 | :rtype: str 6 | """ 7 | s = s 8 | mlen = len(s) 9 | while True: 10 | i = 0 11 | while i + mlen <= len(s): 12 | sl = s[i:i + mlen] 13 | sr = sl[::-1] 14 | if sl == sr: 15 | return sl 16 | i = i + 1 17 | mlen = mlen - 1 18 | if mlen == 0: 19 | return "No solution" 20 | 21 | 22 | test_str = "abcbd" 23 | s = Solution() 24 | print(s.longestPalindrome(test_str)) 25 | -------------------------------------------------------------------------------- /06ZigZag.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def convert(self, s, numRows): 3 | """ 4 | :type s: str 5 | :type numRows: int 6 | :rtype: str 7 | """ 8 | if numRows == 1: 9 | return(s) 10 | zlist = [] 11 | sc = "" 12 | n = numRows 13 | while n: 14 | zlist.append([]) 15 | n = n - 1 16 | j = 0 17 | for a in s: 18 | if j == 0: 19 | coverse = False 20 | 21 | zlist[j].append(a) 22 | if j + 1 < numRows: 23 | if coverse: 24 | j = j - 1 25 | else: 26 | j = j + 1 27 | else: 28 | j = j - 1 29 | coverse = True 30 | 31 | for z in zlist: 32 | for t in z: 33 | sc = sc + t 34 | return(sc) 35 | 36 | 37 | s = Solution() 38 | print(s.convert('ABC', 1)) 39 | -------------------------------------------------------------------------------- /07reverse_integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverse(self, x): 3 | """ 4 | :type x: int 5 | :rtype: int 6 | """ 7 | 8 | sx = str(x) 9 | if len(sx) == 1: 10 | return x 11 | sx = sx[::-1] 12 | if sx[0] == '0': 13 | sx = sx[1:] 14 | if sx[-1] == '-': 15 | sx = sx[:-1] 16 | sx = '-' + sx 17 | 18 | rev_int = int(sx) 19 | if rev_int <= 2 ** 31 - 1 and rev_int >= -(2 ** 31): 20 | return rev_int 21 | else: 22 | return 0 23 | 24 | 25 | # test: 26 | s = Solution() 27 | print(s.reverse(120)) 28 | -------------------------------------------------------------------------------- /08string2int-2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def myAtoi(self, str): 3 | """ 4 | :type str: str 5 | :rtype: int 6 | """ 7 | raw_str = str 8 | # set of valid 9 | valid_set = { 10 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', ' ' 11 | } 12 | # set of num 13 | num_set = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} 14 | # set of sign 15 | sign_set = {'+', '-'} 16 | # set of space 17 | 18 | k = 0 # current location 19 | m = 0 # the number of signs 20 | p = 0 # the last space location 21 | n = 0 # the last signs location 22 | i = 0 # the number of 'num' 23 | 24 | temp_str = '' 25 | 26 | # case1: str is Null 27 | if len(raw_str) == 0: 28 | return 0 29 | 30 | # case2: illegal words at begining 31 | if raw_str[0] not in valid_set: 32 | return 0 33 | 34 | for s in raw_str: 35 | if s in sign_set: 36 | # the sign after num is not valid 37 | if i > 0: 38 | break 39 | 40 | m = m + 1 41 | n = k 42 | # case3: if there are more than 1 signs 43 | if m > 1: 44 | return 0 45 | if s == ' ': 46 | # the space after num is not valid 47 | if i > 0: 48 | break 49 | p = k 50 | 51 | if s in num_set: 52 | # case4: if the last sign location before last space location 53 | if p > n and m > 0: 54 | return 0 55 | i = i + 1 56 | temp_str = temp_str + s 57 | 58 | if s not in valid_set: 59 | k = k + 1 60 | break 61 | 62 | k = k + 1 63 | 64 | # case5: have no number in str: 65 | if i == 0: 66 | return 0 67 | else: 68 | # the num with sign 69 | if m > 0: 70 | temp_str = raw_str[n] + temp_str 71 | 72 | covert_int = int(temp_str) 73 | 74 | # overflow 75 | if covert_int >= 2**31 - 1: 76 | return 2**31 - 1 77 | if covert_int <= (-2**31): 78 | return (-2**31) 79 | 80 | return covert_int 81 | 82 | 83 | # test 84 | s = Solution() 85 | print(s.myAtoi("-42")) 86 | -------------------------------------------------------------------------------- /09palindrome_number.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self, x): 3 | """ 4 | :type x: int 5 | :rtype: bool 6 | """ 7 | int_r = x 8 | str_r = str(int_r) 9 | if str_r == str_r[::-1]: 10 | return True 11 | else: 12 | return False 13 | 14 | def isPalindrome2(self, x): 15 | """ 16 | :type x: int 17 | :rtype: bool 18 | """ 19 | int_r = x 20 | if int_r < 0: 21 | return False 22 | 23 | list_t = [] 24 | while int_r: 25 | list_t.append(int_r % 10) 26 | int_r = int_r // 10 27 | 28 | if list_t == list_t[::-1]: 29 | return True 30 | else: 31 | return False 32 | 33 | 34 | 35 | s = Solution() 36 | print(s.isPalindrome2(121)) 37 | -------------------------------------------------------------------------------- /10REM.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isMatch(self, s, p): 3 | """ 4 | :type s: str 5 | :type p: str 6 | :rtype: bool 7 | """ 8 | in_str = s 9 | pt = p 10 | 11 | if not pt: 12 | return not in_str 13 | 14 | first_match = bool(in_str) and pt[0] in {in_str[0], '.'} 15 | # 如果之后是*,那么直接从*之后开始匹配 16 | if len(pt) >= 2 and pt[1] == '*': 17 | # 从左往右,and 的优先级高于 or 18 | return (self.isMatch(in_str, pt[2:]) 19 | or first_match and self.isMatch(in_str[1:], pt)) 20 | else: 21 | return first_match and self.isMatch(in_str[1:], pt[1:]) 22 | 23 | 24 | s = Solution() 25 | print(s.isMatch("ab", "c*ab")) 26 | -------------------------------------------------------------------------------- /11water.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxArea(self, height): 3 | """ 4 | :type height: List[int] 5 | :rtype: int 6 | """ 7 | height_list = height 8 | len_height = len(height_list) 9 | if len_height < 2: 10 | return 0 11 | max_area = 0 12 | i = 0 13 | j = len_height - 1 14 | while i != j: 15 | h = min(height_list[i], height_list[j]) 16 | w = j - i 17 | if max_area < h * w: 18 | max_area = h * w 19 | if height_list[i] < height_list[j]: 20 | i = i + 1 21 | else: 22 | j = j - 1 23 | 24 | return max_area -------------------------------------------------------------------------------- /12Integer2Roman.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Created on: Saturday, September 01, 2018 4 | @author: Jedi Liu 5 | 6 | ''' 7 | 8 | 9 | class Solution: 10 | def intToRoman(self, num): 11 | """ 12 | :type num: int 13 | :rtype: str 14 | """ 15 | n = num 16 | roman = '' 17 | 18 | m = n // 1000 19 | if m > 0: 20 | n = n - m * 1000 21 | while m > 0: 22 | m = m - 1 23 | roman = roman + 'M' 24 | 25 | c = n // 100 26 | if c > 0: 27 | if c == 9: 28 | n = n - 900 29 | roman = roman + 'CM' 30 | elif c >= 5: 31 | n = n - 500 32 | roman = roman + 'D' 33 | c = c - 5 34 | n = n - c * 100 35 | while c > 0: 36 | c = c - 1 37 | roman = roman + 'C' 38 | elif c == 4: 39 | n = n - 400 40 | roman = roman + 'CD' 41 | elif c > 0: 42 | n = n - c * 100 43 | while c > 0: 44 | c = c - 1 45 | roman = roman + 'C' 46 | 47 | x = n // 10 48 | if x > 0: 49 | if x == 9: 50 | n = n - 90 51 | roman = roman + 'XC' 52 | elif x >= 5: 53 | n = n - 50 54 | roman = roman + 'L' 55 | x = x - 5 56 | n = n - x * 10 57 | while x > 0: 58 | x = x - 1 59 | roman = roman + 'X' 60 | elif x == 4: 61 | n = n - 40 62 | roman = roman + 'XL' 63 | elif x > 0: 64 | n = n - x * 10 65 | while x > 0: 66 | x = x - 1 67 | roman = roman + 'X' 68 | 69 | if n == 9: 70 | roman = roman + 'IX' 71 | elif n >= 5: 72 | n = n - 5 73 | roman = roman + 'V' 74 | while n > 0: 75 | n = n - 1 76 | roman = roman + 'I' 77 | elif n == 4: 78 | roman = roman + 'IV' 79 | else: 80 | while n > 0: 81 | roman = roman + 'I' 82 | n = n - 1 83 | return roman 84 | 85 | 86 | class Solution1: 87 | def intToRoman(self, num): 88 | """ 89 | :type num: int 90 | :rtype: str 91 | """ 92 | n = num 93 | roman = "" 94 | div = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] 95 | romans = [ 96 | "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", 97 | "I" 98 | ] 99 | while n != 0: 100 | for i in range(len(div)): 101 | d = div[i] 102 | times = n // d 103 | if times != 0: 104 | roman = roman + (times) * romans[i] 105 | n = n - d * times 106 | return roman 107 | 108 | 109 | s = Solution1() 110 | print(s.intToRoman(27)) 111 | -------------------------------------------------------------------------------- /13Roman2Integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def romanToInt(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | roman = s 8 | num = 0 9 | rlen = len(roman) 10 | 11 | if rlen == 0: 12 | return 0 13 | 14 | i = 0 15 | while i < rlen: 16 | if roman[i] == "M": 17 | num = num + 1000 18 | i = i + 1 19 | continue 20 | 21 | if roman[i] == "C": 22 | if i + 1 < rlen: 23 | if roman[i+1] == "M": 24 | num = num + 900 25 | i = i + 2 26 | continue 27 | elif roman[i+1] == "D": 28 | num = num + 400 29 | i = i + 2 30 | continue 31 | else: 32 | num = num + 100 33 | i = i + 1 34 | continue 35 | else: 36 | num = num + 100 37 | i = i + 1 38 | continue 39 | 40 | if roman[i] == "D": 41 | num = num + 500 42 | i = i + 1 43 | continue 44 | 45 | if roman[i] == "X": 46 | if i + 1 < rlen: 47 | if roman[i+1] == "C": 48 | num = num + 90 49 | i = i + 2 50 | continue 51 | elif roman[i+1] == "L": 52 | num = num + 40 53 | i = i + 2 54 | continue 55 | else: 56 | num = num + 10 57 | i = i + 1 58 | continue 59 | else: 60 | num = num + 10 61 | i = i + 1 62 | continue 63 | 64 | if roman[i] == "L": 65 | num = num + 50 66 | i = i + 1 67 | continue 68 | 69 | if roman[i] == "I": 70 | if i + 1 < rlen: 71 | if roman[i+1] == "X": 72 | num = num + 9 73 | i = i + 2 74 | continue 75 | elif roman[i+1] == "V": 76 | num = num + 4 77 | i = i + 2 78 | continue 79 | else: 80 | num = num + 1 81 | i = i + 1 82 | continue 83 | else: 84 | num = num + 1 85 | i = i + 1 86 | continue 87 | 88 | if roman[i] == "V": 89 | num = num + 5 90 | i = i + 1 91 | continue 92 | return num 93 | 94 | 95 | class Solution1: 96 | def romanToInt(self, s): 97 | """ 98 | :type s: str 99 | :rtype: int 100 | """ 101 | roman_id = { 102 | 'I': 1, 103 | 'V': 5, 104 | 'X': 10, 105 | 'L': 50, 106 | 'C': 100, 107 | 'D': 500, 108 | 'M': 1000, 109 | } 110 | c = 0 111 | num = 0 112 | 113 | for i in range(len(s) - 1, -1, -1): 114 | j = roman_id[s[i]] 115 | # 如果当前字符小于上次迭代的字符,那么属于特殊请求(e.g.,CD,IV..) 116 | if j < c: 117 | num -= j 118 | # 否则直接相加 119 | if j >= c: 120 | num += j 121 | c = j 122 | return num 123 | 124 | 125 | s = Solution1() 126 | print(s.romanToInt("MCDLXXVI")) -------------------------------------------------------------------------------- /14Longest_Common_Prefix.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestCommonPrefix(self, strs): 3 | """ 4 | :type strs: List[str] 5 | :rtype: str 6 | """ 7 | 8 | if not strs: 9 | return "" 10 | 11 | # 找到最短的字符串 12 | shorest = min(strs, key=len) 13 | 14 | for i_th, letter in enumerate(shorest): 15 | 16 | for other in strs: 17 | 18 | if other[i_th] != letter: 19 | 20 | return shorest[:i_th] 21 | 22 | return shorest 23 | 24 | 25 | s = Solution() 26 | print("here is longest prefix:", 27 | s.longestCommonPrefix(['flow', 'flower', 'flight'])) 28 | -------------------------------------------------------------------------------- /153Sum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | class Solution(object): 4 | def threeSum(self, nums): 5 | """ 6 | :type nums: List[int] 7 | :rtype: List[List[int]] 8 | """ 9 | nums.sort() 10 | L, res = len(nums), [] 11 | for i in range(L-2): 12 | if i > 0 and nums[i] == nums[i-1]: 13 | continue 14 | target = -1 * nums[i] 15 | j,k = i + 1, L - 1 16 | while j= target: 16 | return sum(nums[:3]) 17 | # 如果最大的和小于目标,那返回最大的和 18 | if sum(nums[-3:]) <= target: 19 | return sum(nums[-3:]) 20 | 21 | cur = nums[0] + nums[1] + nums[-1] 22 | 23 | for i in range(0, len(nums) - 2): 24 | # 避免重复计算 25 | if i > 0 and nums[i] == nums[i - 1]: 26 | continue 27 | j = i + 1 28 | k = len(nums) - 1 29 | 30 | while j < k: 31 | res = nums[i] + nums[j] + nums[k] 32 | if abs(res - target) < abs(cur - target): 33 | cur = res 34 | elif res == target: 35 | return target 36 | elif res < target: 37 | j = j + 1 38 | else: 39 | k = k - 1 40 | return cur 41 | -------------------------------------------------------------------------------- /17lcp.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def letterCombinations(self, digits): 3 | 4 | """ 5 | :type digits: str 6 | :rtype: List[str] 7 | """ 8 | if not digits: 9 | return [] 10 | 11 | type_dic = { 12 | "2": "abc", 13 | "3": "def", 14 | "4": "ghi", 15 | "5": "jkl", 16 | "6": "mno", 17 | "7": "pqrs", 18 | "8": "tuv", 19 | "9": "wxyz" 20 | } 21 | 22 | res = [""] 23 | 24 | for d in digits: 25 | temp = [] 26 | if d in type_dic.keys(): 27 | for c in type_dic[d]: 28 | for r in res: 29 | temp.append(r + c) 30 | res = temp 31 | 32 | return res 33 | # test here 34 | s1 = Solution() 35 | print(s1.letterCombinations("23")) 36 | -------------------------------------------------------------------------------- /184sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def fourSum(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: List[List[int]] 7 | """ 8 | nums = sorted(nums) 9 | res = [] 10 | 11 | if not nums or len(nums) < 4: 12 | return res 13 | 14 | if nums[0] + nums[1] + nums[2] + nums[3] > target: 15 | return res 16 | 17 | if nums[-1] + nums[-2] + nums[-3] + nums[-4] < target: 18 | return res 19 | 20 | for i in range(0, len(nums)): 21 | # if nums[i] == nums[i - 1] and i > 0: 22 | # continue 23 | if nums[i] + nums[-1] + nums[-2] + nums[-3] < target: 24 | continue 25 | for j in range(i + 1, len(nums) - 2): 26 | # if nums[j] == nums[j-1] and j > 1: 27 | # continue 28 | if nums[i] + nums[j] + nums[-2] + nums[-1] < target: 29 | continue 30 | x = j + 1 31 | y = len(nums) - 1 32 | while x < y: 33 | if nums[i] + nums[j] + nums[x] + nums[y] == target: 34 | res.append([nums[i], nums[j], nums[x], nums[y]]) 35 | x = x + 1 36 | while x < y and nums[x] == nums[x - 1]: 37 | x = x + 1 38 | elif nums[i] + nums[j] + nums[x] + nums[y] < target: 39 | x = x + 1 40 | else: 41 | y = y - 1 42 | 43 | sl = [] 44 | for r in res: 45 | if r not in sl: 46 | sl.append(r) 47 | return sl 48 | 49 | 50 | class Solution1: 51 | def fourSum(self, nums, target): 52 | """ 53 | :type nums: List[int] 54 | :type target: int 55 | :rtype: List[List[int]] 56 | """ 57 | nums.sort() 58 | results = [] 59 | self.findNsum(nums, target, 4, [], results) 60 | return results 61 | 62 | def findNsum(self, nums, target, N, result, results): 63 | if len(nums) < N or N < 2: 64 | return 65 | # solve 2-sum 66 | if N == 2: 67 | l, r = 0, len(nums) - 1 68 | while l < r: 69 | if nums[l] + nums[r] == target: 70 | results.append(result + [nums[l], nums[r]]) 71 | l += 1 72 | r -= 1 73 | while l < r and nums[l] == nums[l - 1]: 74 | l += 1 75 | while r > l and nums[r] == nums[r + 1]: 76 | r -= 1 77 | elif nums[l] + nums[r] < target: 78 | l += 1 79 | else: 80 | r -= 1 81 | else: 82 | for i in range(0, len(nums) - N + 1): # careful about range 83 | if target < nums[i] * N or target > nums[-1] * N: # take advantages of sorted list 84 | break 85 | if i == 0 or i > 0 and nums[i - 1] != nums[i]: # recursively reduce N 86 | self.findNsum(nums[i + 1:], target - nums[i], N - 1, 87 | result + [nums[i]], results) 88 | return 89 | 90 | 91 | s = Solution1() 92 | print(s.fourSum([-3, -2, -1, 0, 0, 1, 2, 3], 0)) 93 | -------------------------------------------------------------------------------- /19 Remove Nth Node.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | 8 | class Solution: 9 | def removeNthFromEnd(self, head, n): 10 | """ 11 | :type head: ListNode 12 | :type n: int 13 | :rtype: ListNode 14 | """ 15 | 16 | node_list = [] 17 | while head: 18 | node_list.append(head) 19 | if head.next is None: 20 | break 21 | else: 22 | head = head.next 23 | 24 | if len(node_list) == 1: 25 | return None 26 | 27 | elif len(node_list) == n: 28 | node_list.pop(0) 29 | return node_list[0] 30 | 31 | 32 | n = 0 - n 33 | node_list[n - 1].next = node_list[n].next 34 | # if node_list[n - 1]: 35 | # if node_list[n + 1]: 36 | # node_list[n - 1].next = node_list[n + 1] 37 | # else: 38 | # node_list[n + 1].next = None 39 | node_list.pop(n) 40 | return node_list[0] 41 | 42 | head = ListNode(1) 43 | head.next = ListNode(2) 44 | head.next.next = ListNode(3) 45 | head.next.next.next = ListNode(4) 46 | head.next.next.next.next = ListNode(5) 47 | 48 | 49 | class Solution1: 50 | def removeNthFromEnd(self, head, n): 51 | """ 52 | :type head: ListNode 53 | :type n: int 54 | :rtype: ListNode 55 | """ 56 | head0 = ListNode(0) 57 | head0.next = head 58 | 59 | runner = head0 60 | walker = head0 61 | 62 | for i in range(n): 63 | runner = runner.next 64 | 65 | while runner.next: 66 | walker = walker.next 67 | runner = runner.next 68 | 69 | node = walker.next 70 | walker.next = node.next 71 | node.next = None 72 | return head0.next 73 | 74 | 75 | s = Solution1() 76 | head = s.removeNthFromEnd(head, 2) 77 | 78 | while head: 79 | print(head.val) 80 | if head.next is None: 81 | break 82 | else: 83 | head = head.next -------------------------------------------------------------------------------- /20 Valid Parentheses.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | 3 | def isValid(self, s): 4 | """ 5 | :type s: str 6 | :rtype: bool 7 | """ 8 | 9 | # s with odd length is not valid 10 | l = len(s) 11 | if l % 2 != 0: 12 | return False 13 | 14 | p = {"(": 1.1, ")": -1.1, "{": 2.22, "}": -2.22, "[": 3.333, "]": -3.333} 15 | num = [0] 16 | 17 | for c in s: 18 | if num[-1] + p[c] == 0: 19 | num.pop() 20 | else: 21 | num.append(p[c]) 22 | 23 | if len(num) != 1: 24 | return False 25 | else: 26 | return True 27 | 28 | 29 | # while '[]' in s or '()' in s or '{}' in s: 30 | # s = s.replace('[]', '').replace('()', '').replace('{}', '') 31 | 32 | # return not len(s) 33 | 34 | s = Solution() 35 | print(s.isValid("([)]")) 36 | -------------------------------------------------------------------------------- /21merge2sortedlists.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | 8 | class Solution: 9 | def mergeTwoLists(self, l1, l2): 10 | """ 11 | :type l1: ListNode 12 | :type l2: ListNode 13 | :rtype: ListNode 14 | """ 15 | if l1 is None and l2 is None: 16 | return None 17 | elif l1 is not None and l2 is None: 18 | return l1 19 | elif l2 is not None and l1 is None: 20 | return l2 21 | 22 | 23 | l = [] 24 | while l1 is not None: 25 | l.append(l1.val) 26 | l1 = l1.next 27 | while l2 is not None: 28 | l.append(l2.val) 29 | l2 = l2.next 30 | 31 | l = sorted(l) 32 | new_l = ListNode(l[0]) 33 | head_l = new_l 34 | for i in range(1,len(l)): 35 | new_l.next = ListNode(l[i]) 36 | new_l = new_l.next 37 | new_l.next = None 38 | return head_l 39 | -------------------------------------------------------------------------------- /22GenerateParentheses.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def generateParenthesis(self, n): 3 | """ 4 | :type n: int 5 | :rtype: List[str] 6 | """ 7 | # ans = [] 8 | # if n <= 0: 9 | # return ans 10 | 11 | # if n == 1: 12 | # return ["()"] 13 | 14 | # ans.append("()") 15 | 16 | # k = 1 17 | # for j in range(1, n): 18 | # if n % j == 0: 19 | # k = j 20 | 21 | # for i in range(1, n + 1): 22 | # for a in ans: 23 | # if len(a) < 2*n: 24 | # if a + "()" != "()" + a: 25 | # m = int(len(a) / 2) 26 | # ans.append(a[:m] + "()" + a[m:]) 27 | # ans.append("(" + a + ")") 28 | # ans.append(a + "()") 29 | # ans.append("()" + a) 30 | # ans.remove(a) 31 | # elif a + "()" == "()" + a: 32 | # m = int(len(a) / 2) 33 | # ans.append(a[:m] + "()" + a[m:]) 34 | # ans.append("(" + a + ")") 35 | # ans.append("()" + a) 36 | # ans.remove(a) 37 | 38 | # # for a in ans: 39 | # # if len(a) != 2*n: 40 | # # ans.remove(a) 41 | # temp = "(" * k + ")" * k 42 | # temp = temp * k 43 | # ans.append(temp) 44 | # for a in ans: 45 | # if len(a) < 2*n: 46 | # ans.remove(a) 47 | # ans = list(set(ans)) 48 | # return ans 49 | ans = [] 50 | 51 | def backtrack(S='', left=0, right=0): 52 | if len(S) == 2 * n: 53 | ans.append(S) 54 | return 55 | if left < n: 56 | backtrack(S+'(', left+1, right) 57 | if right < left: 58 | backtrack(S+')', left, right+1) 59 | 60 | backtrack() 61 | return ans 62 | 63 | 64 | s = Solution() 65 | print(s.generateParenthesis(4)) 66 | -------------------------------------------------------------------------------- /23mergeksortedlists.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | 8 | class Solution: 9 | def mergeKLists(self, lists): 10 | """ 11 | :type lists: List[ListNode] 12 | :rtype: ListNode 13 | """ 14 | temp_list = [] 15 | ans = [] 16 | 17 | #剔除为空的list 18 | for r in lists: 19 | if r != []: 20 | temp_list.append(r) 21 | 22 | lists = temp_list 23 | 24 | if len(lists) == 0: 25 | return [] 26 | 27 | for l in lists: 28 | while l is not None: 29 | ans.append(l) 30 | l = l.next 31 | 32 | if len(ans) == 0: 33 | return [] 34 | 35 | ans = sorted(ans, key=lambda n: n.value) 36 | # 小心索引上界 37 | for i in range(0, len(ans) - 1): 38 | ans[i].next = ans[i + 1] 39 | 40 | return ans[0] 41 | 42 | 43 | 44 | s = Solution() 45 | print(s.mergeKLists([[]])) 46 | -------------------------------------------------------------------------------- /24swapnodesinpairs.py: -------------------------------------------------------------------------------- 1 | 2 | class ListNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | 8 | class Solution: 9 | def swapPairs(self, head): 10 | """ 11 | :type head: ListNode 12 | :rtype: ListNode 13 | """ 14 | if head is None: 15 | return None 16 | 17 | if head.next is None: 18 | return head 19 | 20 | temp = [] 21 | 22 | while head is not None: 23 | temp.append(head.val) 24 | head = head.next 25 | i = 0 26 | while i + 1 < len(temp): 27 | t = temp[i] 28 | temp[i] = temp[i + 1] 29 | temp[i + 1] = t 30 | i = i + 2 31 | 32 | h = ListNode(temp[0]) 33 | c = ListNode(temp[1]) 34 | h.next = c 35 | for j in range(2,len(temp)): 36 | node = ListNode(temp[j]) 37 | c.next = node 38 | c = c.next 39 | 40 | head = ListNode(1) 41 | head.next = ListNode(2) 42 | head.next.next = ListNode(3) 43 | head.next.next.next = ListNode(4) 44 | s = Solution() 45 | new_head = s.swapPairs(head) 46 | while new_head is not None: 47 | print(new_head.val) 48 | new_head = new_head.next 49 | -------------------------------------------------------------------------------- /25ReverseNodesink-Group.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | 8 | class Solution: 9 | def reverseKGroup(self, head, k): 10 | """ 11 | :type head: ListNode 12 | :type k: int 13 | :rtype: ListNode 14 | """ 15 | if head is None or head.next is None or k == 1: 16 | return head 17 | 18 | temp = [] 19 | reverse_list = [] 20 | 21 | while head is not None: 22 | temp.append(head.val) 23 | head = head.next 24 | 25 | if k == len(temp): 26 | temp.reverse() 27 | cur = ListNode(temp[0]) 28 | head = cur 29 | cur = ListNode(temp[1]) 30 | head.next = cur 31 | for j in range(2, len(temp)): 32 | cur.next = ListNode(temp[j]) 33 | cur = cur.next 34 | 35 | return head 36 | 37 | 38 | i = 0 39 | while i + k <= len(temp): 40 | re_temp = temp[i:i + k] 41 | re_temp.reverse() 42 | for t in re_temp: 43 | reverse_list.append(t) 44 | i = i + k 45 | 46 | for t in temp[i:]: 47 | reverse_list.append(t) 48 | 49 | cur = ListNode(reverse_list[0]) 50 | head = cur 51 | cur = ListNode(reverse_list[1]) 52 | head.next = cur 53 | for j in range(2, len(reverse_list)): 54 | cur.next = ListNode(reverse_list[j]) 55 | cur = cur.next 56 | 57 | return head 58 | 59 | 60 | head = ListNode(1) 61 | head.next = ListNode(2) 62 | head.next.next = ListNode(3) 63 | head.next.next.next = ListNode(4) 64 | # head.next.next.next.next = ListNode(5) 65 | 66 | s = Solution() 67 | s.reverseKGroup(head, 2) 68 | -------------------------------------------------------------------------------- /26RemoveDuplicatesFromSortedArray.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeDuplicates(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | if len(nums) == 0 or len(nums) == 1: 8 | return len(nums) 9 | i = 1 10 | while i < len(nums): 11 | if nums[i] == nums[i-1]: 12 | nums.remove(nums[i]) 13 | continue 14 | i = i + 1 15 | 16 | return len(nums) 17 | 18 | 19 | class Solution2: 20 | def removeDuplicates(self, nums): 21 | """ 22 | :type nums: List[int] 23 | :rtype: int 24 | """ 25 | l = sorted(list(set(nums))) 26 | if len(l): 27 | for i in range(0, len(l)): 28 | nums[i] = l[i] 29 | return len(l) 30 | 31 | 32 | 33 | 34 | s = Solution2() 35 | print(s.removeDuplicates([1, 1, 2])) 36 | -------------------------------------------------------------------------------- /27RemoveElement.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeElement(self, nums, val): 3 | """ 4 | :type nums: List[int] 5 | :type val: int 6 | :rtype: int 7 | """ 8 | if not len(nums): 9 | return 0 10 | 11 | i = 0 12 | while i < len(nums): 13 | if nums[i] == val: 14 | nums.remove(nums[i]) 15 | else: 16 | i = i + 1 17 | 18 | return len(nums) 19 | 20 | 21 | -------------------------------------------------------------------------------- /28Implementstr.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def strStr(self, haystack, needle): 3 | """ 4 | :type haystack: str 5 | :type needle: str 6 | :rtype: int 7 | """ 8 | 9 | if haystack == needle: 10 | return 0 11 | 12 | i = 0 13 | needle_len = len(needle) 14 | while i + needle_len <= len(haystack): 15 | if haystack[i:i + needle_len] == needle: 16 | return i 17 | else: 18 | i = i + 1 19 | 20 | return -1 21 | 22 | 23 | s = Solution() 24 | s.strStr("mississippi", "pi") 25 | -------------------------------------------------------------------------------- /29DivideTwoIntegers.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Solution: 4 | def divide(self, dividend, divisor): 5 | """ 6 | :type dividend: int 7 | :type divisor: int 8 | :rtype: 9 | 10 | """ 11 | res = 0 12 | if dividend == 0: 13 | return res 14 | 15 | # 初始化 16 | i = 0 17 | res = 0 18 | p = abs(dividend) 19 | q = abs(divisor) 20 | 21 | # 移位对齐被除数的最左端 22 | while q << i <= p: 23 | i = i + 1 24 | 25 | # 利用二进制进行除法运算 26 | for j in reversed(range(i)): 27 | if q << j <= p: 28 | p = p - (q << j) 29 | res = res + (1 << j) 30 | 31 | # 内存限制 32 | if (dividend > 0) != (divisor > 0) or res < -1 << 31: 33 | res = -res 34 | 35 | return min(res, (1 << 31) - 1) 36 | 37 | 38 | s = Solution() 39 | print(s.divide(120, 13)) 40 | -------------------------------------------------------------------------------- /30SubstringWithConcatenationOfAllWords.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findSubstring(self, s, words): 3 | """ 4 | :type s: str 5 | :type words: List[str] 6 | :rtype: List[int] 7 | """ 8 | # 初始化 9 | strlen = 0 10 | res = [] 11 | 12 | if strlen > len(s) or len(s) == 0 or len(words) == 0: 13 | return res 14 | 15 | dic_words = {} 16 | 17 | # 转换为字典,并计算出现次数 18 | for w in words: 19 | if w in dic_words: 20 | dic_words[w] += 1 21 | else: 22 | dic_words[w] = 1 23 | 24 | # 子串长度 25 | len_word = len(words[0]) 26 | len_words = len(words) 27 | strlen += len_word * len_words 28 | 29 | j = 0 30 | 31 | # 滑动子串 32 | while j + strlen <= len(s): 33 | dic_substr = {} 34 | substr = s[j: j + strlen] 35 | k = 0 36 | # 滑动单词 37 | while k + len_word <= len(substr): 38 | if substr[k: k + len_word] in dic_words: 39 | if substr[k: k + len_word] in dic_substr: 40 | dic_substr[substr[k: k + len_word]] += 1 41 | else: 42 | dic_substr[substr[k: k + len_word]] = 1 43 | k = k + len_word 44 | else: 45 | break 46 | 47 | if dic_words == dic_substr: 48 | res.append(j) 49 | 50 | j = j + 1 51 | 52 | return res 53 | 54 | 55 | s = Solution() 56 | print( 57 | s.findSubstring("ababaab", 58 | ["ab", "ba", "ba"])) 59 | -------------------------------------------------------------------------------- /31NextPermutation.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def nextPermutation(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: void Do not return anything, modify nums in-place instead. 6 | """ 7 | 8 | numr = sorted(nums, reverse=True) 9 | 10 | # such arrangement is not possible 11 | if numr == nums: 12 | nums.reverse() 13 | print(nums) 14 | 15 | elif len(nums) != 0 and numr != nums: 16 | j = len(nums) - 1 17 | while j > 0: 18 | i = j - 1 19 | if nums[j] > nums[i]: 20 | # look backward for min num which greater than nums[i] 21 | k = j 22 | swap = j 23 | while k < len(nums): 24 | if nums[i] < nums[k]: 25 | if nums[k] < nums[j]: 26 | swap = k 27 | k = k + 1 28 | temp = nums[i] 29 | nums[i] = nums[swap] 30 | nums[swap] = temp 31 | # sorted in ascending order 32 | nums[i + 1:] = sorted(nums[i + 1:]) 33 | break 34 | else: 35 | j = j - 1 36 | -------------------------------------------------------------------------------- /32Longest Valid Parentheses-2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestValidParentheses(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | 8 | dp = [] 9 | lens = len(s) 10 | 11 | if lens < 2: 12 | return 0 13 | 14 | 15 | # initialize dp lisSt 16 | j = 0 17 | while j < lens: 18 | dp.append(0) 19 | j += 1 20 | 21 | i = 1 22 | while i < lens: 23 | if s[i] == ")" and s[i - 1] == "(": 24 | dp[i] = dp[i - 2] + 2 25 | 26 | if s[i] == s[i - 1] == ")": 27 | if i - dp[i-1] - 1 >= 0: 28 | if s[i - dp[i - 1] - 1] == "(": 29 | dp[i] = dp[i - 1] + dp[i - dp[i - 1] - 2] + 2 30 | i += 1 31 | 32 | return max(dp) -------------------------------------------------------------------------------- /32LongestValidParentheses.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestValidParentheses(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | 8 | if len(s) == 0 or len(s) == 1: 9 | return 0 10 | 11 | stack = [] 12 | j = 0 13 | max_len = 0 14 | 15 | while j < len(s): 16 | if s[j] == "(": 17 | stack.append(j) 18 | 19 | if s[j] == ")": 20 | if len(stack) and s[stack[-1]] == "(": 21 | stack.pop() 22 | if len(stack): 23 | lens = j - stack[-1] 24 | if lens > max_len: 25 | max_len = lens 26 | else: 27 | lens = j + 1 28 | if lens > max_len: 29 | max_len = lens 30 | 31 | else: 32 | stack.append(j) 33 | j += 1 34 | 35 | return max_len 36 | 37 | 38 | s = Solution() 39 | print(s.longestValidParentheses(")()())()()(")) 40 | -------------------------------------------------------------------------------- /33 SearchinRotated SortedArray.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def search(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: int 7 | """ 8 | if len(nums) == 0: 9 | return -1 10 | 11 | if len(nums) == 1: 12 | if target == nums[0]: 13 | return 0 14 | else: 15 | return -1 16 | 17 | if target < nums[0]: 18 | j = -1 19 | while j >= - len(nums): 20 | if target == nums[j]: 21 | return len(nums) + j 22 | if target < nums[j]: 23 | if j - 1 >= - len(nums): 24 | if nums[j-1] <= nums[j]: 25 | j = j - 1 26 | continue 27 | else: 28 | return -1 29 | else: 30 | return -1 31 | 32 | if target > nums[j]: 33 | return -1 34 | 35 | if target == nums[0]: 36 | return 0 37 | 38 | if target > nums[0]: 39 | i = 0 40 | while i < len(nums): 41 | if target == nums[i]: 42 | return i 43 | if target > nums[i]: 44 | if i + 1 < len(nums): 45 | if nums[i] <= nums[i+1]: 46 | i = i + 1 47 | continue 48 | else: 49 | return -1 50 | else: 51 | return -1 52 | if target < nums[i]: 53 | return -1 54 | 55 | -------------------------------------------------------------------------------- /34Find First and Last Position of Element in Sorted Array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def searchRange(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: List[int] 7 | """ 8 | le = len(nums) 9 | if le == 0: 10 | return [-1, -1] 11 | 12 | left = 0 13 | right = le - 1 14 | res = [-1, -1] 15 | lflag = True 16 | rflag = True 17 | 18 | while left < le and right >= 0: 19 | if left <= right: 20 | 21 | if nums[left] == target and lflag: 22 | res[0] = left 23 | lflag = False 24 | elif lflag: 25 | if left + 1 < le: 26 | left = left + 1 27 | else: 28 | return res 29 | 30 | if nums[right] == target and rflag: 31 | res[1] = right 32 | rflag = False 33 | 34 | elif rflag: 35 | if right - 1 >= 0: 36 | right = right - 1 37 | else: 38 | return res 39 | 40 | if not rflag and not lflag: 41 | return res 42 | 43 | else: 44 | return res 45 | 46 | 47 | s = Solution() 48 | print(s.searchRange([1, 2, 3], 1)) 49 | -------------------------------------------------------------------------------- /35SearchInsertPosition.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def searchInsert(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: int 7 | """ 8 | 9 | le = len(nums) 10 | if le == 0: 11 | return 0 12 | 13 | if target > nums[-1]: 14 | return le 15 | elif target < nums[0]: 16 | return 0 17 | elif target = nums[-1]: 18 | return le - 1 19 | elif target = nums[0]: 20 | return 0 21 | 22 | lo = 0 23 | hi = le - 1 24 | 25 | while lo < hi: 26 | if (hi - lo) // 2 > 0: 27 | mid = lo + (hi - lo) // 2 28 | if nums[mid] < target: 29 | lo = mid 30 | elif nums[mid] > target: 31 | hi = mid 32 | elif nums[mid] == target: 33 | return mid 34 | else: 35 | return hi 36 | 37 | return hi 38 | 39 | s = Solution() 40 | print(s.searchInsert([1, 3, 5, 6], 5)) 41 | -------------------------------------------------------------------------------- /36ValidSudoku.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isValidSudoku(self, board): 3 | """ 4 | :type board: List[List[str]] 5 | :rtype: bool 6 | """ 7 | 8 | # check every row valid or not 9 | for row in board: 10 | temp_row = [] 11 | for num in row: 12 | if num == ".": 13 | continue 14 | elif num not in temp_row: 15 | temp_row.append(num) 16 | else: 17 | return False 18 | 19 | # check every col valid or not 20 | i = 0 21 | while i < 9: 22 | temp_col = [] 23 | for row in board: 24 | if row[i] == ".": 25 | continue 26 | elif row[i] not in temp_col: 27 | temp_col.append(row[i]) 28 | else: 29 | return False 30 | i += 1 31 | 32 | # check every 3*3 valid or not: 33 | s = 0 34 | while s <= 6: 35 | col = 0 36 | while col <= 6: 37 | temp_box = [] 38 | for row in board[s:s + 3]: 39 | for num in row[col:col + 3]: 40 | if num == ".": 41 | continue 42 | elif num not in temp_box: 43 | temp_box.append(num) 44 | else: 45 | return False 46 | col += 3 47 | s += 3 48 | 49 | return True 50 | 51 | 52 | s = Solution() 53 | res = s.isValidSudoku([[".", ".", "4", ".", ".", ".", "6", "3", "."], [ 54 | ".", ".", ".", ".", ".", ".", ".", ".", "." 55 | ], ["5", ".", ".", ".", ".", ".", ".", "9", 56 | "."], [".", ".", ".", "5", "6", ".", ".", ".", 57 | "."], ["4", ".", "3", ".", ".", ".", ".", ".", 58 | "1"], [".", ".", ".", "7", ".", ".", ".", ".", "."], 59 | [".", ".", ".", "5", ".", ".", ".", ".", 60 | "."], [".", ".", ".", ".", ".", ".", ".", ".", "."], 61 | [".", ".", ".", ".", ".", ".", ".", ".", "."]]) 62 | print(res) 63 | -------------------------------------------------------------------------------- /37SudokuSolver.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def solver(self, board): 3 | import copy 4 | # get the candidates based on rule of row 5 | cd_row = [["1", "2", "3", "4", "5", "6", "7", "8", 6 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 7 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"], 8 | ["1", "2", "3", "4", "5", "6", "7", "8", 9 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 10 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"], 11 | ["1", "2", "3", "4", "5", "6", "7", "8", 12 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 13 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"]] 14 | i = 0 15 | while i < 9: 16 | for n in board[i]: 17 | 18 | if n in cd_row[i]: 19 | cd_row[i].remove(n) 20 | i += 1 21 | 22 | # Terminal condition 23 | T = 0 24 | for r in cd_row: 25 | if len(r) == 0: 26 | T = T + 1 27 | if T == 9: 28 | return board 29 | 30 | # get the candidates based on rule of col 31 | cd_col = [["1", "2", "3", "4", "5", "6", "7", "8", 32 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 33 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"], 34 | ["1", "2", "3", "4", "5", "6", "7", "8", 35 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 36 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"], 37 | ["1", "2", "3", "4", "5", "6", "7", "8", 38 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 39 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"]] 40 | j = 0 41 | while j < 9: 42 | for row in board: 43 | if row[j] in cd_col[j]: 44 | cd_col[j].remove(row[j]) 45 | j += 1 46 | 47 | # get candidates based on rule of 3*3 box 48 | cd_box = [["1", "2", "3", "4", "5", "6", "7", "8", 49 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 50 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"], 51 | ["1", "2", "3", "4", "5", "6", "7", "8", 52 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 53 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"], 54 | ["1", "2", "3", "4", "5", "6", "7", "8", 55 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", 56 | "9"], ["1", "2", "3", "4", "5", "6", "7", "8", "9"]] 57 | s = 0 58 | b = 0 59 | while s <= 6: 60 | col = 0 61 | while col <= 6: 62 | for row in board[s:s + 3]: 63 | for n in row[col:col + 3]: 64 | if n in cd_box[b]: 65 | cd_box[b].remove(n) 66 | b += 1 67 | col += 3 68 | s += 3 69 | 70 | min_cd = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] 71 | p_x = 0 # solve point x-th row 72 | p_y = 0 # solve point y-th col 73 | cert = [] # point only has one candidate 74 | 75 | a = 0 76 | cd_board = [] 77 | while a < 9: 78 | cd_b = [] 79 | b = 0 80 | while b < 9: 81 | if board[a][b] != ".": 82 | cd_b.append(board[a][b]) 83 | else: 84 | # print("cd_row[a]:", cd_row[a]) 85 | # print("cd_col[b]:", cd_col[b]) 86 | # print("cd_box[]:", cd_box[(a//3)*3 + b//3]) 87 | cd = [ 88 | c for c in cd_row[a] if c in cd_col[b] 89 | and c in cd_box[(a // 3) * 3 + b // 3] 90 | ] 91 | if len(cd) == 0: 92 | cert = [] 93 | return "wrong" 94 | 95 | elif len(cd) <= len(min_cd): 96 | min_cd = cd 97 | p_x = a 98 | p_y = b 99 | if len(cd) == 1: 100 | cert.append([p_x, p_y]) 101 | cd_b.append(cd) 102 | b += 1 103 | cd_board.append(cd_b) 104 | a += 1 105 | 106 | if len(cert) > 0: 107 | for p in cert: 108 | temp = copy.deepcopy(board) 109 | temp[p[0]][p[1]] = cd_board[p[0]][p[1]][0] 110 | # print("board:", board) 111 | res = self.solver(temp) 112 | if res == "wrong": 113 | return "wrong" 114 | else: 115 | return res 116 | 117 | else: 118 | trynum = min_cd[0] 119 | temp = copy.deepcopy(board) 120 | temp[p_x][p_y] = trynum 121 | res = self.solver(temp) 122 | while res == "wrong": 123 | if len(min_cd) > 1: 124 | min_cd.remove(trynum) 125 | trynum = min_cd[0] 126 | temp[p_x][p_y] = trynum 127 | res = self.solver(temp) 128 | else: 129 | return "wrong" 130 | return res 131 | 132 | def solveSudoku(self, board): 133 | res = self.solver(board) 134 | i = 0 135 | if res != "wrong": 136 | while i < 9: 137 | j = 0 138 | while j < 9: 139 | board[i][j] = res[i][j] 140 | j = j + 1 141 | i = i + 1 142 | print(res) 143 | 144 | 145 | s = Solution() 146 | print( 147 | s.solveSudoku([["1", ".", ".", ".", "7", ".", ".", "3", 148 | "."], ["8", "3", ".", "6", ".", ".", ".", ".", 149 | "."], [".", ".", "2", "9", ".", ".", "6", ".", "8"], 150 | ["6", ".", ".", ".", ".", "4", "9", ".", 151 | "7"], [".", "9", ".", ".", ".", ".", ".", "5", 152 | "."], ["3", ".", "7", "5", ".", ".", ".", ".", "4"], 153 | ["2", ".", "3", ".", ".", "9", "1", ".", 154 | "."], [".", ".", ".", ".", ".", "2", ".", "4", 155 | "3"], [".", 156 | "4", ".", ".", "8", ".", ".", ".", "9"]])) 157 | -------------------------------------------------------------------------------- /382_Linked_List_Random_Node.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Fri, May 10, 2019 10:52 4 | @Email: xiangyangan@gmail.com 5 | @Blog: www.tundrazone.com 6 | ''' 7 | 8 | import random 9 | 10 | 11 | # Definition for singly-linked list. 12 | class ListNode: 13 | def __init__(self, x): 14 | self.val = x 15 | self.next = None 16 | 17 | 18 | class Solution: 19 | def __init__(self, head: ListNode): 20 | """ 21 | @param head The linked list's head. 22 | Note that the head is guaranteed to be not null, 23 | so it contains at least one node. 24 | """ 25 | self.head = head 26 | self.candid = [] 27 | while self.head: 28 | self.candid.append(self.head.val) 29 | self.head = self.head.next 30 | 31 | def getRandom(self) -> int: 32 | """ 33 | Returns a random node's value. 34 | """ 35 | return random.choice(self.candid) 36 | 37 | 38 | 39 | # Your Solution object will be instantiated and called as such: 40 | # obj = Solution(head) 41 | # param_1 = obj.getRandom() -------------------------------------------------------------------------------- /38CountandSay.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution: 3 | def count(self, snum): 4 | num_count = [] 5 | before = "" 6 | for s in snum: 7 | if s != before: 8 | num_count.append(["1" + s]) 9 | before = s 10 | else: 11 | # print(num_count[-1][0][0]) 12 | num_count[-1] = [str(int(num_count[-1][0][0]) + 1) + s] 13 | res = "" 14 | for n in num_count: 15 | res = res + n[0] 16 | return res 17 | 18 | def countAndSay(self, n): 19 | ''' 20 | :type n: int 21 | :rtype: str 22 | ''' 23 | i = 1 24 | snum = "1" 25 | while i < n: 26 | snum = self.count(snum) 27 | i += 1 28 | return snum 29 | 30 | s = Solution() 31 | print(s.countAndSay(5)) 32 | -------------------------------------------------------------------------------- /398_Random_Pick_Index.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Wed, May 8, 2019 11:11 4 | @Email: xiangyangan@gmail.com 5 | @Blog: www.tundrazone.com 6 | ''' 7 | 8 | import random 9 | 10 | 11 | # beats 100% 12 | class Solution1: 13 | def __init__(self, nums): 14 | self.nums = nums 15 | 16 | def pick(self, target): 17 | e = self.nums.count(target) 18 | # ranodom select the i-th object 19 | i = random.randint(1, e) 20 | # count 1 to i 21 | for j in range(len(self.nums)): 22 | if self.nums[j] == target: 23 | i = i - 1 24 | if i = 0: 25 | return j 26 | 27 | # beats 50% 28 | class Solution2: 29 | def __init__(self, nums): 30 | self.nums = nums 31 | 32 | def pick(self, target): 33 | candid =[] 34 | for i in range(len(self.nums)): 35 | if self.nums[i] == target: 36 | candid.append(i) 37 | return random.sample(candid, 1) 38 | 39 | 40 | 41 | 42 | s = Solution([1]) 43 | print(s.pick(1)) 44 | 45 | # Your Solution object will be instantiated and called as such: 46 | # obj = Solution(nums) 47 | # param_1 = obj.pick(target) -------------------------------------------------------------------------------- /39CombinationSum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def Solver(self, res, path, candidates, target, idx): 3 | for i in range(idx, len(candidates)): 4 | new_target = target - candidates[i] 5 | if new_target < 0: 6 | return 7 | else: 8 | if new_target == 0: 9 | res.append(path + [candidates[i]]) 10 | else: 11 | self.Solver(res, path + [candidates[i]], candidates, 12 | new_target, i) 13 | 14 | def combinationSum(self, candidates, target): 15 | """ 16 | :type candidates: List[int] 17 | :type target: int 18 | :rtype: List[List[int]] 19 | """ 20 | path = [] 21 | res = [] 22 | candidates = sorted(candidates) 23 | self.Solver(res, path, candidates, target, 0) 24 | return res 25 | 26 | 27 | s = Solution() 28 | print(s.combinationSum([8, 7, 4, 3], 11)) 29 | -------------------------------------------------------------------------------- /40CombinationSum2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def Slover(self, candidates, target, res, path, idx): 3 | for i in range(idx, len(candidates)): 4 | new_target = target - candidates[i] 5 | if new_target < 0: 6 | return 7 | else: 8 | if new_target == 0: 9 | res.append(path + [candidates[i]]) 10 | else: 11 | idx = idx + 1 12 | if idx < len(candidates): 13 | self.Slover(candidates, new_target, res, 14 | path + [candidates[i]], idx) 15 | else: 16 | return 17 | 18 | def combinationSum2(self, candidates, target): 19 | """ 20 | :type candidates: List[int] 21 | :type target: int 22 | :rtype: List[List[int]] 23 | """ 24 | res = [] 25 | path = [] 26 | idx = 0 27 | candidates = sorted(candidates) 28 | self.Slover(candidates, target, res, path, idx) 29 | ud_res = [] 30 | for r in res: 31 | if r not in ud_res: 32 | ud_res.append(r) 33 | return ud_res 34 | -------------------------------------------------------------------------------- /41FirstMissingPositve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | class Solution: 4 | def firstMissingPositive(self, nums): 5 | """ 6 | :type nums: List[int] 7 | :rtype: int 8 | """ 9 | 10 | i = 0 11 | for i in range(1, len(nums) + 2): 12 | if i not in nums: 13 | return i 14 | 15 | 16 | 17 | s = Solution() 18 | print(s.firstMissingPositive([])) 19 | -------------------------------------------------------------------------------- /42TrappingRainWater.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def trap(self, height): 3 | """ 4 | :type height: List[int] 5 | :rtype: int 6 | """ 7 | left = left_max = 0 8 | right = right_max = len(height) - 1 9 | res = 0 10 | 11 | while left < right: 12 | if height[left] > height[right]: 13 | if height[right_max] < height[right]: 14 | right_max = right 15 | right = right - 1 16 | else: 17 | res += height[right_max] - height[right] 18 | right = right - 1 19 | 20 | if height[left] <= height[right]: 21 | if height[left_max] < height[left]: 22 | left_max = left 23 | left = left + 1 24 | else: 25 | res += height[left_max] - height[left] 26 | left = left + 1 27 | return res 28 | -------------------------------------------------------------------------------- /43MultiplyStrings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | class Solution: 4 | def str2num(self, num): 5 | int_num = 0 6 | pos = 1 7 | for n in num[::-1]: 8 | int_num += (ord(n) - 48) * pos 9 | pos = pos * 10 10 | print(int_num) 11 | return int_num 12 | 13 | def multiply(self, num1, num2): 14 | """ 15 | :type num1: str 16 | :type num2: str 17 | :rtype: str 18 | """ 19 | n1 = self.str2num(num1) 20 | n2 = self.str2num(num2) 21 | k = n1 * n2 22 | c = repr(k) 23 | return c 24 | 25 | 26 | 27 | 28 | s = Solution() 29 | print(s.multiply("12", "20")) 30 | 31 | -------------------------------------------------------------------------------- /44WildcardMatching.py: -------------------------------------------------------------------------------- 1 | """ 2 | @auther: Jedi.L 3 | @Date: Mon, Jan 21, 2019 11:34 4 | """ 5 | 6 | 7 | class Solution: 8 | def isMatch(self, s, p): 9 | """ 10 | :type s: str 11 | :type p: str 12 | :rtype: bool 13 | """ 14 | if p == "*": 15 | return True 16 | lp, ls = len(p), len(s) 17 | res = [True] + [False] * ls 18 | 19 | for i in range(lp): 20 | if p[i] == "*": 21 | for j in range(ls): 22 | res[j+1] = res[j+1] or res[j] 23 | else: 24 | for j in range(ls-1, -1, -1): 25 | """ 26 | if res[j] = False, then res[j+1] equal False, the current 27 | position Match is meaningful 28 | only if the previous position is matched 29 | """ 30 | res[j+1] = (p[i] == s[j] or p[i] == "?") and res[j] 31 | res[0] = False 32 | 33 | return res[ls] 34 | 35 | # test solution 36 | s = "cbc" 37 | p = "cbcbc" 38 | sl = Solution() 39 | print(sl.isMatch(s, p)) 40 | -------------------------------------------------------------------------------- /45_Jump_Game_II.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Solution Solution_back_2_front 3 | 92 / 92 test cases passed. 4 | Status: Accepted 5 | Runtime: 2436 ms 6 | Memory Usage: 14.9 MB 7 | ''' 8 | 9 | 10 | class Solution_back_2_front: 11 | def jump(self, nums): 12 | if sum(nums) == len(nums) and len(set(nums)) == 1: 13 | return len(nums) - 1 14 | 15 | steps = 0 16 | pre_points = [len(nums) - 1] 17 | while 0 not in pre_points: 18 | reach_points = [] 19 | for idx, n in enumerate(nums[:max(pre_points) + 1]): 20 | for p in pre_points: 21 | if idx < p and idx + n >= p and idx not in pre_points: 22 | if idx not in reach_points: 23 | reach_points.append(idx) 24 | pre_points = reach_points 25 | steps += 1 26 | return steps 27 | 28 | 29 | class Solution_greedy: 30 | def jump(self, nums) -> int: 31 | if not nums or len(nums) == 1: 32 | return 0 33 | 34 | des = len(nums) - 1 35 | res = 0 36 | i = 0 37 | max_range = 0 38 | nxt = 0 39 | while i < des: 40 | if i + nums[i] >= des: 41 | return res + 1 42 | for r in range(i + 1, i + nums[i] + 1): 43 | if r + nums[r] > max_range: 44 | max_range = r + nums[r] 45 | nxt = r 46 | i = nxt 47 | res += 1 48 | 49 | 50 | class Solution_BFS: 51 | def jump(self, nums) -> int: 52 | if not nums or len(nums) == 1: 53 | return 0 54 | 55 | frontier = [0] 56 | des = len(nums) - 1 57 | level = 0 58 | left = 0 59 | while frontier: 60 | nxt_lst = [] 61 | right = left 62 | for cur in frontier: 63 | if cur == des: 64 | return level 65 | right = max(right, cur + nums[cur]) 66 | for n in range(left + 1, right + 1): 67 | nxt_lst += [n] 68 | frontier = nxt_lst 69 | level += 1 70 | left = right 71 | 72 | 73 | # Test 74 | s = Solution_BFS() 75 | print( 76 | s.jump([ 77 | 8, 2, 4, 4, 4, 9, 5, 2, 5, 8, 8, 0, 8, 6, 9, 1, 1, 6, 3, 5, 1, 2, 6, 6, 78 | 0, 4, 8, 6, 0, 3, 2, 8, 7, 6, 5, 1, 7, 0, 3, 4, 8, 3, 5, 9, 0, 4, 0, 1, 79 | 0, 5, 9, 2, 0, 7, 0, 2, 1, 0, 8, 2, 5, 1, 2, 3, 9, 7, 4, 7, 0, 0, 1, 8, 80 | 5, 6, 7, 5, 1, 9, 9, 3, 5, 0, 7, 5 81 | ])) 82 | -------------------------------------------------------------------------------- /45_explanation_Jump_Game_II .md: -------------------------------------------------------------------------------- 1 | # 45_explanation_Jump_Game_II 2 | 3 | ## Problem 4 | [Jump Game II - LeetCode](https://leetcode.com/problems/jump-game-ii/) 5 | > Given an array of non-negative integers, you are initially positioned at the first index of the array. 6 | 7 | > Each element in the array represents your maximum jump length at that position. 8 | 9 | > Your goal is to reach the last index in the minimum number of jumps. 10 | 11 | > *Example:* 12 | 13 | > *Input:* [2,3,1,1,4] 14 | 15 | > *Output:* 2 16 | 17 | > *Explanation:* The minimum number of jumps to reach the last index is 2. 18 | 19 | > Jump 1 step from index 0 to 1, then 3 steps to the last index. 20 | 21 | > *Note:* 22 | 23 | > You can assume that you can always reach the last index. 24 | 25 | ## Method 26 | 27 | We can think the number of each item in `nums` represents a coverage area. Hence, to solve this problem, we want to cover the entire range with a minimum number of areas. Note that although we call this algorithm the greedy algorithm, in general, the greedy algorithm does not find the optimal solution. However, in this topic, the next area covering the farthest is the dominant strategy compared to other areas [Strategic dominance](https://www.wikiwand.com/en/Strategic_dominance). Hence, in this problem, the optimal solution can be obtained by greed. 28 | 29 | The main idea of my algorithm as follows: 30 | 31 | 1. Based on the current position and its region, find the adjacent areas `r` in range from `i` to `(i + num )` . 32 | 2. Compared the furthest coverage range of these areas with the maximum range: If `(i + num )` greater than the maximum range, set the next coverage area start from `r` and maximum range equals to `i + num`. 33 | 3. Update the current position as `r`. 34 | 4. Keep doing this until the whole area is covered. 35 | 36 | ## Code 37 | 38 | ``` 39 | class Solution: 40 | def jump(self, nums) -> int: 41 | if not nums or len(nums) == 1: 42 | return 0 43 | 44 | des = len(nums) - 1 45 | res = 0 46 | i = 0 47 | max_range = 0 48 | nxt = 0 49 | while i < des: 50 | if i + nums[i] >= des: 51 | return res + 1 52 | for r in range(i + 1, i + nums[i] + 1): 53 | if r + nums[r] > max_range: 54 | max_range = r + nums[r] 55 | nxt = r 56 | i = nxt 57 | res += 1 58 | ``` 59 | -------------------------------------------------------------------------------- /470_explain.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | a = np.array([1, 2, 3, 4, 5, 6, 7]) 4 | b = np.array([1, 2, 3, 4, 5, 6, 7]) 5 | x = np.zeros((7, 7)) 6 | # x = a + (b - 1) * 7 7 | i = 0 8 | while i < len(a): 9 | j = 0 10 | while j < len(b): 11 | x[i][j] = a[i] + (b[j] - 1) * 7 12 | j = j + 1 13 | i = i + 1 14 | # generate from 1 to 49 15 | print(x) 16 | 17 | y = 1 18 | k = [] 19 | while y <= 40: 20 | k.append((y - 1) % 10 + 1) 21 | y = y + 1 22 | # generate from 1 to 10 with the same probability 23 | print(k) 24 | -------------------------------------------------------------------------------- /470_implement_rand10_using_rand7.py: -------------------------------------------------------------------------------- 1 | # Creat by Jedi.L 2 | # The rand7() API is already defined for you. 3 | # def rand7(): 4 | # @return a random integer in the range 1 to 7 5 | 6 | 7 | class Solution: 8 | def rand10(self): 9 | """ 10 | :rtype: int 11 | """ 12 | idx = 49 13 | while idx > 40: 14 | row = rand7() 15 | col = rand7() 16 | idx = row + (col - 1) * 7 17 | if idx <= 40: 18 | return 1 + (idx - 1) % 10 19 | 20 | 21 | -------------------------------------------------------------------------------- /478_Generate_Random_Point_in_a_Circle.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Solution: 5 | 6 | def __init__(self, radius: 'float', x_center: 'float', y_center: 'float'): 7 | self.radius = radius 8 | self.x_center = x_center 9 | self.y_center = y_center 10 | self.x_max = x_center + radius 11 | self.y_max = y_center + radius 12 | self.x_min = x_center - radius 13 | self.y_min = y_center - radius 14 | 15 | def randPoint(self) -> 'List[float]': 16 | while True: 17 | res_x = random.uniform(self.x_min, self.x_max) 18 | res_y = random.uniform(self.y_min, self.y_max) 19 | dis = (res_x - self.x_center)**2 + (res_y - self.y_center)**2 20 | if dis**2 <= self.radius**2: 21 | return [res_x, res_y] 22 | 23 | 24 | 25 | 26 | # Your Solution object will be instantiated and called as such: 27 | # obj = Solution(radius, x_center, y_center) 28 | # param_1 = obj.randPoint() -------------------------------------------------------------------------------- /497Random_Point_in_Non-overlapping_Rectangles.py: -------------------------------------------------------------------------------- 1 | import random 2 | import bisect 3 | 4 | ''' 5 | @auther: Jedi.L 6 | @Date: Tue, Feb 26, 2019 12:10 7 | @Email: xiangyangan@gmail.com 8 | ''' 9 | 10 | 11 | # class Solution: 12 | # def __init__(self, rects: List[List[int]]): 13 | # self.rects = rects 14 | # self.weights = [] 15 | # for [x_bl, y_bl, x_tr, y_tr] in self.rects: 16 | # self.weights.append((x_tr - x_bl + 1) * (y_tr - y_bl + 1)) 17 | 18 | # def pick(self) -> List[int]: 19 | # [x_bl, y_bl, x_tr, y_tr] = random.choices( 20 | # self.rects, weights=self.weights)[0] 21 | # res = [ 22 | # random.randrange(x_bl, x_tr + 1), 23 | # random.randrange(y_bl, y_tr + 1) 24 | # ] 25 | # return res 26 | 27 | 28 | class Solution: 29 | def __init__(self, rects: List[List[int]]): 30 | self.rects = rects 31 | self.weights = [] 32 | for [x_bl, y_bl, x_tr, y_tr] in self.rects: 33 | self.weights.append((x_tr - x_bl + 1) * (y_tr - y_bl + 1)) 34 | 35 | def pick(self) -> List[int]: 36 | [x_bl, y_bl, x_tr, y_tr] = random.choices( 37 | self.rects, weights=self.weights)[0] 38 | res = [ 39 | random.randrange(x_bl, x_tr + 1), 40 | random.randrange(y_bl, y_tr + 1) 41 | ] 42 | return res 43 | 44 | 45 | class Solution2: 46 | def __init__(self, rects): 47 | self.rects, self.ranges, point_sum = rects, [], 0 48 | for x_bl, y_bl, x_tr, y_tr in rects: 49 | point_sum += (x_tr - x_bl + 1) * (y_tr - y_bl + 1) 50 | self.ranges.append(point_sum) 51 | 52 | def pick(self): 53 | x1, y1, x2, y2 = self.rects[bisect.bisect_left( 54 | self.ranges, random.randint(1, self.ranges[-1]))] 55 | return [random.randint(x1, x2), random.randint(y1, y2)] 56 | 57 | # Your Solution object will be instantiated and called as such: 58 | # obj = Solution(rects) 59 | # param_1 = obj.pick() -------------------------------------------------------------------------------- /519_random_flip_matrix.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Wed, Feb 20, 2019 11:44 4 | @Email: xiangyangan@gmail.com 5 | ''' 6 | 7 | import random 8 | 9 | # class Solution: 10 | # def __init__(self, n_rows, n_cols): 11 | # """ 12 | # :type n_rows: int 13 | # :type n_cols: int 14 | # """ 15 | # self.cols = n_cols 16 | # self.end = n_rows * n_cols - 1 17 | # self.hash = {} 18 | # self.start = 0 19 | 20 | # def flip(self): 21 | # """ 22 | # :rtype: List[int] 23 | # """ 24 | # position = random.randint(self.start, self.end) 25 | # res = self.hash.get(position, position) 26 | # self.hash[position] = self.d.get(self.start, self.start) 27 | # self.start += 1 28 | # return divmod(res, self.cols) 29 | 30 | # def reset(self): 31 | # """ 32 | # :rtype: void 33 | # """ 34 | # self.hash = {} 35 | # self.start = 0 36 | 37 | 38 | class Solution: 39 | def __init__(self, n_rows, n_cols): 40 | """ 41 | :type n_rows: int 42 | :type n_cols: int 43 | """ 44 | self.cols = n_cols 45 | self.end = n_rows * n_cols - 1 46 | self.fliped = set() 47 | self.start = 0 48 | 49 | def flip(self): 50 | """ 51 | :rtype: List[int] 52 | """ 53 | while True: 54 | position = random.randint(self.start, self.end) 55 | if position not in self.fliped: 56 | self.fliped.add(position) 57 | return divmod(position, self.cols) 58 | 59 | def reset(self): 60 | """ 61 | :rtype: void 62 | """ 63 | self.fliped = set() 64 | 65 | 66 | 67 | # Your Solution object will be instantiated and called as such: 68 | # obj = Solution(n_rows, n_cols) 69 | # param_1 = obj.flip() 70 | # obj.reset() 71 | -------------------------------------------------------------------------------- /528_Random_Pick_with_Weight.py: -------------------------------------------------------------------------------- 1 | 2 | ''' 3 | @auther: Jedi.L 4 | @Date: Tue, Feb 26, 2019 5:28 5 | @Email: xiangyangan@gmail.com 6 | @Blog: www.tundrazone.com 7 | ''' 8 | 9 | import random 10 | import bisect 11 | 12 | 13 | class Solution: 14 | def __init__(self, w: List[int]): 15 | self.w = w 16 | self.sw = [] 17 | w_sum = 0 18 | 19 | for ww in self.w: 20 | w_sum += ww 21 | self.sw.append(w_sum) 22 | 23 | def pickIndex(self) -> int: 24 | return bisect.bisect_left(self.sw, random.randint(1, self.sw[-1])) 25 | 26 | 27 | # Your Solution object will be instantiated and called as such: 28 | # obj = Solution(w) 29 | # param_1 = obj.pickIndex() -------------------------------------------------------------------------------- /55_Jump_Game.py: -------------------------------------------------------------------------------- 1 | class Solution_greedy: 2 | def canJump(self, nums) -> int: 3 | if not nums or len(nums) == 1: 4 | return False 5 | 6 | des = len(nums) - 1 7 | 8 | i = 0 9 | max_range = 0 10 | nxt = 0 11 | while i < des: 12 | if i + nums[i] >= des: 13 | return True 14 | for r in range(i + 1, i + nums[i] + 1): 15 | if r + nums[r] > max_range: 16 | max_range = r + nums[r] 17 | nxt = r 18 | if i == nxt: 19 | return False 20 | else: 21 | i = nxt 22 | 23 | 24 | class Solution_backforward: 25 | def canJump(self, nums) -> int: 26 | if not nums or len(nums) == 1: 27 | return True 28 | 29 | des = len(nums) - 1 30 | 31 | for i in range(des - 1, -1, -1): 32 | if i + nums[i] >= des: 33 | des = i 34 | if des == 0: 35 | return True 36 | return des == 0 37 | 38 | 39 | # Test 40 | s = Solution_backforward() 41 | print("False: ", s.canJump([1, 2, 0, 0, 0, 6])) 42 | print("True: ", s.canJump([1, 2, 3, 2, 0, 6])) 43 | -------------------------------------------------------------------------------- /55_explanation_Jump_Game.md: -------------------------------------------------------------------------------- 1 | # leetcode题目讲解(Python): 55 跳跃游戏 (55 Jump Game) 2 | ## Problem 3 | ![ACF20240-EA56-46C0-BDBC-C78EAC14149B](https://i.loli.net/2020/01/31/sprIhZnDAdxKqlz.png) 4 | 5 | [Jump Game](https://leetcode.com/problems/jump-game/) 6 | 7 | ## Solution 8 | ### Back-forward 9 | 10 | In English: 11 | 1. Set des(destination) equals to the last item in the “nums”. 12 | 2. From back to front finding i which can meet the condition: i + nums[i] >= des 13 | 3. If we can find i satisfies the condition, set des = i. If i == 0, then return True, otherwise start the next loop. 14 | 4. If there is no i can meet the condition, return False. 15 | 16 | In Chinese: 17 | 1. 首先把 list 里最后一项作为目标。 18 | 2. 由后向前寻找可以到达目标的位置i(满足 i + nums[i] >= des)。 19 | 3. 如果发现满足条件的位置 i ,把目标更新为位置 i,如果 i 为 0,返回 True,否则然后开始下一个循环。 20 | 4. 如果找不到满足条件的 i, 返回 False 21 | 22 | 23 | ``` 24 | class Solution: 25 | def canJump(self, nums) -> int: 26 | if not nums or len(nums) == 1: 27 | return True 28 | 29 | des = len(nums) - 1 30 | 31 | for I in range(des - 1, -1, -1): 32 | if I + nums[I] >= des: 33 | des = i 34 | if des == 0: 35 | return True 36 | 37 | ``` 38 | 39 | ### Greedy 40 | English: 41 | We can easily change our code in Problem 45 to get the solution. 42 | 43 | Chinese: 44 | 我们也可以通过修改问题45 的代码通过贪婪算法得到答案。 45 | 46 | ``` 47 | class Solution: 48 | def canJump(self, nums) -> int: 49 | if not nums or len(nums) == 1: 50 | return False 51 | 52 | des = len(nums) - 1 53 | 54 | I = 0 55 | max_range = 0 56 | nxt = 0 57 | while I < des: 58 | if I + nums[I] >= des: 59 | return True 60 | for r in range(I + 1, I + nums[I] + 1): 61 | if r + nums[r] > max_range: 62 | max_range = r + nums[r] 63 | nxt = r 64 | if I == nxt: 65 | return False 66 | else: 67 | I = nxt 68 | 69 | ``` 70 | -------------------------------------------------------------------------------- /587_Erect_the_Fence.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Sat, May 4, 2019 12:04 4 | @Email: xiangyangan@gmail.com 5 | @Blog: www.tundrazone.com 6 | ''' 7 | 8 | 9 | class Solution: 10 | def orientation(self, a, b, c): 11 | ori = (b[1] - a[1]) * (c[0] - b[0]) - (c[1] - b[1]) * (b[0] - a[0]) 12 | if ori == 0: 13 | return 0 # colinear 14 | res = 1 if ori > 0 else 2 # clock or counterclock wise 15 | return res 16 | 17 | def inbetween(self, a, b, c): 18 | ori = (b[1] - a[1]) * (c[0] - b[0]) - (c[1] - b[1]) * (b[0] - a[0]) 19 | if ori == 0 and min(a[0], c[0]) <= b[0] and max( 20 | a[0], c[0]) >= b[0] and min(a[1], c[1]) <= b[1] and max( 21 | a[1], c[1]) >= b[1]: 22 | return True # b in between a , c 23 | 24 | def outerTrees(self, points): 25 | points.sort(key=lambda x: x[0]) 26 | lengh = len(points) 27 | 28 | # must more than 3 points 29 | if lengh < 4: 30 | return points 31 | 32 | hull = [] 33 | a = 0 34 | start = True 35 | while a != 0 or start: 36 | start = False 37 | hull.append(points[a]) 38 | c = (a + 1) % lengh 39 | for b in range(0, lengh): 40 | if self.orientation(points[a], points[b], points[c]) == 2: 41 | c = b 42 | 43 | for b in range(0, lengh): 44 | if b != a and b != c and self.inbetween( 45 | points[a], points[b], 46 | points[c]) and points[b] not in hull: 47 | hull.append(points[b]) 48 | 49 | a = c 50 | return hull 51 | 52 | 53 | s = Solution() 54 | print(s.outerTrees([[1, 1], [2, 2], [2, 0], [2, 4], [3, 3], [4, 2]])) 55 | -------------------------------------------------------------------------------- /710_Random_Pick_with_Blacklist.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Mon, Mar 4, 2019 10:32 4 | @Email: xiangyangan@gmail.com 5 | @Blog: www.tundrazone.com 6 | ''' 7 | 8 | 9 | import random 10 | import bisect 11 | 12 | 13 | class Solution: 14 | def __init__(self, N, blacklist): 15 | self.N = N - 1 16 | self.black = sorted(blacklist) 17 | self.range = [] 18 | self.weight = [] 19 | self.blacklen = len(self.black) 20 | if self.blacklen: 21 | s = 0 22 | for r in self.black: 23 | if r - s >= 1: 24 | self.range.append([s, r - 1]) 25 | s = r + 1 26 | if s < self.N + 1: 27 | self.range.append([s, self.N]) 28 | 29 | weight = 0 30 | for r in self.range: 31 | weight = weight + r[1] - r[0] + 1 32 | self.weight.append(weight) 33 | 34 | def pick(self) -> int: 35 | if self.blacklen: 36 | r = self.range[bisect.bisect_left( 37 | self.weight, random.randint(1, self.weight[-1]))] 38 | return random.randint(r[0], r[1]) if r[1] > r[0] else r[0] 39 | 40 | else: 41 | return random.randint(0, self.N) 42 | 43 | 44 | class Solution2: 45 | def __init__(self, N, blacklist): 46 | """ 47 | :type N: int 48 | :type blacklist: List[int] 49 | """ 50 | self.N, self.N_b = N, len(blacklist) 51 | self.map = {} 52 | self.black = set(blacklist) 53 | cur_white = self.N - self.N_b 54 | for b in self.black: 55 | if b < self.N - self.N_b: 56 | while cur_white in self.black: 57 | cur_white += 1 58 | self.map[b] = cur_white 59 | cur_white += 1 60 | 61 | def pick(self): 62 | """ 63 | :rtype: int 64 | """ 65 | k = random.randint(0, self.N - self.N_b - 1) 66 | return self.map[k] if k in self.black else k 67 | 68 | 69 | s = Solution2(7, [0, 1, 3, 4]) 70 | n = 6 71 | while n: 72 | print(s.pick()) 73 | n = n - 1 74 | 75 | # Your Solution object will be instantiated and called as such: 76 | # obj = Solution(N, blacklist) 77 | # param_1 = obj.pick() 78 | -------------------------------------------------------------------------------- /892SurfaceAreaof3DShapes.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Wed, Mar 27, 2019 12:44 4 | @Email: xiangyangan@gmail.com 5 | @Blog: www.tundrazone.com 6 | ''' 7 | 8 | 9 | class Solution: 10 | def surfaceArea(self, grid): 11 | self.grid = grid 12 | tsa = 0 # total surface area of resulting shapes 13 | x = len(self.grid) - 1 # max i for grid[i][j] 14 | y = len((self.grid[0])) - 1 # max j for grid[i][j] 15 | i = 0 16 | while i <= x: 17 | j = 0 18 | while j <= y: 19 | if self.grid[i][j] != 0: 20 | tsa += self.grid[i][j] * 4 + 2 # surface are at point 21 | # we count the left surface area of this point as follow: 22 | # up close 23 | if i-1 >= 0 and self.grid[i-1][j] >= self.grid[i][j]: 24 | tsa = tsa - self.grid[i][j] 25 | elif i-1 >= 0 and self.grid[i-1][j] < self.grid[i][j]: 26 | tsa = tsa - self.grid[i-1][j] 27 | # down close 28 | if i+1 <= x and self.grid[i+1][j] >= self.grid[i][j]: 29 | tsa = tsa - self.grid[i][j] 30 | elif i+1 <= x and self.grid[i+1][j] < self.grid[i][j]: 31 | tsa = tsa - self.grid[i+1][j] 32 | # left close 33 | if j-1 >= 0 and self.grid[i][j-1] >= self.grid[i][j]: 34 | tsa = tsa - self.grid[i][j] 35 | elif j-1 >= 0 and self.grid[i][j-1] < self.grid[i][j]: 36 | tsa = tsa - self.grid[i][j-1] 37 | # right close 38 | if j + 1 <= y and self.grid[i][j+1] >= self.grid[i][j]: 39 | tsa = tsa - self.grid[i][j] 40 | elif j + 1 <= y and self.grid[i][j+1] < self.grid[i][j]: 41 | tsa = tsa - self.grid[i][j+1] 42 | j = j + 1 43 | i = i + 1 44 | return tsa 45 | 46 | 47 | class Solution2(object): 48 | def surfaceArea(self, grid): 49 | """ 50 | :type grid: List[List[int]] 51 | :rtype: int 52 | """ 53 | area = 0 54 | for i in range(len(grid)): 55 | for j in range(len(grid[i])): 56 | left = 0 if j == 0 else grid[i][j - 1] 57 | up = 0 if i == 0 else grid[i - 1][j] 58 | height = grid[i][j] 59 | area += max(height - left, 0) + max(height - up, 60 | 0) + (1 if height else 0) 61 | return area * 2 62 | 63 | 64 | class Solution3: 65 | def surfaceArea(self, grid): 66 | self.grid = grid 67 | tsa = 0 # total surface area of resulting shapes 68 | x = len(self.grid) - 1 # max i for grid[i][j] 69 | y = len((self.grid[0])) - 1 # max j for grid[i][j] 70 | i = 0 71 | while i <= x: 72 | j = 0 73 | while j <= y: 74 | if self.grid[i][j] != 0: 75 | tsa += self.grid[i][j] * 4 + 2 # surface are at point 76 | # we count the left surface area of this point as follow: 77 | # down close 78 | if i + 1 <= x and self.grid[i + 1][j] >= self.grid[i][j]: 79 | tsa = tsa - 2*self.grid[i][j] 80 | elif i + 1 <= x and self.grid[i + 1][j] < self.grid[i][j]: 81 | tsa = tsa - 2*self.grid[i + 1][j] 82 | # right close 83 | if j + 1 <= y and self.grid[i][j + 1] >= self.grid[i][j]: 84 | tsa = tsa - 2*self.grid[i][j] 85 | elif j + 1 <= y and self.grid[i][j + 1] < self.grid[i][j]: 86 | tsa = tsa - 2*self.grid[i][j + 1] 87 | j = j + 1 88 | i = i + 1 89 | return tsa 90 | 91 | 92 | s = Solution3() 93 | print(s.surfaceArea([[2]])) -------------------------------------------------------------------------------- /963_Minimum_Area_Rectangle_II.py: -------------------------------------------------------------------------------- 1 | ''' 2 | @auther: Jedi.L 3 | @Date: Tue, Apr 30, 2019 3:40 4 | @Email: xiangyangan@gmail.com 5 | @Blog: www.tundrazone.com 6 | ''' 7 | 8 | import itertools 9 | import collections 10 | 11 | 12 | class Solution(object): 13 | def minAreaFreeRect(self, points): 14 | points = [complex(*z) for z in points] 15 | seen = collections.defaultdict(list) 16 | for P, Q in itertools.combinations(points, 2): 17 | center = (P + Q) / 2 # get the center point 18 | radius = abs(center - P) # caculate the distance 19 | # Only record P here, because Q = 2 * center - P 20 | seen[center, radius].append(P) 21 | 22 | res = float("inf") 23 | for (center, radius), candidates in seen.items(): 24 | for P, Q in itertools.combinations(candidates, 2): 25 | # caculate area 26 | res = min(res, abs(P - Q) * abs(P - (2 * center - Q))) 27 | 28 | return res if res < float("inf") else 0 29 | -------------------------------------------------------------------------------- /Exp_470_Expectation calculation.py: -------------------------------------------------------------------------------- 1 | n = 0.0 2 | r = 0.0 3 | 4 | while n < 10000.0: 5 | r = r + (40 / 49) * ((9 / 49)**n) * (n + 1) 6 | n = n + 1.0 7 | 8 | print(r) 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeetCodeByPython 2 | The python codes for problems on LeetCode 3 | 4 | 从2018年进行Leetcode的题目讲解以来,发现大家反馈的主要问题有以下几种: 5 | 6 | 1. 被题目数量吓到:目前题库中的题目快1000了,每天做5个题目也得快200天才能做完。 7 | 2. 做了白做: 花了很大功夫做完的题目,没几天就忘光了 8 | 3. 最优解不好理解:提交的算法都是垫底的,看了别人的算法又理解不深刻 9 | 10 | 针对这些问题,我也进行了反思,最后发现是我去,恐怕是题目的打开方式错了。大多数朋友在进行算法练习的时候都是这样做题的: 11 | 12 | ![顺序做题](https://upload-images.jianshu.io/upload_images/1369466-6db53e58728a1a19.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | 这种做题方式很大程度上造成了“记不住”和“做了白做”的问题,原因是没有形成某一类问题思维体系,下次遇到同类问题,又重头来过。 15 | 16 | 那根据类别做题看起来是个好选择,一些朋友是以这个顺序做的: 17 | 18 | ![类别顺序](https://upload-images.jianshu.io/upload_images/1369466-2fde007be8a75457.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 19 | 20 | 问题是这种模式下你会发现前几个类别的题目数量非常多,做到后面几乎是有种想吐的感觉,没有新鲜感,很多朋友甚至没法坚持做完一个类别。 21 | 22 | ![前几个类别题目数量暴多](https://upload-images.jianshu.io/upload_images/1369466-f1aca2be3fbf92be.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 23 | 24 | 所以,我觉得,正确的做题顺序应该是由类别顺序的从下到上,也就是逆类别做题: 25 | ![正确的打开方式](https://upload-images.jianshu.io/upload_images/1369466-70b17f01cc838e29.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 26 | 27 | 不信你看最下面的类别有多少道题目: 28 | ![逆类别做题](https://upload-images.jianshu.io/upload_images/1369466-49ad301ee107251f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 29 | 30 | 这种做题方式,可以让你很快搞定一些类别,并且有成就感和新鲜感。有朋友说别人的最优解不好理解,网上很多人建议快速刷提,直接看答案然后再做题。这种方式我并不赞同,除了急着找工作的朋友,我觉得练习算法的目的是为了进行思维训练从而更好的解决我们实际应用中遇到问题。所以,不管如何,拿到题目首先一定要尝试自己去解答,即使没有能成功提交,但是再看别人的算法时才能发现思路的差异,也才可以有更深入的理解。 31 | 32 | 最后,不少朋友说,尝试自己求解时一不小心几个钟头就过去了。我的建议是设立Deadline,比如半个小时还没有能解题那么就去看别人的代码,这样来达到效率和理解的平衡。 33 | 34 | 从今年(2019)开始,我会按照类别逆序开始更新,并且对某一类别的题目进行思路总结。本人水平有限,智力不高,但想和大家一同进步,不当之处多多包涵。 35 | 36 | 37 | You can view the problem-solving ideas by visiting: 38 | 苔原带 www.tundrazone.com 39 | 40 | If you have better solutions, welcome to discuss. 41 | 42 | :-D 43 | --------------------------------------------------------------------------------