├── .gitignore ├── 2020 TPC 腾讯程序设计竞赛 ├── 1.py └── 2.py ├── Amazon └── 104. Maximum Depth of Binary Tree.py ├── Arrays ├── 105. 从前序与中序遍历序列构造二叉树.py ├── 106. Construct Binary Tree from Inorder and Postorder Traversal.py ├── 118. Pascal's Triangle.py ├── 119. Pascal's Triangle II.py ├── 120. Triangle.py ├── 122. Best Time to Buy and Sell Stock II.py ├── 1343. 大小为 K 且平均值大于等于阈值的子数组数目.py ├── 16. 最接近的三数之和.py ├── 162. Find Peak Element.py ├── 163. Missing Ranges.py ├── 167. Two Sum II - Input array is sorted.py ├── 169. Majority Element.py ├── 18. 四数之和.py ├── 189. Rotate Array.py ├── 209. Minimum Size Subarray Sum.py ├── 216. Combination Sum III.py ├── 217. Contains Duplicate.py ├── 31. 下一个排列.py ├── 34. 在排序数组中查找元素的第一个和最后一个位置.py ├── 40. Combination Sum II.py ├── 45. Jump Game II - Greedy.py ├── 45. Jump Game II - dp.py ├── 55. Jump Game - Greedy.py ├── 55. Jump Game - dp.py ├── 63. Unique Paths II.py ├── 66. Plus One.py ├── 73. Set Matrix Zeroes.py ├── 74. Search a 2D Matrix.py ├── 80. Remove Duplicates from Sorted Array II.py ├── 81. Search in Rotated Sorted Array II.py └── 90. Subsets II.py ├── Microsoft ├── 1. Two Sum.py ├── 103. Binary Tree Zigzag Level Order Traversal.py ├── 105. Construct Binary Tree from Preorder and Inorder Traversal.py ├── 108. Convert Sorted Array to Binary Search Tree.py ├── 11. Container With Most Water.py ├── 116. Populating Next Right Pointers in Each Node.py ├── 117. Populating Next Right Pointers in Each Node II.py ├── 1185. Day of the Week.py ├── 121. Best Time to Buy and Sell Stock.py ├── 1239. Maximum Length of a Concatenated String with Unique Characters.py ├── 124. Binary Tree Maximum Path Sum.py ├── 125. Valid Palindrome.py ├── 126. Word Ladder II.py ├── 127. Word Ladder.py ├── 129. Sum Root to Leaf Numbers.py ├── 13. Roman to Integer.py ├── 133. Clone Graph.py ├── 134. Gas Station.py ├── 136. Single Number.py ├── 138. Copy List with Random Pointer - 1.py ├── 138. Copy List with Random Pointer - 2.py ├── 14. Longest Common Prefix.py ├── 140. Word Break II.py ├── 142. Linked List Cycle II.py ├── 143. Reorder List.py ├── 146. LRU Cache.py ├── 15. 3Sum.py ├── 151. Reverse Words in a String.py ├── 152. Maximum Product Subarray.py ├── 160. Intersection of Two Linked Lists.py ├── 165. Compare Version Numbers.py ├── 168. Excel Sheet Column Title.py ├── 173. Binary Search Tree Iterator.py ├── 179. Largest Number.py ├── 186. Reverse Words in a String II.py ├── 19. Remove Nth Node From End of List.py ├── 2. Add Two Numbers.py ├── 200. Number of Islands.py ├── 206. Reverse Linked List.py ├── 207. Course Schedule.py ├── 21. Merge Two Sorted Lists.py ├── 210. Course Schedule II.py ├── 212. Word Search II.py ├── 22. Generate Parentheses.py ├── 225. Implement Stack using Queues.py ├── 23. Merge k Sorted Lists.py ├── 232. Implement Queue using Stacks.py ├── 235. Lowest Common Ancestor of a Binary Search Tree.py ├── 236. Lowest Common Ancestor of a Binary Tree.py ├── 24. Swap Nodes in Pairs.py ├── 240. Search a 2D Matrix II.py ├── 242. Valid Anagram.py ├── 243. Shortest Word Distance.py ├── 25. Reverse Nodes in k-Group.py ├── 253. Meeting Rooms II.py ├── 269. Alien Dictionary.py ├── 273. Integer to English Words.py ├── 277. Find the Celebrity.py ├── 28. Implement strStr().py ├── 285. Inorder Successor in BST.py ├── 287. Find the Duplicate Number.py ├── 297. Serialize and Deserialize Binary Tree.py ├── 328. Odd Even Linked List.py ├── 33. Search in Rotated Sorted Array.py ├── 340. Longest Substring with At Most K Distinct Characters.py ├── 346. Moving Average from Data Stream.py ├── 347. Top K Frequent Elements.py ├── 348. Design Tic-Tac-Toe.py ├── 415. Add Strings.py ├── 42. Trapping Rain Water - 1.py ├── 42. Trapping Rain Water - 2.py ├── 431. Encode N-ary Tree to Binary Tree.py ├── 44. Wildcard Matching - 1.py ├── 44. Wildcard Matching - 2.py ├── 443. String Compression.py ├── 445. Add Two Numbers II.py ├── 450. Delete Node in a BST.py ├── 470. Implement Rand10() Using Rand7().py ├── 48. Rotate Image.py ├── 5. Longest Palindromic Substring.py ├── 50. Pow(x, n).py ├── 510. Inorder Successor in BST II.py ├── 53. Maximum Subarray.py ├── 535. Encode and Decode TinyURL.py ├── 54. Spiral Matrix.py ├── 540. Single Element in a Sorted Array.py ├── 557. Reverse Words in a String III.py ├── 56. Merge Intervals.py ├── 636. Exclusive Time of Functions.py ├── 64. Minimum Path Sum.py ├── 669. Trim a Binary Search Tree.py ├── 688. Knight Probability in Chessboard.py ├── 695. Max Area of Island.py ├── 7. Reverse Integer.py ├── 722. Remove Comments.py ├── 75. Sort Colors.py ├── 768. Max Chunks To Make Sorted II.py ├── 769. Max Chunks To Make Sorted.py ├── 78. Subsets.py ├── 785. Is Graph Bipartite.py ├── 79. Word Search.py ├── 794. Valid Tic-Tac-Toe State.py ├── 8. String to Integer (atoi).py ├── 836. Rectangle Overlap.py ├── 863. All Nodes Distance K in Binary Tree.py ├── 909. Snakes and Ladders.py ├── 93. Restore IP Addresses.py ├── 98. Validate Binary Search Tree.py └── 99. Recover Binary Search Tree.py ├── Notes ├── 2020.1.22.md ├── 2020.1.23.md ├── 2020.1.24.md ├── 2020.1.26.md ├── 2020.1.27.md ├── 2020.1.28.md ├── 2020.1.29.md ├── 2020.1.30.md ├── 2020.1.31.md ├── 2020.2.1.md ├── 2020.2.10.md ├── 2020.2.11.md ├── 2020.2.12.md ├── 2020.2.13.md ├── 2020.2.15.md ├── 2020.2.17.md ├── 2020.2.19.md ├── 2020.2.20.md ├── 2020.2.21.md ├── 2020.2.22.md ├── 2020.2.23.md ├── 2020.2.25.md ├── 2020.2.26.md ├── 2020.2.27.md ├── 2020.2.28.md ├── 2020.2.29.md ├── 2020.2.3.md ├── 2020.2.4.md ├── 2020.2.5.md ├── 2020.2.6.md ├── 2020.2.7.md ├── 2020.2.8.md ├── 2020.2.9.md ├── 2020.3.1.md ├── 2020.3.12.md ├── 2020.3.3.md ├── 2020.3.4.md ├── 2020.3.5.md ├── 2020.3.6.md ├── 2020.3.7.md └── 2020.3.8.md ├── README.md └── problems ├── 114. 二叉树展开为链表.py ├── 199. Binary Tree Right Side View.py ├── 200. Number of Islands(DFS).py ├── 200. Number of Islands.py ├── 26. 删除排序数组中的重复项.py ├── 27. 移除元素-2.py ├── 27. 移除元素.py ├── 35. 搜索插入位置.py ├── 415. 字符串相加.py ├── 6. ZigZag Conversion.py ├── 9. Palindrome Number.py └── 剑指 Offer 10- I. 斐波那契数列.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### playground 3 | playground.py 4 | ### macOS template 5 | # General 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # Icon must end with two \r 11 | Icon 12 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | .com.apple.timemachine.donotpresent 24 | 25 | # Directories potentially created on remote AFP share 26 | .AppleDB 27 | .AppleDesktop 28 | Network Trash Folder 29 | Temporary Items 30 | .apdisk 31 | ### Python template 32 | # Byte-compiled / optimized / DLL files 33 | __pycache__/ 34 | *.py[cod] 35 | *$py.class 36 | 37 | # C extensions 38 | *.so 39 | 40 | # Distribution / packaging 41 | .Python 42 | build/ 43 | develop-eggs/ 44 | dist/ 45 | downloads/ 46 | eggs/ 47 | .eggs/ 48 | lib/ 49 | lib64/ 50 | parts/ 51 | sdist/ 52 | var/ 53 | wheels/ 54 | *.egg-info/ 55 | .installed.cfg 56 | *.egg 57 | MANIFEST 58 | 59 | # PyInstaller 60 | # Usually these files are written by a python script from a template 61 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 62 | *.manifest 63 | *.spec 64 | 65 | # Installer logs 66 | pip-log.txt 67 | pip-delete-this-directory.txt 68 | 69 | # Unit test / coverage reports 70 | htmlcov/ 71 | .tox/ 72 | .coverage 73 | .coverage.* 74 | .cache 75 | nosetests.xml 76 | coverage.xml 77 | *.cover 78 | .hypothesis/ 79 | .pytest_cache/ 80 | 81 | # Translations 82 | *.mo 83 | *.pot 84 | 85 | # Django stuff: 86 | *.log 87 | local_settings.py 88 | db.sqlite3 89 | 90 | # Flask stuff: 91 | instance/ 92 | .webassets-cache 93 | 94 | # Scrapy stuff: 95 | .scrapy 96 | 97 | # Sphinx documentation 98 | docs/_build/ 99 | 100 | # PyBuilder 101 | target/ 102 | 103 | # Jupyter Notebook 104 | .ipynb_checkpoints 105 | 106 | # pyenv 107 | .python-version 108 | 109 | # celery beat schedule file 110 | celerybeat-schedule 111 | 112 | # SageMath parsed files 113 | *.sage.py 114 | 115 | # Environments 116 | .env 117 | .venv 118 | env/ 119 | venv/ 120 | ENV/ 121 | env.bak/ 122 | venv.bak/ 123 | 124 | # Spyder project settings 125 | .spyderproject 126 | .spyproject 127 | 128 | # Rope project settings 129 | .ropeproject 130 | 131 | # mkdocs documentation 132 | /site 133 | 134 | # mypy 135 | .mypy_cache/ 136 | 137 | # Pycharm 138 | .idea 139 | 140 | # VsCode 141 | .vscode -------------------------------------------------------------------------------- /2020 TPC 腾讯程序设计竞赛/1.py: -------------------------------------------------------------------------------- 1 | length = int(input()) 2 | arr = [] 3 | 4 | for _ in range(length): 5 | arr.append(int(input())) 6 | 7 | for i in arr: 8 | if i >= 1: 9 | print('You are the future of Tencent!') 10 | else: 11 | print('Good luck and Enjoy TPC!') 12 | -------------------------------------------------------------------------------- /2020 TPC 腾讯程序设计竞赛/2.py: -------------------------------------------------------------------------------- 1 | def max_total(arr, n, m): 2 | if len(arr) < 3: 3 | return sum(arr) 4 | 5 | for i in range(2, n): 6 | target_index = -1 7 | cur_memes = m 8 | for j in range(i - 2, i + 1): 9 | if arr[j] == -1: 10 | target_index = j 11 | else: 12 | cur_memes -= arr[j] 13 | 14 | if target_index != -1: 15 | if cur_memes <= 0: 16 | arr[target_index] = 0 17 | else: 18 | arr[target_index] = cur_memes 19 | else: 20 | print(arr[i], arr, cur_memes) 21 | if cur_memes > 0: 22 | return 'Impossible' 23 | return sum(arr) 24 | 25 | 26 | test_num = int(input()) 27 | 28 | test_cases = [] 29 | 30 | for _ in range(test_num): 31 | [n, m] = list(map(int, input().split(' '))) 32 | 33 | test_cases.append({ 34 | "n": n, 35 | "m": m, 36 | "arr": list(map(int, input().split(' '))) 37 | }) 38 | 39 | for t in test_cases: 40 | n, m, arr = t 41 | print(max_total(t["arr"], t["n"], t["m"])) 42 | -------------------------------------------------------------------------------- /Amazon/104. Maximum Depth of Binary Tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution: 9 | def maxDepth(self, root: TreeNode) -> int: 10 | if root is None: 11 | return 0 12 | 13 | left = self.maxDepth(root.left) 14 | right = self.maxDepth(root.right) 15 | 16 | return max(left, right) + 1 17 | -------------------------------------------------------------------------------- /Arrays/105. 从前序与中序遍历序列构造二叉树.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | from typing import List 3 | 4 | 5 | class TreeNode: 6 | def __init__(self, x): 7 | self.val = x 8 | self.left = None 9 | self.right = None 10 | 11 | class Solution: 12 | def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: 13 | if not inorder: 14 | return None 15 | 16 | root = TreeNode(preorder[0]) 17 | 18 | rootPos = inorder.index(preorder[0]) 19 | 20 | root.left = self.buildTree(preorder[1: 1 + rootPos], inorder[:rootPos]) 21 | root.right = self.buildTree(preorder[rootPos + 1:], inorder[rootPos + 1:]) 22 | 23 | return root 24 | -------------------------------------------------------------------------------- /Arrays/106. Construct Binary Tree from Inorder and Postorder Traversal.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | from typing import List 3 | 4 | 5 | class TreeNode: 6 | def __init__(self, x): 7 | self.val = x 8 | self.left = None 9 | self.right = None 10 | 11 | class Solution: 12 | def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: 13 | if not postorder: 14 | return None 15 | 16 | root = TreeNode(postorder[-1]) 17 | root_pos = inorder.index(postorder[-1]) 18 | 19 | root.left = self.buildTree(inorder[:root_pos], postorder[:root_pos]) 20 | root.right = self.buildTree(inorder[root_pos + 1:], postorder[root_pos:-1]) 21 | 22 | return root 23 | -------------------------------------------------------------------------------- /Arrays/118. Pascal's Triangle.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def generate(self, num_rows: int) -> List[List[int]]: 6 | triangle = [] 7 | 8 | for i in range(num_rows): 9 | rows = [None] * (i + 1) 10 | rows[0], rows[-1] = 1, 1 11 | 12 | for j in range(1, i): 13 | rows[j] = triangle[i - 1][j - 1] + triangle[i - 1][j] 14 | 15 | triangle.append(rows) 16 | 17 | return triangle 18 | -------------------------------------------------------------------------------- /Arrays/119. Pascal's Triangle II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def getRow(self, rowIndex: int) -> List[int]: 6 | rows = [1] 7 | for i in range(1, rowIndex + 1): 8 | rows.insert(0, 0) 9 | for j in range(i): 10 | rows[j] = rows[j] + rows[j + 1] 11 | return rows 12 | -------------------------------------------------------------------------------- /Arrays/120. Triangle.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def minimumTotal(self, triangle: List[List[int]]) -> int: 6 | if not triangle: 7 | return 0 8 | 9 | n = len(triangle) 10 | dp = [[0] * n for _ in range(n)] 11 | dp[0][0] = triangle[0][0] 12 | 13 | for i in range(1, n): 14 | # 最左边 15 | dp[i][0] = dp[i - 1][0] + triangle[i][0] 16 | for j in range(1, i): 17 | dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j] 18 | # 最右边 19 | dp[i][i] = dp[i - 1][i - 1] + triangle[i][i] 20 | 21 | return min(dp[n - 1]) 22 | -------------------------------------------------------------------------------- /Arrays/122. Best Time to Buy and Sell Stock II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | # 只能买卖一次,相加差值就好了 6 | def maxProfit(self, prices: List[int]) -> int: 7 | if not prices: 8 | return 0 9 | 10 | profit = 0 11 | for i in range(1, len(prices)): 12 | if prices[i] - prices[i - 1] > 0: 13 | profit += prices[i] - prices[i - 1] 14 | 15 | return profit 16 | -------------------------------------------------------------------------------- /Arrays/1343. 大小为 K 且平均值大于等于阈值的子数组数目.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def numOfSubarrays(self, arr: List[int], k: int, threshold: int) -> int: 6 | result = 0 7 | cur_sum = 0 8 | 9 | for i in range(k): 10 | cur_sum += arr[i] 11 | 12 | for i in range(k, len(arr)): 13 | if cur_sum >= threshold * k: 14 | result += 1 15 | 16 | cur_sum += arr[i] 17 | cur_sum -= arr[i - k] 18 | 19 | if cur_sum >= threshold * k: 20 | result += 1 21 | 22 | return result 23 | -------------------------------------------------------------------------------- /Arrays/16. 最接近的三数之和.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def threeSumClosest(self, nums: List[int], target: int) -> int: 6 | if not nums or len(nums) < 3: 7 | return 0 8 | 9 | nums = sorted(nums) 10 | closest = float('inf') 11 | n = len(nums) 12 | 13 | for i in range(n - 2): 14 | if i > 0 and nums[i - 1] == nums[i]: 15 | continue 16 | 17 | left, right = i + 1, n - 1 18 | while left < right: 19 | cur_sum = nums[i] + nums[left] + nums[right] 20 | 21 | if abs(cur_sum - target) < abs(closest - target): 22 | closest = cur_sum 23 | 24 | if cur_sum < target: 25 | left += 1 26 | elif cur_sum > target: 27 | right -= 1 28 | else: 29 | return cur_sum 30 | return closest 31 | -------------------------------------------------------------------------------- /Arrays/162. Find Peak Element.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findPeakElement(self, nums: List[int]) -> int: 6 | if not nums: 7 | return -1 8 | 9 | left, right = 0, len(nums) - 1 10 | while left + 1 < right: 11 | mid = (left + right) // 2 12 | 13 | if nums[mid - 1] < nums[mid]: 14 | left = mid 15 | else: 16 | right = mid 17 | 18 | if nums[left] < nums[right]: 19 | return right 20 | else: 21 | return left 22 | -------------------------------------------------------------------------------- /Arrays/163. Missing Ranges.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findMissingRanges(self, nums: List[int], lower: int, upper: int) -> List[str]: 3 | results = [] 4 | if not nums: 5 | results.append(self.helper(lower, upper)) 6 | return results 7 | 8 | pre_point = lower - 1 9 | 10 | for point in nums: 11 | if pre_point != point and pre_point + 1 != point: 12 | results.append(self.helper(pre_point + 1, point - 1)) 13 | pre_point = point 14 | 15 | if nums[-1] < upper: 16 | results.append(self.helper(nums[-1] + 1, upper)) 17 | 18 | return results 19 | 20 | 21 | def helper(self, lower, upper): 22 | if lower == upper: 23 | return str(lower) 24 | 25 | return str(lower) + '->' + str(upper) 26 | 27 | -------------------------------------------------------------------------------- /Arrays/167. Two Sum II - Input array is sorted.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def twoSum(self, numbers: List[int], target: int) -> List[int]: 5 | left, right = 0, len(numbers) - 1 6 | 7 | while left < right: 8 | cur_sum = numbers[left] + numbers[right] 9 | 10 | if cur_sum < target: 11 | left += 1 12 | elif cur_sum > target: 13 | right -= 1 14 | else: 15 | return [left + 1, right + 1] 16 | 17 | return [] 18 | -------------------------------------------------------------------------------- /Arrays/169. Majority Element.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def majorityElement(self, nums: List[int]) -> int: 5 | key, count = None, 0 6 | 7 | for num in nums: 8 | if count == 0: 9 | key, count = num, 1 10 | elif key == num: 11 | count += 1 12 | else: 13 | count -= 1 14 | 15 | return key 16 | -------------------------------------------------------------------------------- /Arrays/18. 四数之和.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def fourSum(self, nums: List[int], target: int) -> List[List[int]]: 6 | if not nums or len(nums) < 4: 7 | return [] 8 | 9 | nums = sorted(nums) 10 | results = [] 11 | n = len(nums) 12 | 13 | for i in range(n - 3): 14 | if i > 0 and nums[i] == nums[i - 1]: 15 | continue 16 | self.find_3_sum(nums, nums[i], i + 1, n, target - nums[i], results) 17 | 18 | return results 19 | 20 | def find_3_sum(self, nums, first, start, n, target, results): 21 | for i in range(start, n - 2): 22 | if i > start and nums[i] == nums[i - 1]: 23 | continue 24 | self.find_2_sum(nums, first, nums[i], i + 1, n - 1, target - nums[i], results) 25 | 26 | def find_2_sum(self, nums, first, second, left, right, target, results): 27 | while left < right: 28 | cur_sum = nums[left] + nums[right] 29 | if cur_sum < target: 30 | left += 1 31 | elif cur_sum > target: 32 | right -= 1 33 | else: 34 | results.append([first, second, nums[left], nums[right]]) 35 | left += 1 36 | right -= 1 37 | while left < right and nums[left - 1] == nums[left]: 38 | left += 1 39 | while left < right and nums[right] == nums[right + 1]: 40 | right -= 1 41 | -------------------------------------------------------------------------------- /Arrays/189. Rotate Array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rotate(self, nums: List[int], k: int) -> None: 3 | if (len(nums) <= 1): 4 | return 5 | 6 | length = len(nums) 7 | k = k % length 8 | 9 | self.reverse(nums, 0, length - 1) 10 | self.reverse(nums, 0, k - 1) 11 | self.reverse(nums, k, length - 1) 12 | 13 | 14 | def reverse(self, nums, start, end): 15 | while start < end: 16 | nums[start], nums[end] = nums[end], nums[start] 17 | start, end = start + 1, end - 1 18 | -------------------------------------------------------------------------------- /Arrays/209. Minimum Size Subarray Sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minSubArrayLen(self, s: int, nums: List[int]) -> int: 3 | if not nums: 4 | return 0 5 | 6 | j, n, curt_sum = 0, len(nums), 0 7 | min_len = n + 1 8 | 9 | for i in range(n): 10 | while j < n and curt_sum < s: 11 | curt_sum += nums[j] 12 | j += 1 13 | 14 | if curt_sum >= s: 15 | min_len = min(min_len, j - i) 16 | 17 | curt_sum -= nums[i] 18 | 19 | return 0 if min_len == n + 1 else min_len 20 | -------------------------------------------------------------------------------- /Arrays/216. Combination Sum III.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def combinationSum3(self, k: int, n: int) -> List[List[int]]: 3 | self.res = [] 4 | 5 | self.helper([], 1, k, n) 6 | 7 | return self.res 8 | 9 | def helper(self, curt, index, k, n): 10 | if k == 0: 11 | if sum(curt) == n: 12 | self.res.append(curt[:]) 13 | return 14 | 15 | for i in range(index, 10): 16 | curt.append(i) 17 | if sum(curt) <= n: 18 | self.helper(curt, i + 1, k - 1, n) 19 | curt.pop() 20 | -------------------------------------------------------------------------------- /Arrays/217. Contains Duplicate.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def containsDuplicate(self, nums: List[int]) -> bool: 3 | s = set(nums) 4 | 5 | return len(s) != len(nums) 6 | -------------------------------------------------------------------------------- /Arrays/31. 下一个排列.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def nextPermutation(self, nums: List[int]) -> None: 6 | i = len(nums) - 2 7 | 8 | # 找到 nums[i] < nums[i + 1] 对 9 | while i >= 0 and nums[i] >= nums[i + 1]: 10 | i -= 1 11 | 12 | if i >= 0: 13 | j = len(nums) - 1 14 | # 找到 nums[i] < nums[j] 对 15 | while j >= 0 and nums[j] <= nums[i]: 16 | j -= 1 17 | 18 | nums[i], nums[j] = nums[j], nums[i] 19 | 20 | self.reverse(nums, i + 1, len(nums) - 1) 21 | 22 | def reverse(self, nums, start, end): 23 | while start < end: 24 | nums[start], nums[end] = nums[end], nums[start] 25 | start += 1 26 | end -= 1 27 | -------------------------------------------------------------------------------- /Arrays/34. 在排序数组中查找元素的第一个和最后一个位置.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def searchRange(self, nums: List[int], target: int) -> List[int]: 6 | if not nums or len(nums) == 0: 7 | return [-1, -1] 8 | 9 | first_pos = self.find_first(nums, target) 10 | last_pos = self.find_last(nums, target) 11 | 12 | return [first_pos, last_pos] 13 | 14 | def find_first(self, nums, target): 15 | left, right = 0, len(nums) - 1 16 | 17 | while left + 1 < right: 18 | mid = (left + right) // 2 19 | 20 | if nums[mid] < target: 21 | left = mid 22 | else: 23 | right = mid 24 | 25 | if nums[left] == target: 26 | return left 27 | if nums[right] == target: 28 | return right 29 | return -1 30 | 31 | def find_last(self, nums, target): 32 | left, right = 0, len(nums) - 1 33 | 34 | while left + 1 < right: 35 | mid = (left + right) // 2 36 | 37 | if nums[mid] > target: 38 | right = mid 39 | else: 40 | left = mid 41 | 42 | if nums[right] == target: 43 | return right 44 | if nums[left] == target: 45 | return left 46 | return -1 47 | -------------------------------------------------------------------------------- /Arrays/40. Combination Sum II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: 6 | if not candidates: 7 | return [] 8 | 9 | results = [] 10 | 11 | nums = sorted(candidates) 12 | visited = [0 for _ in range(len(candidates))] 13 | 14 | self.dfs(nums, visited, 0, target, [], results) 15 | 16 | return results 17 | 18 | def dfs(self, nums, visited, index, target, path, results): 19 | if target < 0: 20 | return 21 | 22 | if target == 0: 23 | results.append(path[:]) 24 | return 25 | 26 | for i in range(index, len(nums)): 27 | if i > 0 and nums[i] == nums[i - 1] and not visited[i - 1]: 28 | continue 29 | 30 | path.append(nums[i]) 31 | visited[i] = 1 32 | self.dfs(nums, visited, i + 1, target - nums[i], path, results) 33 | visited[i] = 0 34 | path.pop() 35 | -------------------------------------------------------------------------------- /Arrays/45. Jump Game II - Greedy.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def jump(self, nums: List[int]) -> int: 6 | if not nums: 7 | return -1 8 | 9 | n, right_most, end = len(nums), 0, 0 10 | step = 0 11 | 12 | for i in range(n - 1): 13 | right_most = max(right_most, i + nums[i]) 14 | 15 | if i == end: 16 | end = right_most 17 | step += 1 18 | 19 | return step 20 | -------------------------------------------------------------------------------- /Arrays/45. Jump Game II - dp.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def jump(self, nums: List[int]) -> int: 6 | if not nums: 7 | return -1 8 | 9 | n = len(nums) 10 | dp = [float('inf')] * n 11 | dp[0] = 0 12 | 13 | for i in range(1, n): 14 | for j in range(i): 15 | if j + nums[j] >= i: 16 | dp[i] = min(dp[i], dp[j] + 1) 17 | break 18 | 19 | return dp[-1] 20 | -------------------------------------------------------------------------------- /Arrays/55. Jump Game - Greedy.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canJump(self, nums: List[int]) -> bool: 6 | if not nums: 7 | return False 8 | 9 | n, right_most = len(nums), 0 10 | 11 | for i in range(n): 12 | if right_most >= i: 13 | right_most = max(right_most, nums[i] + i) 14 | if right_most >= n - 1: 15 | return True 16 | 17 | return False 18 | -------------------------------------------------------------------------------- /Arrays/55. Jump Game - dp.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canJump(self, nums: List[int]) -> bool: 6 | if not nums: 7 | return False 8 | 9 | dp = [False] * len(nums) 10 | dp[0] = True 11 | 12 | for i in range(1, len(nums)): 13 | for j in range(i): 14 | if dp[j] and j + nums[j] >= i: 15 | dp[i] = True 16 | break 17 | 18 | return dp[-1] 19 | -------------------------------------------------------------------------------- /Arrays/63. Unique Paths II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: 6 | if not obstacleGrid: 7 | return 0 8 | 9 | rows, cols = len(obstacleGrid), len(obstacleGrid[0]) 10 | dp = [[0] * cols] * rows 11 | 12 | for i in range(rows): 13 | for j in range(cols): 14 | if obstacleGrid[i][j] == 1: 15 | dp[i][j] = 0 16 | continue 17 | 18 | if i == 0 and j == 0: 19 | dp[i][j] = 1 20 | elif i == 0: 21 | dp[i][j] = dp[i][j - 1] 22 | elif j == 0: 23 | dp[i][j] = dp[i - 1][j] 24 | else: 25 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 26 | 27 | return dp[-1][-1] -------------------------------------------------------------------------------- /Arrays/66. Plus One.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def plusOne(self, digits: List[int]) -> List[int]: 6 | if not digits: 7 | return digits 8 | 9 | carrier = 1 10 | 11 | for i in range(len(digits) - 1, -1, -1): 12 | if carrier == 0: 13 | break 14 | 15 | carrier, digits[i] = divmod(digits[i] + carrier, 10) 16 | 17 | if carrier == 1: 18 | digits = [1] + digits 19 | 20 | return digits 21 | -------------------------------------------------------------------------------- /Arrays/73. Set Matrix Zeroes.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def setZeroes(self, matrix: List[List[int]]) -> None: 6 | if not matrix or not matrix[0]: 7 | return 8 | 9 | rows_num, cols_num = len(matrix), len(matrix[0]) 10 | rows, cols = [False] * rows_num, [False] * cols_num 11 | 12 | for i in range(rows_num): 13 | for j in range(cols_num): 14 | if matrix[i][j] == 0: 15 | rows[i], cols[j] = True, True 16 | 17 | for i in range(rows_num): 18 | for j in range(cols_num): 19 | if rows[i] or cols[j]: 20 | matrix[i][j] = 0 21 | -------------------------------------------------------------------------------- /Arrays/74. Search a 2D Matrix.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: 6 | if not matrix or not matrix[0]: 7 | return False 8 | 9 | rows, cols = len(matrix), len(matrix[0]) 10 | x, y = rows - 1, 0 11 | 12 | while x >= 0 and y < cols: 13 | if matrix[x][y] < target: 14 | y += 1 15 | elif matrix[x][y] > target: 16 | x -= 1 17 | else: 18 | return True 19 | 20 | return False 21 | -------------------------------------------------------------------------------- /Arrays/80. Remove Duplicates from Sorted Array II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def removeDuplicates(self, nums: List[int]) -> int: 6 | if not nums: 7 | return 0 8 | 9 | index, count = 0, 1 10 | for i in range(1, len(nums)): 11 | if nums[i] == nums[index]: 12 | if count < 2: 13 | index += 1 14 | nums[index] = nums[i] 15 | count += 1 16 | else: 17 | index += 1 18 | nums[index] = nums[i] 19 | count = 1 20 | 21 | return index + 1 22 | -------------------------------------------------------------------------------- /Arrays/81. Search in Rotated Sorted Array II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def search(self, nums: List[int], target: int) -> bool: 6 | if not nums: 7 | return False 8 | 9 | for i in range(len(nums)): 10 | if nums[i] == target: 11 | return True 12 | 13 | return False 14 | -------------------------------------------------------------------------------- /Arrays/90. Subsets II.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: 6 | if not nums: 7 | return [] 8 | 9 | nums = sorted(nums) 10 | 11 | path = [] 12 | self.results = [] 13 | 14 | self.dfs(nums, 0, len(nums), path) 15 | 16 | return self.results 17 | 18 | def dfs(self, nums, index, length, path): 19 | if index > length: 20 | return 21 | 22 | self.results.append(path[:]) 23 | 24 | for i in range(index, length): 25 | if i > index and nums[i] == nums[i - 1]: 26 | continue 27 | path.append(nums[i]) 28 | self.dfs(nums, i + 1, length, path) 29 | path.pop() 30 | -------------------------------------------------------------------------------- /Microsoft/1. Two Sum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def twoSum(self, nums, target): 3 | store = {} 4 | 5 | for i, num in enumerate(nums): 6 | if target - num in store: 7 | return [store[target - num], i] 8 | store[num] = i 9 | 10 | return [-1, -1] 11 | -------------------------------------------------------------------------------- /Microsoft/103. Binary Tree Zigzag Level Order Traversal.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class TreeNode: 5 | def __init__(self, x): 6 | self.val = x 7 | self.left = None 8 | self.right = None 9 | 10 | 11 | class Solution: 12 | def zigzagLevelOrder(self, root: TreeNode): 13 | if root is None: 14 | return [] 15 | 16 | flag = True 17 | queue = deque([root]) 18 | order = [] 19 | 20 | while queue: 21 | level = [] 22 | if flag: 23 | order.append([node.val for node in queue]) 24 | else: 25 | order.append([node.val for node in queue[::-1]]) 26 | 27 | for node in queue: 28 | if node.left: 29 | level.append(node.left) 30 | if node.right: 31 | level.append(node.right) 32 | 33 | queue = level 34 | flag = not flag 35 | 36 | return order 37 | -------------------------------------------------------------------------------- /Microsoft/105. Construct Binary Tree from Preorder and Inorder Traversal.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def buildTree(self, preorder, inorder) -> TreeNode: 9 | if not preorder or not inorder: 10 | return None 11 | 12 | root = TreeNode(preorder[0]) 13 | index = inorder.index(root.val) 14 | 15 | root.left = self.buildTree(preorder[1:index + 1], inorder[:index]) 16 | root.right = self.buildTree(preorder[index + 1:], inorder[index + 1:]) 17 | 18 | return root 19 | -------------------------------------------------------------------------------- /Microsoft/108. Convert Sorted Array to Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def sortedArrayToBST(self, nums) -> TreeNode: 9 | return self.divide_conquer(nums, 0, len(nums) - 1) 10 | 11 | def divide_conquer(self, nums, left, right): 12 | if left > right: 13 | return None 14 | 15 | mid = (left + right) // 2 16 | 17 | root = TreeNode(nums[mid]) 18 | root.left = self.divide_conquer(nums, left, mid - 1) 19 | root.right = self.divide_conquer(nums, mid + 1, right) 20 | 21 | return root 22 | -------------------------------------------------------------------------------- /Microsoft/11. Container With Most Water.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxArea(self, heights) -> int: 3 | if not heights: 4 | return 0 5 | 6 | left, right = 0, len(heights) - 1 7 | max_area = 0 8 | while left < right: 9 | if heights[left] < heights[right]: 10 | area = heights[left] * (right - left) 11 | left += 1 12 | else: 13 | area = heights[right] * (right - left) 14 | right -= 1 15 | max_area = max(max_area, area) 16 | return max_area 17 | -------------------------------------------------------------------------------- /Microsoft/116. Populating Next Right Pointers in Each Node.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Node: 4 | def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None): 5 | self.val = val 6 | self.left = left 7 | self.right = right 8 | self.next = next 9 | 10 | 11 | class Solution: 12 | def connect(self, root: 'Node') -> 'Node': 13 | if root is None: 14 | return root 15 | 16 | dummy = Node() 17 | 18 | queue = deque([root]) 19 | while queue: 20 | node = dummy 21 | for _ in range(len(queue)): 22 | curt = queue.popleft() 23 | 24 | node.next = curt 25 | node = node.next 26 | 27 | if node.left: 28 | queue.append(node.left) 29 | if node.right: 30 | queue.append(node.right) 31 | 32 | return root 33 | -------------------------------------------------------------------------------- /Microsoft/117. Populating Next Right Pointers in Each Node II.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Node: 4 | def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None): 5 | self.val = val 6 | self.left = left 7 | self.right = right 8 | self.next = next 9 | 10 | 11 | class Solution: 12 | def connect(self, root: 'Node') -> 'Node': 13 | if root is None: 14 | return None 15 | 16 | queue = deque([root]) 17 | while queue: 18 | # Make a list 19 | self.make_list(queue) 20 | 21 | for _ in range(len(queue)): 22 | node = queue.popleft() 23 | if node.left: 24 | queue.append(node.left) 25 | if node.right: 26 | queue.append(node.right) 27 | return root 28 | 29 | def make_list(self, queue): 30 | for i in range(len(queue) - 1): 31 | queue[i].next = queue[i + 1] 32 | -------------------------------------------------------------------------------- /Microsoft/1185. Day of the Week.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.dayNames = ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] 4 | self.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 5 | 6 | def dayOfTheWeek(self, day: int, month: int, year: int) -> str: 7 | known_start = self.daysSinceStart(22, 2, 2020) 8 | target = self.daysSinceStart(day, month, year) 9 | return self.dayNames[(target - known_start) % 7] 10 | 11 | def daysSinceStart(self, day, month, year): 12 | num_days = 0 13 | # Year 14 | for y in range(year - 1, 1970, -1): 15 | num_days += 365 + self.has_leap_year(y) 16 | # Month 17 | num_days += sum(self.daysInMonth[:month - 1]) 18 | if month > 2: 19 | num_days += self.has_leap_year(year) 20 | # Day 21 | num_days += day 22 | 23 | return num_days 24 | 25 | def has_leap_year(self, year): 26 | return 1 if year % 4 == 0 and year % 100 != 0 or year % 400 == 0 else 0 27 | -------------------------------------------------------------------------------- /Microsoft/121. Best Time to Buy and Sell Stock.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxProfit(self, prices) -> int: 3 | if not prices: 4 | return 0 5 | 6 | min_price, max_profit = float('inf'), 0 7 | for price in prices: 8 | min_price = min(min_price, price) 9 | max_profit = max(max_profit, price - min_price) 10 | return max_profit 11 | -------------------------------------------------------------------------------- /Microsoft/1239. Maximum Length of a Concatenated String with Unique Characters.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.max_len = 0 4 | 5 | def maxLength(self, arr): 6 | if not arr: 7 | return 0 8 | 9 | self.dfs(0, [], arr) 10 | 11 | return self.max_len 12 | 13 | def dfs(self, index, curt, arr): 14 | concatenate = ''.join(curt) 15 | 16 | if len(concatenate) == len(set(concatenate)): 17 | self.max_len = max(self.max_len, len(concatenate)) 18 | if len(concatenate) > len(set(concatenate)): 19 | return 20 | 21 | for i in range(index, len(arr)): 22 | curt.append(arr[i]) 23 | self.dfs(i + 1, curt, arr) 24 | curt.pop() 25 | -------------------------------------------------------------------------------- /Microsoft/124. Binary Tree Maximum Path Sum.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def maxPathSum(self, root: TreeNode) -> int: 9 | if root is None: 10 | return 0 11 | 12 | max_sum, _ = self.dfs(root) 13 | 14 | return max_sum 15 | 16 | def dfs(self, root): 17 | if root is None: 18 | return float('-inf'), 0 19 | 20 | left_max_sum, left_single = self.dfs(root.left) 21 | right_max_sum, right_single = self.dfs(root.right) 22 | 23 | max_sum = max(left_max_sum, right_max_sum, left_single + root.val + right_single) 24 | single = max(left_single + root.val, right_single + root.val, 0) 25 | 26 | return max_sum, single 27 | -------------------------------------------------------------------------------- /Microsoft/125. Valid Palindrome.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self, s: str) -> bool: 3 | clean_str = '' 4 | for char in s: 5 | if char.isdigit() or char.isalpha(): 6 | clean_str += char.lower() 7 | 8 | n = len(clean_str) 9 | left = n // 2 - 1 10 | right = left + (1 if n % 2 == 0 else 2) 11 | 12 | while 0 <= left and right < n: 13 | if clean_str[left] != clean_str[right]: 14 | return False 15 | left -= 1 16 | right += 1 17 | return True 18 | -------------------------------------------------------------------------------- /Microsoft/126. Word Ladder II.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def findLadders(self, beginWord: str, endWord: str, wordList): 5 | wordList = set(wordList) 6 | wordList.add(beginWord) 7 | 8 | distance = {} 9 | 10 | self.bfs(endWord, distance, wordList) 11 | 12 | results = [] 13 | self.dfs(beginWord, endWord, distance, wordList, [beginWord], results) 14 | 15 | return results 16 | 17 | def bfs(self, start, distance, wordList): 18 | distance[start] = 0 19 | queue = deque([start]) 20 | while queue: 21 | word = queue.popleft() 22 | for next_word in self.get_next_words(word, wordList): 23 | if next_word not in distance: 24 | distance[next_word] = distance[word] + 1 25 | queue.append(next_word) 26 | 27 | def get_next_words(self, word, wordList): 28 | next_words = [] 29 | for i in range(len(word)): 30 | for char in 'abcdefghijklmnopqrstuvwxyz': 31 | next_word = word[:i] + char + word[i + 1:] 32 | if next_word != word and next_word in wordList: 33 | next_words.append(next_word) 34 | return next_words 35 | 36 | def dfs(self, curt, target, distance, wordList, path, results): 37 | if curt == target: 38 | results.append(path[:]) 39 | return 40 | 41 | for word in self.get_next_words(curt, wordList): 42 | if distance[word] != distance[curt] - 1: 43 | continue 44 | 45 | path.append(word) 46 | self.dfs(word, target, distance, wordList, path, results) 47 | path.pop() 48 | -------------------------------------------------------------------------------- /Microsoft/127. Word Ladder.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def ladderLength(self, beginWord, endWord, wordList) -> int: 5 | queue = deque([beginWord]) 6 | visited = {beginWord} 7 | wordList = set(wordList) 8 | 9 | steps = 1 10 | 11 | while queue: 12 | for _ in range(len(queue)): 13 | word = queue.popleft() 14 | 15 | if word == endWord: 16 | return steps 17 | 18 | for next_word in self.get_next_words(word, wordList, visited): 19 | queue.append(next_word) 20 | visited.add(next_word) 21 | steps += 1 22 | 23 | return 0 24 | 25 | def get_next_words(self, word, wordList, visited): 26 | next_words = [] 27 | for i in range(len(word)): 28 | for char in 'abcdefghijklmnopqrstuvwxyz': 29 | if char == word[i]: 30 | continue 31 | next_word = word[:i] + char + word[i + 1:] 32 | if next_word not in visited and next_word in wordList: 33 | next_words.append(next_word) 34 | return next_words 35 | -------------------------------------------------------------------------------- /Microsoft/129. Sum Root to Leaf Numbers.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def sumNumbers(self, root: TreeNode) -> int: 9 | return self.dfs(root, 0) 10 | 11 | def dfs(self, root, prev): 12 | if root is None: 13 | return 0 14 | 15 | curt = 10 * prev + root.val 16 | if not root.left and not root.right: 17 | return curt 18 | 19 | return self.dfs(root.left, curt) + self.dfs(root.right, curt) 20 | -------------------------------------------------------------------------------- /Microsoft/13. Roman to Integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def romanToInt(self, s: str) -> int: 3 | ROMAN = { 4 | 'I': 1, 5 | 'V': 5, 6 | 'X': 10, 7 | 'L': 50, 8 | 'C': 100, 9 | 'D': 500, 10 | 'M': 1000 11 | } 12 | 13 | result = ROMAN[s[-1]] 14 | for index in range(len(s) - 2, -1, -1): 15 | if ROMAN[s[index]] < ROMAN[s[index + 1]]: 16 | result -= ROMAN[s[index]] 17 | else: 18 | result += ROMAN[s[index]] 19 | return result 20 | -------------------------------------------------------------------------------- /Microsoft/133. Clone Graph.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Node: 4 | def __init__(self, val = 0, neighbors = []): 5 | self.val = val 6 | self.neighbors = neighbors 7 | 8 | 9 | class Solution: 10 | def cloneGraph(self, node: 'Node') -> 'Node': 11 | if node is None: 12 | return node 13 | 14 | root = node 15 | graph = self.get_graph(node) 16 | 17 | mapping = {} 18 | for node in graph: 19 | mapping[node] = Node(node.val) 20 | 21 | for node in graph: 22 | new_node = mapping[node] 23 | for neighbor in node.neighbors: 24 | new_node.neighbors.append(mapping[neighbor]) 25 | 26 | return mapping[root] 27 | 28 | def get_graph(self, node): 29 | graph = {node} 30 | queue = deque([node]) 31 | 32 | while queue: 33 | curt = queue.popleft() 34 | for neighbor in curt.neighbors: 35 | if neighbor not in graph: 36 | graph.add(neighbor) 37 | queue.append(neighbor) 38 | return graph 39 | -------------------------------------------------------------------------------- /Microsoft/134. Gas Station.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def canCompleteCircuit(self, gas, cost) -> int: 3 | if sum(gas) < sum(cost): 4 | return -1 5 | 6 | start = 0 7 | gas_remain = 0 8 | 9 | for i in range(len(gas)): 10 | gas_remain += gas[i] - cost[i] 11 | if gas_remain < 0: 12 | gas_remain = 0 13 | start = i + 1 14 | 15 | return start 16 | -------------------------------------------------------------------------------- /Microsoft/136. Single Number.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def singleNumber(self, nums) -> int: 3 | result = 0 4 | 5 | for num in nums: 6 | result = result ^ num 7 | 8 | return result 9 | -------------------------------------------------------------------------------- /Microsoft/138. Copy List with Random Pointer - 1.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): 3 | self.val = int(x) 4 | self.next = next 5 | self.random = random 6 | 7 | 8 | class Solution: 9 | def copyRandomList(self, head: 'Node') -> 'Node': 10 | if head is None: 11 | return head 12 | 13 | store = {} 14 | dummy = Node(0) 15 | new_list = dummy 16 | node = head 17 | while node: 18 | new_node = Node(node.val) 19 | new_node.random = node.random 20 | 21 | store[node] = new_node 22 | 23 | new_list.next = new_node 24 | 25 | new_list = new_list.next 26 | node = node.next 27 | 28 | new_list = dummy.next 29 | while new_list: 30 | new_list.random = store[new_list.random] if new_list.random in store else None 31 | new_list = new_list.next 32 | return dummy.next 33 | -------------------------------------------------------------------------------- /Microsoft/138. Copy List with Random Pointer - 2.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): 3 | self.val = int(x) 4 | self.next = next 5 | self.random = random 6 | 7 | 8 | class Solution: 9 | def copyRandomList(self, head: 'Node') -> 'Node': 10 | if head is None: 11 | return head 12 | 13 | dummy = Node(0) 14 | new_list = dummy 15 | node = head 16 | 17 | while node: 18 | new_node = Node(node.val) 19 | new_node.random = node.random 20 | 21 | next = node.next 22 | 23 | node.next = new_node 24 | new_node.next = next 25 | 26 | node = next 27 | 28 | node = head 29 | while node: 30 | new_node = node.next 31 | 32 | if new_node.random: 33 | new_node.random = new_node.random.next 34 | 35 | new_list.next = new_node 36 | 37 | new_list = new_list.next 38 | node = new_node.next 39 | 40 | return dummy.next 41 | -------------------------------------------------------------------------------- /Microsoft/14. Longest Common Prefix.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestCommonPrefix(self, strs) -> str: 3 | if not strs or len(strs) == 0: 4 | return "" 5 | 6 | for j in range(0, len(strs[0])): 7 | for i in range(0, len(strs)): 8 | if j >= len(strs[i]) or strs[i][j] != strs[0][j]: 9 | string = strs[i] 10 | return string[0: j] 11 | 12 | return strs[0] 13 | -------------------------------------------------------------------------------- /Microsoft/140. Word Break II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def wordBreak(self, s: str, wordDict): 3 | return self.dfs(s, wordDict, {}) 4 | 5 | def dfs(self, s, wordDict, memo): 6 | if s in memo: 7 | return memo[s] 8 | 9 | if len(s) == 0: 10 | return [] 11 | 12 | parts = [] 13 | 14 | for i in range(1, len(s)): 15 | prefix = s[:i] 16 | if prefix not in wordDict: 17 | continue 18 | 19 | sub_parts = self.dfs(s[i:], wordDict, memo) 20 | for sub_part in sub_parts: 21 | parts.append(prefix + ' ' + sub_part) 22 | 23 | if s in wordDict: 24 | parts.append(s) 25 | 26 | memo[s] = parts 27 | return parts 28 | -------------------------------------------------------------------------------- /Microsoft/142. Linked List Cycle II.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def detectCycle(self, head: ListNode) -> ListNode: 8 | if head is None or head.next is None: 9 | return None 10 | 11 | slow, fast = head, head 12 | while fast and fast.next: 13 | slow = slow.next 14 | fast = fast.next.next 15 | if fast == slow: 16 | break 17 | 18 | if slow != fast: 19 | return None 20 | 21 | fast = head 22 | while slow != fast: 23 | slow = slow.next 24 | fast = fast.next 25 | return slow 26 | -------------------------------------------------------------------------------- /Microsoft/143. Reorder List.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def reorderList(self, head: ListNode) -> None: 8 | if head is None or head.next is None: 9 | return head 10 | 11 | # 找中点 12 | p_slow = head 13 | p_fast = head 14 | while p_fast.next is not None and p_fast.next.next is not None: 15 | p_slow = p_slow.next 16 | p_fast = p_fast.next.next 17 | 18 | # 初始 19 | p_fast = p_slow.next 20 | p_slow.next = None 21 | p_next = p_fast.next 22 | p_fast.next = None 23 | 24 | # 反序 25 | while p_next is not None: 26 | p_temp = p_next.next 27 | p_next.next = p_fast 28 | 29 | p_fast = p_next 30 | p_next = p_temp 31 | 32 | tail = head 33 | while p_fast is not None: 34 | p_temp = p_fast.next 35 | p_fast.next = tail.next 36 | tail.next = p_fast 37 | 38 | p_fast = p_temp 39 | tail = tail.next.next 40 | 41 | return head -------------------------------------------------------------------------------- /Microsoft/146. LRU Cache.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, key, val, next=None): 3 | self.val = val 4 | self.key = key 5 | self.next = next 6 | 7 | class LRUCache: 8 | 9 | def __init__(self, capacity: int): 10 | self.tail = self.dummy = Node(0, 0) 11 | self.key_to_prev = {} 12 | self.size = 0 13 | self.capacity = capacity 14 | 15 | def get(self, key: int) -> int: 16 | if key not in self.key_to_prev: 17 | return -1 18 | 19 | self.kick(self.key_to_prev[key]) 20 | 21 | return self.key_to_prev[key].next.val 22 | 23 | def put(self, key: int, value: int) -> None: 24 | if key in self.key_to_prev: 25 | self.kick(self.key_to_prev[key]) 26 | self.key_to_prev[key].next.val = value 27 | return 28 | 29 | self.push_back(Node(key, value)) 30 | self.size += 1 31 | 32 | if self.size > self.capacity: 33 | self.pop_front() 34 | 35 | def kick(self, prev): 36 | node = prev.next 37 | next = node.next 38 | 39 | if node == self.tail: 40 | return 41 | 42 | self.key_to_prev[next.key] = prev 43 | prev.next = next 44 | 45 | node.next = None 46 | 47 | self.push_back(node) 48 | 49 | def push_back(self, node): 50 | self.tail.next = node 51 | self.key_to_prev[node.key] = self.tail 52 | self.tail = node 53 | 54 | def pop_front(self): 55 | head = self.dummy.next 56 | next = head.next 57 | 58 | self.dummy.next = next 59 | self.key_to_prev[next.key] = self.dummy 60 | 61 | head.next = None 62 | del self.key_to_prev[head.key] 63 | 64 | self.size -= 1 65 | -------------------------------------------------------------------------------- /Microsoft/15. 3Sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def threeSum(self, nums): 3 | if not nums or len(nums) < 3: 4 | return [] 5 | 6 | nums = sorted(nums) 7 | results = [] 8 | n = len(nums) 9 | 10 | for i in range(n - 2): 11 | if i > 0 and nums[i - 1] == nums[i]: 12 | continue 13 | 14 | self.two_sum(nums, i + 1, n - 1, -nums[i], results) 15 | 16 | return results 17 | 18 | def two_sum(self, nums, left, right, target, results): 19 | while left < right: 20 | curt_sum = nums[left] + nums[right] 21 | if curt_sum < target: 22 | left += 1 23 | elif curt_sum > target: 24 | right -= 1 25 | else: 26 | results.append([-target, nums[left], nums[right]]) 27 | left, right = left + 1, right - 1 28 | 29 | while left < right and nums[left - 1] == nums[left]: 30 | left += 1 31 | while left < right and nums[right] == nums[right + 1]: 32 | right -= 1 33 | -------------------------------------------------------------------------------- /Microsoft/151. Reverse Words in a String.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseWords(self, s: str) -> str: 3 | return ' '.join(s.strip().split()[::-1]) 4 | -------------------------------------------------------------------------------- /Microsoft/152. Maximum Product Subarray.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxProduct(self, nums) -> int: 3 | if not nums: 4 | return 0 5 | 6 | global_max = prev_min = prev_max = nums[0] 7 | for i in range(1, len(nums)): 8 | if nums[i] > 0: 9 | curt_max = max(nums[i], prev_max * nums[i]) 10 | curt_min = min(nums[i], prev_min * nums[i]) 11 | else: 12 | curt_max = max(nums[i], prev_min * nums[i]) 13 | curt_min = min(nums[i], prev_max * nums[i]) 14 | 15 | global_max = max(global_max, curt_max) 16 | prev_max, prev_min = curt_max, curt_min 17 | return global_max 18 | -------------------------------------------------------------------------------- /Microsoft/160. Intersection of Two Linked Lists.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: 8 | l1 = self.get_length(headA) 9 | l2 = self.get_length(headB) 10 | 11 | if l1 > l2: 12 | headA, headB = headB, headA 13 | l1, l2 = l2, l1 14 | 15 | offset = l2 - l1 16 | for _ in range(offset): 17 | headB = headB.next 18 | 19 | while headA != headB: 20 | headA = headA.next 21 | headB = headB.next 22 | 23 | return headA 24 | 25 | def get_length(self, head): 26 | length = 0 27 | while head: 28 | length += 1 29 | head = head.next 30 | return length 31 | -------------------------------------------------------------------------------- /Microsoft/165. Compare Version Numbers.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def compareVersion(self, version1: str, version2: str) -> int: 3 | v_list1, v_list2 = version1.split('.'), version2.split('.') 4 | l1, l2 = len(v_list1), len(v_list2) 5 | 6 | for i in range(max(l1, l2)): 7 | v1 = int(v_list1[i]) if l1 > i else 0 8 | v2 = int(v_list2[i]) if l2 > i else 0 9 | 10 | if v1 > v2: 11 | return 1 12 | elif v1 < v2: 13 | return -1 14 | return 0 15 | -------------------------------------------------------------------------------- /Microsoft/168. Excel Sheet Column Title.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def convertToTitle(self, n: int) -> str: 3 | result = '' 4 | 5 | while n > 0: 6 | n -= 1 7 | result = chr(n % 26 + ord('A')) + result 8 | n = n // 26 9 | 10 | return result 11 | -------------------------------------------------------------------------------- /Microsoft/173. Binary Search Tree Iterator.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class BSTIterator: 9 | 10 | def __init__(self, root: TreeNode): 11 | self.stack = [] 12 | while root: 13 | self.stack.append(root) 14 | root = root.left 15 | 16 | 17 | def next(self) -> int: 18 | node = self.stack[-1] 19 | if node.right: 20 | n = node.right 21 | while n: 22 | self.stack.append(n) 23 | n = n.left 24 | else: 25 | n = self.stack.pop() 26 | while self.stack and self.stack[-1].right == n: 27 | n = self.stack.pop() 28 | 29 | return node.val 30 | 31 | 32 | 33 | def hasNext(self) -> bool: 34 | return len(self.stack) > 0 35 | 36 | 37 | 38 | # Your BSTIterator object will be instantiated and called as such: 39 | # obj = BSTIterator(root) 40 | # param_1 = obj.next() 41 | # param_2 = obj.hasNext() 42 | -------------------------------------------------------------------------------- /Microsoft/179. Largest Number.py: -------------------------------------------------------------------------------- 1 | from functools import cmp_to_key 2 | class Solution: 3 | def largestNumber(self, nums) -> str: 4 | nums = sorted(nums, key=cmp_to_key(lambda x, y: 1 if str(x) + str(y) < str(y) + str(x) else -1)) 5 | if nums[0] == 0: 6 | return '0' 7 | 8 | return ''.join([str(x) for x in nums]) 9 | -------------------------------------------------------------------------------- /Microsoft/186. Reverse Words in a String II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseWords(self, s) -> None: 3 | self.reverse(s, 0, len(s) - 1) 4 | 5 | self.reverse_each_word(s) 6 | 7 | def reverse(self, s, left, right): 8 | while left < right: 9 | s[left], s[right] = s[right], s[left] 10 | left += 1 11 | right -= 1 12 | 13 | def reverse_each_word(self, s): 14 | n = len(s) 15 | 16 | start = end = 0 17 | while start < n: 18 | while end < n and s[end] != ' ': 19 | end += 1 20 | 21 | self.reverse(s, start, end - 1) 22 | 23 | start = end + 1 24 | end += 1 25 | -------------------------------------------------------------------------------- /Microsoft/19. Remove Nth Node From End of List.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: 8 | if head is None or head.next is None: 9 | return None 10 | 11 | dummy = ListNode(0) 12 | dummy.next = head 13 | 14 | slow, fast = dummy, dummy 15 | for _ in range(n): 16 | fast = fast.next 17 | 18 | while fast.next: 19 | slow = slow.next 20 | fast = fast.next 21 | 22 | self.remove_node(slow) 23 | 24 | return dummy.next 25 | 26 | def remove_node(self, prev): 27 | node, next = prev.next, prev.next.next 28 | 29 | prev.next = next 30 | node.next = None 31 | -------------------------------------------------------------------------------- /Microsoft/2. Add Two Numbers.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: 8 | head = ListNode(0) 9 | node = head 10 | carry = 0 11 | 12 | while True: 13 | if l1: 14 | carry += l1.val 15 | l1 = l1.next 16 | if l2: 17 | carry += l2.val 18 | l2 = l2.next 19 | 20 | node.val = carry % 10 21 | carry = carry // 10 22 | 23 | if l1 or l2 or carry != 0: 24 | node.next = ListNode(0) 25 | node = node.next 26 | else: 27 | break 28 | return head 29 | -------------------------------------------------------------------------------- /Microsoft/200. Number of Islands.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.dx = [0, 1, 0, -1] 4 | self.dy = [1, 0, -1, 0] 5 | 6 | def numIslands(self, grid) -> int: 7 | if not grid or not grid[0]: 8 | return 0 9 | 10 | rows, cols = len(grid), len(grid[0]) 11 | islands = 0 12 | for i in range(rows): 13 | for j in range(cols): 14 | if grid[i][j] == '1': 15 | self.dfs(grid, i, j, rows, cols) 16 | islands += 1 17 | return islands 18 | 19 | def dfs(self, grid, x, y, rows, cols): 20 | if not (0 <= x < rows and 0 <= y < cols) or grid[x][y] == '0': 21 | return 22 | 23 | grid[x][y] = '0' 24 | 25 | for delta in range(4): 26 | next_x, next_y = x + self.dx[delta], y + self.dy[delta] 27 | self.dfs(grid, next_x, next_y, rows, cols) 28 | -------------------------------------------------------------------------------- /Microsoft/206. Reverse Linked List.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def reverseList(self, head: ListNode) -> ListNode: 8 | prev, node = None, head 9 | 10 | while node: 11 | next = node.next 12 | 13 | node.next = prev 14 | 15 | prev = node 16 | node = next 17 | 18 | return prev 19 | -------------------------------------------------------------------------------- /Microsoft/207. Course Schedule.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def canFinish(self, numCourses: int, prerequisites) -> bool: 5 | indegrees = {node: 0 for node in range(numCourses)} 6 | graph = {node: [] for node in range(numCourses)} 7 | 8 | for child, parent in prerequisites: 9 | graph[parent].append(child) 10 | indegrees[child] += 1 11 | 12 | queue = deque([node for node in indegrees if indegrees[node] == 0]) 13 | visited = set(queue) 14 | while queue: 15 | node = queue.popleft() 16 | 17 | for child in graph[node]: 18 | if child not in visited: 19 | indegrees[child] -= 1 20 | if indegrees[child] == 0: 21 | queue.append(child) 22 | visited.add(child) 23 | 24 | return len(visited) == numCourses 25 | -------------------------------------------------------------------------------- /Microsoft/21. Merge Two Sorted Lists.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: 8 | dummy = ListNode(0) 9 | curt = dummy 10 | 11 | while l1 or l2: 12 | if not l2 or (l1 and l1.val < l2.val): 13 | curt.next = l1 14 | l1 = l1.next 15 | else: 16 | curt.next = l2 17 | l2 = l2.next 18 | curt = curt.next 19 | 20 | return dummy.next 21 | -------------------------------------------------------------------------------- /Microsoft/210. Course Schedule II.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def findOrder(self, numCourses: int, prerequisites): 5 | graph = {node: [] for node in range(numCourses)} 6 | indegrees = {node: 0 for node in range(numCourses)} 7 | 8 | for child, parent in prerequisites: 9 | graph[parent].append(child) 10 | indegrees[child] += 1 11 | 12 | queue = deque([node for node in graph if indegrees[node] == 0]) 13 | order = [] 14 | while queue: 15 | node = queue.popleft() 16 | order.append(node) 17 | 18 | for child in graph[node]: 19 | indegrees[child] -= 1 20 | if indegrees[child] == 0: 21 | queue.append(child) 22 | 23 | if len(order) == numCourses: 24 | return list(order) 25 | else: 26 | return [] 27 | -------------------------------------------------------------------------------- /Microsoft/212. Word Search II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.directions = [(0, -1), (0, 1), (-1, 0), (1, 0)] 4 | 5 | def findWords(self, board, words): 6 | if not board or not board[0]: 7 | return [] 8 | 9 | word_set, prefix_set = set(words), set() 10 | for word in words: 11 | for i in range(len(word)): 12 | prefix_set.add(word[:i + 1]) 13 | 14 | result = set() 15 | for i in range(len(board)): 16 | for j in range(len(board[0])): 17 | first = board[i][j] 18 | self.search(board, i, j, board[i][j], word_set, prefix_set, {(i, j)}, result) 19 | 20 | return list(result) 21 | 22 | def search(self, board, x, y, word, word_set, prefix_set, visited, result): 23 | if word not in prefix_set: 24 | return 25 | 26 | if word in word_set: 27 | result.add(word) 28 | 29 | for delta_x, delta_y in self.directions: 30 | next_x, next_y = x + delta_x, y + delta_y 31 | 32 | if not self.inside(board, next_x, next_y): 33 | continue 34 | if (next_x, next_y) in visited: 35 | continue 36 | 37 | visited.add((next_x, next_y)) 38 | self.search(board, next_x, next_y, word + board[next_x][next_y], word_set, prefix_set, visited, result) 39 | visited.remove((next_x, next_y)) 40 | 41 | def inside(self, board, x, y): 42 | return 0 <= x < len(board) and 0 <= y < len(board[0]) 43 | -------------------------------------------------------------------------------- /Microsoft/22. Generate Parentheses.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def generateParenthesis(self, n: int): 3 | results = [] 4 | 5 | self.dfs(n, n, '', results) 6 | 7 | return results 8 | 9 | def dfs(self, left, right, curt, results): 10 | if right < left: 11 | return 12 | 13 | if left == 0 and right == 0: 14 | results.append(curt) 15 | 16 | if left > 0: 17 | self.dfs(left - 1, right, curt + '(', results) 18 | 19 | if right > 0: 20 | self.dfs(left, right - 1, curt + ')', results) 21 | -------------------------------------------------------------------------------- /Microsoft/225. Implement Stack using Queues.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class MyStack: 4 | 5 | def __init__(self): 6 | self.main = deque([]) 7 | self.support = deque([]) 8 | 9 | def push(self, x: int) -> None: 10 | self.main.append(x) 11 | 12 | def pop(self) -> int: 13 | while len(self.main) > 1: 14 | self.support.append(self.main.popleft()) 15 | 16 | result = self.main.pop() 17 | 18 | self.support, self.main = self.main, self.support 19 | 20 | return result 21 | 22 | def top(self) -> int: 23 | while len(self.main) > 1: 24 | self.support.append(self.main.popleft()) 25 | 26 | result = self.main.pop() 27 | 28 | self.support.append(result) 29 | self.support, self.main = self.main, self.support 30 | 31 | return result 32 | 33 | def empty(self) -> bool: 34 | return len(self.main) == 0 35 | -------------------------------------------------------------------------------- /Microsoft/23. Merge k Sorted Lists.py: -------------------------------------------------------------------------------- 1 | from heapq import heappop 2 | from heapq import heappush 3 | 4 | class ListNode: 5 | def __init__(self, x): 6 | self.val = x 7 | self.next = None 8 | 9 | ListNode.__lt__ = lambda x, y: x.val < y.val 10 | 11 | class Solution: 12 | def mergeKLists(self, lists) -> ListNode: 13 | if not lists: 14 | return None 15 | 16 | heap = [] 17 | 18 | for head in lists: 19 | if head: 20 | heappush(heap, head) 21 | 22 | dummy = ListNode(0) 23 | node = dummy 24 | while heap: 25 | curt = heappop(heap) 26 | 27 | node.next = curt 28 | 29 | if curt.next: 30 | heappush(heap, curt.next) 31 | 32 | node = node.next 33 | 34 | return dummy.next 35 | -------------------------------------------------------------------------------- /Microsoft/232. Implement Queue using Stacks.py: -------------------------------------------------------------------------------- 1 | class MyQueue: 2 | 3 | def __init__(self): 4 | self.forward = [] 5 | self.backward = [] 6 | 7 | def push(self, x: int) -> None: 8 | self.forward.append(x) 9 | 10 | def pop(self) -> int: 11 | result = -1 12 | if self.forward: 13 | self.switch(self.forward, self.backward) 14 | result = self.backward.pop() 15 | self.switch(self.backward, self.forward) 16 | return result 17 | 18 | def peek(self) -> int: 19 | if self.forward: 20 | return self.forward[0] 21 | else: 22 | return -1 23 | 24 | def empty(self) -> bool: 25 | return len(self.forward) == 0 26 | 27 | def switch(self, stack1, stack2): 28 | while stack1: 29 | stack2.append(stack1.pop()) 30 | -------------------------------------------------------------------------------- /Microsoft/235. Lowest Common Ancestor of a Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': 9 | if root is None: 10 | return root 11 | 12 | if p.val > root.val and q.val > root.val: 13 | return self.lowestCommonAncestor(root.right, p, q) 14 | elif p.val < root.val and q.val < root.val: 15 | return self.lowestCommonAncestor(root.left, p, q) 16 | else: 17 | return root 18 | -------------------------------------------------------------------------------- /Microsoft/236. Lowest Common Ancestor of a Binary Tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': 9 | if root is None: 10 | return None 11 | 12 | if root == p or root == q: 13 | return root 14 | 15 | left = self.lowestCommonAncestor(root.left, p, q) 16 | right = self.lowestCommonAncestor(root.right, p, q) 17 | 18 | if left and right: 19 | return root 20 | 21 | if left: 22 | return left 23 | 24 | if right: 25 | return right 26 | 27 | return None 28 | -------------------------------------------------------------------------------- /Microsoft/24. Swap Nodes in Pairs.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | """ 8 | @param head: a ListNode 9 | @return: a ListNode 10 | """ 11 | 12 | def swapPairs(self, head): 13 | if head is None: 14 | return 15 | 16 | dummy = ListNode(0) 17 | dummy.next = head 18 | prev = dummy 19 | first = head 20 | 21 | while first is not None and first.next is not None: 22 | second = first.next 23 | 24 | temp = second.next 25 | 26 | prev.next = second 27 | second.next = first 28 | first.next = temp 29 | 30 | prev = first 31 | first = temp 32 | 33 | return dummy.next -------------------------------------------------------------------------------- /Microsoft/240. Search a 2D Matrix II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def searchMatrix(self, matrix, target): 3 | """ 4 | :type matrix: List[List[int]] 5 | :type target: int 6 | :rtype: bool 7 | """ 8 | if not matrix: 9 | return False 10 | rows, cols = len(matrix), len(matrix[0]) 11 | 12 | x, y = rows - 1, 0 13 | 14 | while x >= 0 and y < cols: 15 | if matrix[x][y] < target: 16 | y += 1 17 | elif matrix[x][y] > target: 18 | x -= 1 19 | else: 20 | return True 21 | 22 | return False -------------------------------------------------------------------------------- /Microsoft/242. Valid Anagram.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isAnagram(self, s: str, t: str) -> bool: 3 | set_s, set_t = [0] * 256, [0] * 256 4 | for i in range(len(s)): 5 | set_s[ord(s[i])] += 1 6 | for i in range(len(t)): 7 | set_t[ord(t[i])] += 1 8 | for i in range(256): 9 | if set_s[i] != set_t[i]: 10 | return False 11 | return True 12 | -------------------------------------------------------------------------------- /Microsoft/243. Shortest Word Distance.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def shortestDistance(self, words: List[str], word1: str, word2: str) -> int: 3 | size = len(words) 4 | index1, index2 = size, size 5 | 6 | result = size 7 | 8 | for i in range(len(words)): 9 | if words[i] == word1: 10 | index1 = i 11 | result = min(result, abs(index1 - index2)) 12 | elif words[i] == word2: 13 | index2 = i 14 | result = min(result, abs(index1 - index2)) 15 | return result 16 | 17 | -------------------------------------------------------------------------------- /Microsoft/25. Reverse Nodes in k-Group.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def reverseKGroup(self, head: ListNode, k: int) -> ListNode: 8 | if head is None: 9 | return head 10 | 11 | dummy = ListNode(0) 12 | dummy.next = head 13 | prev = dummy 14 | 15 | while prev: 16 | prev = self.reverse_next_k(prev, k) 17 | 18 | return dummy.next 19 | 20 | def reverse_next_k(self, prev, k): 21 | n1 = prev.next 22 | nk = self.find_kth(prev, k) 23 | if nk is None: 24 | return None 25 | 26 | nk_next = nk.next 27 | nk.next = None 28 | 29 | nk = self.reverse_list(n1) 30 | 31 | prev.next = nk 32 | n1.next = nk_next 33 | 34 | return n1 35 | 36 | def find_kth(self, prev, k): 37 | for _ in range(k): 38 | if prev is None: 39 | return None 40 | prev = prev.next 41 | return prev 42 | 43 | def reverse_list(self, head): 44 | prev, curt = None, head 45 | while curt: 46 | next = curt.next 47 | 48 | curt.next = prev 49 | 50 | prev = curt 51 | curt = next 52 | return prev 53 | -------------------------------------------------------------------------------- /Microsoft/253. Meeting Rooms II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minMeetingRooms(self, intervals) -> int: 3 | if not intervals: 4 | return 0 5 | 6 | points = [] 7 | for interval in intervals: 8 | points.append((interval[0], 1)) 9 | points.append((interval[1], -1)) 10 | 11 | meeting, rooms = 0, 0 12 | for _, delta in sorted(points): 13 | meeting += delta 14 | rooms = max(rooms, meeting) 15 | 16 | return rooms 17 | -------------------------------------------------------------------------------- /Microsoft/269. Alien Dictionary.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | from heapq import heapify 3 | from heapq import heappop 4 | from heapq import heappush 5 | 6 | 7 | class Solution: 8 | """ 9 | @param words: a list of words 10 | @return: a string which is correct order 11 | """ 12 | 13 | def alienOrder(self, words): 14 | indegrees = {} 15 | graph = {} 16 | 17 | # 初始化 18 | for word in words: 19 | for char in word: 20 | graph[char] = [] 21 | indegrees[char] = 0 22 | 23 | # 构图 24 | for i in range(1, len(words)): 25 | for j in range(min(len(words[i - 1]), len(words[i]))): 26 | if words[i - 1][j] == words[i][j]: 27 | continue 28 | graph[words[i - 1][j]].append(words[i][j]) 29 | indegrees[words[i][j]] += 1 30 | break 31 | 32 | # 初始化 queue 33 | queue = [char for char in graph if indegrees[char] == 0] 34 | heapify(queue) 35 | 36 | order = [] 37 | 38 | while queue: 39 | for _ in range(len(queue)): 40 | curt = heappop(queue) 41 | order.append(curt) 42 | 43 | for next_char in graph[curt]: 44 | indegrees[next_char] -= 1 45 | if indegrees[next_char] == 0: 46 | heappush(queue, next_char) 47 | 48 | if len(order) != len(graph): 49 | return '' 50 | 51 | return ''.join(order) -------------------------------------------------------------------------------- /Microsoft/273. Integer to English Words.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.lessThan20 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", 4 | "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"] 5 | self.tens = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"] 6 | self.thousands = ["", "Thousand", "Million", "Billion"] 7 | 8 | def numberToWords(self, num: int) -> str: 9 | if num == 0: 10 | return 'Zero' 11 | 12 | word = '' 13 | for i in range(len(self.thousands)): 14 | if num % 1000 != 0: 15 | word = self.get_small(num % 1000) + self.thousands[i] + ' ' + word 16 | num = num // 1000 17 | return word.strip() 18 | 19 | def get_small(self, num): 20 | if num == 0: 21 | return '' 22 | elif num < 20: 23 | return self.lessThan20[num] + ' ' 24 | elif num < 100: 25 | return self.tens[num // 10] + ' ' + self.get_small(num % 10) 26 | else: 27 | return self.lessThan20[num // 100] + ' Hundred ' + self.get_small(num % 100) 28 | -------------------------------------------------------------------------------- /Microsoft/277. Find the Celebrity.py: -------------------------------------------------------------------------------- 1 | # The knows API is already defined for you. 2 | # return a bool, whether a knows b 3 | # def knows(a: int, b: int) -> bool: 4 | 5 | def knows(a, b): 6 | return True 7 | 8 | class Solution: 9 | def findCelebrity(self, n: int) -> int: 10 | celebrity = 0 11 | 12 | for i in range(1, n): 13 | if knows(celebrity, i): 14 | celebrity = i 15 | 16 | for i in range(n): 17 | if i != celebrity and knows(celebrity, i): 18 | return -1 19 | if i != celebrity and not knows(i, celebrity): 20 | return -1 21 | 22 | return celebrity 23 | -------------------------------------------------------------------------------- /Microsoft/28. Implement strStr().py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def strStr(self, source: str, target: str) -> int: 3 | if source is None or target is None: 4 | return -1 5 | 6 | len_s = len(source) 7 | len_t = len(target) 8 | 9 | for i in range(len_s - len_t + 1): 10 | j = 0 11 | while j < len_t: 12 | if source[i + j] != target[j]: 13 | break 14 | j += 1 15 | if j == len_t: 16 | return i 17 | return -1 18 | -------------------------------------------------------------------------------- /Microsoft/285. Inorder Successor in BST.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution: 9 | def inorderSuccessor(self, root: 'TreeNode', p: 'TreeNode') -> 'TreeNode': 10 | if root is None: 11 | return None 12 | 13 | if p.val >= root.val: 14 | return self.inorderSuccessor(root.right, p) 15 | 16 | left = self.inorderSuccessor(root.left, p) 17 | 18 | return left or root 19 | -------------------------------------------------------------------------------- /Microsoft/287. Find the Duplicate Number.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findDuplicate(self, nums) -> int: 3 | if len(nums) <= 1: 4 | return -1 5 | 6 | slow = nums[0] 7 | fast = nums[slow] 8 | while slow != fast: 9 | slow = nums[slow] 10 | fast = nums[nums[fast]] 11 | 12 | fast = 0 13 | while slow != fast: 14 | fast = nums[fast] 15 | slow = nums[slow] 16 | 17 | return slow 18 | -------------------------------------------------------------------------------- /Microsoft/297. Serialize and Deserialize Binary Tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode(object): 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Codec: 8 | def serialize(self, root): 9 | if root is None: 10 | return ['#'] 11 | order = [str(root.val)] 12 | left = self.serialize(root.left) 13 | right = self.serialize(root.right) 14 | return order + left + right 15 | 16 | def deserialize(self, data): 17 | char = data.pop(0) 18 | if char == '#': 19 | return None 20 | else: 21 | root = TreeNode(int(char)) 22 | 23 | root.left = self.deserialize(data) 24 | root.right = self.deserialize(data) 25 | return root 26 | -------------------------------------------------------------------------------- /Microsoft/328. Odd Even Linked List.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def oddEvenList(self, head: ListNode) -> ListNode: 8 | if head is None: 9 | return head 10 | odd = head 11 | evenHead = head.next 12 | even = evenHead 13 | while even and even.next: 14 | odd.next = even.next 15 | odd = odd.next 16 | even.next = odd.next 17 | even = even.next 18 | odd.next = evenHead 19 | return head 20 | -------------------------------------------------------------------------------- /Microsoft/33. Search in Rotated Sorted Array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def search(self, nums, target) -> int: 3 | if not nums: 4 | return -1 5 | 6 | left, right = 0, len(nums) - 1 7 | while left + 1 < right: 8 | mid = (left + right) // 2 9 | 10 | if nums[mid] == target: 11 | return mid 12 | 13 | if nums[left] < nums[mid]: 14 | if nums[left] <= target <= nums[mid]: 15 | right = mid 16 | else: 17 | left = mid 18 | else: 19 | if nums[mid] <= target <= nums[right]: 20 | left = mid 21 | else: 22 | right = mid 23 | 24 | if nums[left] == target: 25 | return left 26 | if nums[right] == target: 27 | return right 28 | return -1 29 | -------------------------------------------------------------------------------- /Microsoft/340. Longest Substring with At Most K Distinct Characters.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int: 3 | most_right = {} 4 | l, r = 0, 0 5 | longest = 0 6 | 7 | while r < len(s): 8 | if len(most_right) <= k: 9 | most_right[s[r]] = r 10 | r += 1 11 | if len(most_right) > k: 12 | left = len(s) 13 | # Find most left 14 | for value in most_right.values(): 15 | left = min(left, value) 16 | most_right.pop(s[left]) 17 | l = left + 1 18 | longest = max(longest, r - l) 19 | 20 | return longest -------------------------------------------------------------------------------- /Microsoft/346. Moving Average from Data Stream.py: -------------------------------------------------------------------------------- 1 | class MovingAverage: 2 | 3 | def __init__(self, size: int): 4 | self.window = [] 5 | self.total = 0 6 | self.num = 0 7 | self.size = size 8 | 9 | def next(self, val: int) -> float: 10 | self.window.append(val) 11 | self.total += val 12 | self.num += 1 13 | 14 | if self.num <= self.size: 15 | return self.total / self.num 16 | else: 17 | first = self.window.pop(0) 18 | self.total -= first 19 | return self.total / self.size 20 | -------------------------------------------------------------------------------- /Microsoft/347. Top K Frequent Elements.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def topKFrequent(self, nums, k): 3 | store = {} 4 | 5 | for num in nums: 6 | store[num] = store.get(num, 0) + 1 7 | 8 | sorted_store = sorted(store.items(), key=lambda x: x[1], reverse=True) 9 | 10 | result = [] 11 | for i in range(k): 12 | result.append(sorted_store[i][0]) 13 | 14 | return result 15 | -------------------------------------------------------------------------------- /Microsoft/348. Design Tic-Tac-Toe.py: -------------------------------------------------------------------------------- 1 | class TicTacToe: 2 | 3 | def __init__(self, n: int): 4 | self.board = [[0 for _ in range(n)] for _ in range(n)] 5 | self.size = n 6 | 7 | def move(self, row: int, col: int, player: int): 8 | if self.board[row][col] == 0: 9 | self.board[row][col] = player 10 | 11 | # left -> right 12 | for i in range(self.size): 13 | if self.board[row][i] != player: 14 | break 15 | if i == self.size - 1: 16 | return player 17 | 18 | # top -> bottom 19 | for i in range(self.size): 20 | if self.board[i][col] != player: 21 | break 22 | if i == self.size - 1: 23 | return player 24 | 25 | # top left -> bottom right 26 | for i in range(self.size): 27 | if self.board[i][i] != player: 28 | break 29 | if i == self.size - 1: 30 | return player 31 | 32 | # top right -> bottom left 33 | for i in range(self.size): 34 | if self.board[i][self.size - i - 1] != player: 35 | break 36 | if i == self.size - 1: 37 | return player 38 | 39 | return 0 40 | -------------------------------------------------------------------------------- /Microsoft/415. Add Strings.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addStrings(self, num1, num2): 3 | carrier = 0 4 | digits = "" 5 | i = 0 6 | num1Len = len(num1) 7 | num2Len = len(num2) 8 | maxLen = max(num1Len, num2Len) 9 | while i < maxLen: 10 | theSum = carrier 11 | if i < num1Len: 12 | theSum += int(num1[num1Len - 1 - i]) 13 | if i < num2Len: 14 | theSum += int(num2[num2Len - 1 - i]) 15 | carrier = theSum // 10 16 | theSum = theSum % 10 17 | digits = str(theSum) + digits 18 | 19 | i += 1 20 | if carrier == 1: 21 | return "1" + digits 22 | 23 | return digits 24 | -------------------------------------------------------------------------------- /Microsoft/42. Trapping Rain Water - 1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def trap(self, heights) -> int: 3 | if not heights: 4 | return 0 5 | 6 | left, right = 0, len(heights) - 1 7 | left_max, right_max = heights[left], heights[right] 8 | water = 0 9 | 10 | while left < right: 11 | if heights[left] < heights[right]: 12 | left_max = max(left_max, heights[left]) 13 | water += left_max - heights[left] 14 | left += 1 15 | else: 16 | right_max = max(right_max, heights[right]) 17 | water += right_max - heights[right] 18 | right -= 1 19 | 20 | return water 21 | -------------------------------------------------------------------------------- /Microsoft/42. Trapping Rain Water - 2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def trap(self, heights) -> int: 3 | if not heights: 4 | return 0 5 | 6 | stack = [] 7 | water = 0 8 | for right, height in enumerate(heights): 9 | while stack and heights[stack[-1]] <= height: 10 | ground = heights[stack.pop()] 11 | 12 | if not stack: 13 | continue 14 | 15 | left = stack[-1] 16 | water_line = min(heights[left], height) 17 | water += (water_line - ground) * (right - left - 1) 18 | stack.append(right) 19 | 20 | return water 21 | -------------------------------------------------------------------------------- /Microsoft/431. Encode N-ary Tree to Binary Tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, val=None, children=None): 3 | self.val = val 4 | self.children = children 5 | class TreeNode: 6 | def __init__(self, x): 7 | self.val = x 8 | self.left = None 9 | self.right = None 10 | 11 | 12 | class Codec: 13 | 14 | # Encodes an n-ary tree to a binary tree. 15 | def encode(self, root: 'Node') -> TreeNode: 16 | if root is None: 17 | return None 18 | 19 | result = TreeNode(root.val) 20 | if root.children: 21 | result.left = self.encode(root.children[0]) 22 | 23 | curt = result.left 24 | 25 | for i in range(1, len(root.children)): 26 | curt.right = self.encode(root.children[i]) 27 | curt = curt.right 28 | 29 | return result 30 | 31 | # Decodes your binary tree to an n-ary tree. 32 | def decode(self, root: TreeNode) -> 'Node': 33 | if root is None: 34 | return None 35 | 36 | result = Node(root.val, []) 37 | curt = root.left 38 | 39 | while curt: 40 | result.children.append(self.decode(curt)) 41 | curt = curt.right 42 | return result 43 | 44 | # Your Codec object will be instantiated and called as such: 45 | # codec = Codec() 46 | # codec.decode(codec.encode(root)) -------------------------------------------------------------------------------- /Microsoft/44. Wildcard Matching - 1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isMatch(self, s: str, p: str) -> bool: 3 | return self.dfs(s, 0, p, 0, {}) 4 | 5 | def dfs(self, source, i, pattern, j, memo): 6 | if (i, j) in memo: 7 | return memo[(i, j)] 8 | 9 | # Source 到头了,pattern 后面一定要是 * 10 | if i == len(source): 11 | for index in range(j, len(pattern)): 12 | if pattern[index] != '*': 13 | return False 14 | return True 15 | 16 | # Pattern 到头了,此时 source 还没到头,返回 False 17 | if j == len(pattern): 18 | return False 19 | 20 | if pattern[j] != '*': 21 | matched = self.match_char(source[i], pattern[j]) and self.dfs(source, i + 1, pattern, j + 1, memo) 22 | else: 23 | matched = self.dfs(source, i + 1, pattern, j, memo) or self.dfs(source, i, pattern, j + 1, memo) 24 | 25 | memo[(i, j)] = matched 26 | return matched 27 | 28 | def match_char(self, s, p): 29 | return s == p or p == '?' 30 | -------------------------------------------------------------------------------- /Microsoft/44. Wildcard Matching - 2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isMatch(self, s: str, p: str) -> bool: 3 | n, m = len(s), len(p) 4 | 5 | f = [[False for _ in range(m + 1)] for _ in range(n + 1)] 6 | f[0][0] = True 7 | 8 | if n == 0 and p.count('*') == m: 9 | return True 10 | 11 | for i in range(0, n + 1): 12 | for j in range(0, m + 1): 13 | if i > 0 and j > 0: 14 | f[i][j] |= f[i - 1][j - 1] and (s[i - 1] == p[j - 1] or p[j - 1] in ['*', '?']) 15 | 16 | if i > 0 and j > 0: 17 | f[i][j] |= f[i - 1][j] and p[j - 1] == '*' 18 | 19 | if j > 0: 20 | f[i][j] |= f[i][j - 1] and p[j - 1] == '*' 21 | 22 | return f[-1][-1] 23 | -------------------------------------------------------------------------------- /Microsoft/443. String Compression.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def compress(self, chars) -> int: 3 | left, i = 0, 0 4 | 5 | while i < len(chars): 6 | char, length = chars[i], 1 7 | 8 | while i + 1 < len(chars) and char == chars[i + 1]: 9 | length, i = length + 1, i + 1 10 | 11 | chars[left] = char 12 | 13 | if length > 1: 14 | len_str = str(length) 15 | chars[left + 1: left + 1 + len(len_str)] = len_str 16 | left += len(len_str) 17 | left, i = left + 1, i + 1 18 | 19 | return left 20 | -------------------------------------------------------------------------------- /Microsoft/445. Add Two Numbers II.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.next = None 5 | 6 | class Solution: 7 | def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: 8 | num1, num2 = 0, 0 9 | while l1: 10 | num1 = 10 * num1 + l1.val 11 | l1 = l1.next 12 | while l2: 13 | num2 = 10 * num2 + l2.val 14 | l2 = l2.next 15 | 16 | target = num1 + num2 17 | dummy = ListNode(0) 18 | curt = dummy 19 | 20 | for num in str(target): 21 | curt.next = ListNode(int(num)) 22 | curt = curt.next 23 | 24 | return dummy.next 25 | -------------------------------------------------------------------------------- /Microsoft/450. Delete Node in a BST.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def deleteNode(self, root: TreeNode, key: int) -> TreeNode: 9 | if root is None: 10 | return root 11 | 12 | if key < root.val: 13 | root.left = self.deleteNode(root.left, key) 14 | elif key > root.val: 15 | root.right = self.deleteNode(root.right, key) 16 | else: 17 | # 只有一个 child 的情况 18 | if not root.left: 19 | return root.right 20 | if not root.right: 21 | return root.left 22 | 23 | # 有两个 children 的情况,找到右节点的最左节点 24 | prev, next = root, root.right 25 | while next.left: 26 | prev = next 27 | next = next.left 28 | 29 | root.val = next.val 30 | # 如果有右节点的左节点 31 | if prev != root: 32 | prev.left = next.right 33 | else: 34 | prev.right = next.right 35 | return root 36 | -------------------------------------------------------------------------------- /Microsoft/470. Implement Rand10() Using Rand7().py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rand10(self): 3 | while True: 4 | rand49 = (self.rand7() - 1) * 7 + self.rand7() - 1 5 | if rand49 <= 39: 6 | return rand49 // 4 + 1 7 | 8 | def rand7(self): 9 | return 0 10 | -------------------------------------------------------------------------------- /Microsoft/48. Rotate Image.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rotate(self, matrix) -> None: 3 | n = len(matrix) 4 | for i in range(n): 5 | for j in range(i + 1, n): 6 | matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] 7 | for i in range(n): 8 | matrix[i].reverse() 9 | -------------------------------------------------------------------------------- /Microsoft/5. Longest Palindromic Substring.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestPalindrome(self, s: str) -> str: 3 | longest = 0 4 | start, end = 0, 0 5 | n = len(s) 6 | 7 | for i in range(n): 8 | left, right = i, i 9 | while 0 <= left and right < n: 10 | if s[left] != s[right]: 11 | break 12 | if right - left + 1 > longest: 13 | start, end = left, right 14 | longest = right - left + 1 15 | left, right = left - 1, right + 1 16 | 17 | left, right = i - 1, i 18 | while 0 <= left and right < n: 19 | if s[left] != s[right]: 20 | break 21 | if right - left + 1 > longest: 22 | start, end = left, right 23 | longest = right - left + 1 24 | left, right = left - 1, right + 1 25 | 26 | return s[start: end + 1] 27 | -------------------------------------------------------------------------------- /Microsoft/50. Pow(x, n).py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def myPow(self, x: float, n: int) -> float: 3 | # write your code here 4 | if n == 0: 5 | return 1 6 | if n == 1: 7 | return x 8 | if n == -1: 9 | return 1 / x 10 | 11 | temp = self.myPow(x, n // 2) 12 | 13 | result = temp * temp 14 | 15 | if n % 2 == 1: 16 | result = result * x 17 | 18 | return result 19 | -------------------------------------------------------------------------------- /Microsoft/510. Inorder Successor in BST II.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, val): 3 | self.val = val 4 | self.left = None 5 | self.right = None 6 | self.parent = None 7 | 8 | 9 | class Solution: 10 | def inorderSuccessor(self, node: 'Node') -> 'Node': 11 | if node.right: 12 | node = node.right 13 | while node.left: 14 | node = node.left 15 | return node 16 | else: 17 | val = node.val 18 | node = node.parent 19 | while node and node.val < val: 20 | node = node.parent 21 | return node 22 | -------------------------------------------------------------------------------- /Microsoft/53. Maximum Subarray.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums) -> int: 3 | if not nums: 4 | return 0 5 | 6 | prefix_sum = 0 7 | min_sum, max_sum = float('inf'), float('-inf') 8 | 9 | for num in nums: 10 | prefix_sum += num 11 | max_sum = max(max_sum, prefix_sum - min_sum) 12 | min_sum = min(min_sum, prefix_sum) 13 | 14 | return max_sum 15 | -------------------------------------------------------------------------------- /Microsoft/535. Encode and Decode TinyURL.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | class Codec: 4 | def __init__(self): 5 | self.store = {} 6 | self.store2 = {} 7 | 8 | def encode(self, longUrl: str) -> str: 9 | self.store[longUrl] = str(randint(1, 100)) 10 | self.store2['https://tinyurl.com/' + self.store[longUrl]] = longUrl 11 | return 'https://tinyurl.com/' + self.store[longUrl] 12 | 13 | def decode(self, shortUrl: str) -> str: 14 | return self.store2[shortUrl] 15 | 16 | # Your Codec object will be instantiated and called as such: 17 | # codec = Codec() 18 | # codec.decode(codec.encode(url)) -------------------------------------------------------------------------------- /Microsoft/54. Spiral Matrix.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def spiralOrder(self, matrix): 3 | if not matrix or not matrix[0]: 4 | return [] 5 | 6 | rows, cols = len(matrix), len(matrix[0]) 7 | up, down = 0, rows - 1 8 | left, right = 0, cols - 1 9 | order = [] 10 | 11 | direction = 0 12 | 13 | while True: 14 | if direction == 0: 15 | for i in range(left, right + 1): 16 | order.append(matrix[up][i]) 17 | up += 1 18 | if direction == 1: 19 | for i in range(up, down + 1): 20 | order.append(matrix[i][right]) 21 | right -= 1 22 | if direction == 2: 23 | for i in range(right, left - 1, -1): 24 | order.append(matrix[down][i]) 25 | down -= 1 26 | if direction == 3: 27 | for i in range(down, up - 1, -1): 28 | order.append(matrix[i][left]) 29 | left += 1 30 | 31 | if left > right or up > down: 32 | break 33 | direction = (direction + 1) % 4 34 | 35 | return order 36 | -------------------------------------------------------------------------------- /Microsoft/540. Single Element in a Sorted Array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def singleNonDuplicate(self, nums) -> int: 3 | left, right = 0, len(nums) - 1 4 | while left < right: 5 | mid = (left + right) // 2 6 | 7 | if mid % 2 == 1: 8 | mid -= 1 9 | 10 | if nums[mid] != nums[mid + 1]: 11 | right = mid 12 | else: 13 | left = mid + 2 14 | return nums[left] 15 | -------------------------------------------------------------------------------- /Microsoft/557. Reverse Words in a String III.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseWords(self, s: str) -> str: 3 | return ' '.join([w[::-1] for w in s.split(' ')]) 4 | -------------------------------------------------------------------------------- /Microsoft/56. Merge Intervals.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def merge(self, intervals): 3 | intervals = sorted(intervals, key=lambda x: x[0]) 4 | 5 | results = [] 6 | for interval in intervals: 7 | if not results: 8 | results.append(interval) 9 | continue 10 | if results[-1][1] < interval[0]: 11 | results.append(interval) 12 | continue 13 | results[-1][1] = max(results[-1][1], interval[1]) 14 | 15 | return results 16 | -------------------------------------------------------------------------------- /Microsoft/636. Exclusive Time of Functions.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def exclusiveTime(self, n: int, logs): 3 | if not logs: 4 | return [] 5 | 6 | stack = [] 7 | results = [0 for _ in range(n)] 8 | 9 | last_time = 0 10 | for log in logs: 11 | id, state, time = log.split(':') 12 | id, time = int(id), int(time) 13 | 14 | if state == 'start': 15 | if stack: 16 | results[stack[-1]] += time - last_time 17 | stack.append(id) 18 | else: 19 | time += 1 20 | results[stack.pop()] += time - last_time 21 | last_time = time 22 | return results 23 | -------------------------------------------------------------------------------- /Microsoft/64. Minimum Path Sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minPathSum(self, grid: List[List[int]]) -> int: 3 | for i in range(len(grid)): 4 | for j in range(len(grid[0])): 5 | if i == 0 and j > 0: 6 | grid[i][j] += grid[i][j - 1] 7 | elif j == 0 and i > 0: 8 | grid[i][j] += grid[i - 1][j] 9 | elif i > 0 and j > 0: 10 | grid[i][j] += min(grid[i - 1][j], grid[i][j - 1]) 11 | 12 | return grid[-1][-1] 13 | -------------------------------------------------------------------------------- /Microsoft/669. Trim a Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution: 9 | def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode: 10 | if root is None: 11 | return None 12 | 13 | if root.val < L: 14 | return self.trimBST(root.right, L, R) 15 | elif root.val > R: 16 | return self.trimBST(root.left, L, R) 17 | else: 18 | root.left = self.trimBST(root.left, L, R) 19 | root.right = self.trimBST(root.right, L, R) 20 | return root 21 | -------------------------------------------------------------------------------- /Microsoft/688. Knight Probability in Chessboard.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def knightProbability(self, N: int, K: int, r: int, c: int) -> float: 3 | next = [[-1, -2], [1, -2], [2, -1], [2, 1], [1, 2], [-1, 2], [-2, 1], [-2, -1]] 4 | dp = [[0 for _ in range(N)] for _ in range(N)] 5 | dp[r][c] = 1 6 | for step in range(1, K + 1): 7 | dpTemp = [[0 for _ in range(N)] for _ in range(N)] 8 | for i in range(N): 9 | for j in range(N): 10 | for dx, dy in next: 11 | lastR, lastC = i - dx, j - dy 12 | if 0 <= lastC < N and 0 <= lastR < N: 13 | dpTemp[i][j] += dp[lastR][lastC] * .125 14 | 15 | dp = dpTemp 16 | 17 | result = 0.0 18 | for i in range(N): 19 | for j in range(N): 20 | result += dp[i][j] 21 | 22 | return result 23 | -------------------------------------------------------------------------------- /Microsoft/695. Max Area of Island.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.dx = [0, 1, 0, -1] 4 | self.dy = [1, 0, -1, 0] 5 | 6 | def maxAreaOfIsland(self, grid) -> int: 7 | if not grid or not grid[0]: 8 | return 0 9 | 10 | rows, cols = len(grid), len(grid[0]) 11 | area = 0 12 | 13 | for i in range(rows): 14 | for j in range(cols): 15 | if grid[i][j]: 16 | area = max(area, self.dfs(grid, i, j, rows, cols, 1)) 17 | 18 | return area 19 | 20 | def dfs(self, grid, x, y, rows, cols, area): 21 | grid[x][y] = 0 22 | 23 | for delta in range(4): 24 | next_x, next_y = x + self.dx[delta], y + self.dy[delta] 25 | if not (0 <= next_x < rows and 0 <= next_y < cols) or grid[next_x][next_y] == 0: 26 | continue 27 | area = 1 + self.dfs(grid, next_x, next_y, rows, cols, area) 28 | 29 | return area 30 | -------------------------------------------------------------------------------- /Microsoft/7. Reverse Integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverse(self, x: int) -> int: 3 | result = 0 4 | 5 | sign = -1 if x < 0 else 1 6 | x = abs(x) 7 | 8 | while x > 0: 9 | result = 10 * result + x % 10 10 | x = x // 10 11 | if result < -(1 << 31) or result > (1 << 31) - 1: 12 | return 0 13 | return sign * result 14 | -------------------------------------------------------------------------------- /Microsoft/722. Remove Comments.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeComments(self, source): 3 | codes = [] 4 | open_black = False 5 | buffer = '' 6 | 7 | for line in source: 8 | i = 0 9 | while i < len(line): 10 | if line[i] == '/' and i + 1 < len(line) and line[i + 1] == '/' and not open_black: 11 | i = len(line) 12 | elif line[i] == '/' and i + 1 < len(line) and line[i + 1] == '*' and not open_black: 13 | open_black = True 14 | i = i + 1 15 | elif line[i] == '*' and i + 1 < len(line) and line[i + 1] == '/' and open_black: 16 | open_black = False 17 | i = i + 1 18 | elif not open_black: 19 | buffer += line[i] 20 | i += 1 21 | if buffer and not open_black: 22 | codes.append(buffer) 23 | buffer = '' 24 | return codes 25 | -------------------------------------------------------------------------------- /Microsoft/75. Sort Colors.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def sortColors(self, nums) -> None: 3 | left, right, index = 0, len(nums) - 1, 0 4 | 5 | while index <= right: 6 | if nums[index] == 0: 7 | nums[index], nums[left] = nums[left], nums[index] 8 | left += 1 9 | index += 1 10 | elif nums[index] == 2: 11 | nums[index], nums[right] = nums[right], nums[index] 12 | right -= 1 13 | else: 14 | index += 1 15 | -------------------------------------------------------------------------------- /Microsoft/768. Max Chunks To Make Sorted II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxChunksToSorted(self, arr) -> int: 3 | if not arr: 4 | return 0 5 | 6 | n = len(arr) 7 | counts = 0 8 | forward = [0 for _ in range(n)] 9 | backward = [0 for _ in range(n)] 10 | 11 | forward[0] = arr[0] 12 | for i in range(1, n): 13 | forward[i] = max(forward[i - 1], arr[i]) 14 | 15 | backward[n - 1] = arr[n - 1] 16 | for i in range(n - 2, -1, -1): 17 | backward[i] = min(backward[i + 1], arr[i]) 18 | 19 | for i in range(n - 1): 20 | if forward[i] <= backward[i + 1]: 21 | counts += 1 22 | 23 | return counts + 1 24 | -------------------------------------------------------------------------------- /Microsoft/769. Max Chunks To Make Sorted.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxChunksToSorted(self, arr) -> int: 3 | if not arr: 4 | return 0 5 | 6 | counts = 0 7 | n = len(arr) 8 | left_max = [0 for _ in range(n)] 9 | right_min = [0 for _ in range(n)] 10 | 11 | left_max[0] = arr[0] 12 | for i in range(1, n): 13 | left_max[i] = max(left_max[i - 1], arr[i]) 14 | 15 | right_min[n - 1] = arr[n - 1] 16 | for i in range(n - 2, -1, -1): 17 | right_min[i] = min(right_min[i + 1], arr[i]) 18 | 19 | for i in range(n - 1): 20 | if left_max[i] <= right_min[i + 1]: 21 | counts += 1 22 | 23 | return counts + 1 24 | -------------------------------------------------------------------------------- /Microsoft/78. Subsets.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subsets(self, nums): 3 | sets = [] 4 | 5 | nums = sorted(nums) 6 | self.dfs(nums, 0, [], sets) 7 | 8 | return sets 9 | 10 | def dfs(self, nums, index, curt, sets): 11 | sets.append(curt[:]) 12 | 13 | for i in range(index, len(nums)): 14 | curt.append(nums[i]) 15 | self.dfs(nums, i + 1, curt, sets) 16 | curt.pop() 17 | -------------------------------------------------------------------------------- /Microsoft/785. Is Graph Bipartite.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isBipartite(self, graph) -> bool: 3 | self.colors = [0 for _ in range(len(graph))] 4 | 5 | for i in range(len(graph)): 6 | if self.colors[i] == 0 and not self.mark(i, graph, 1): 7 | return False 8 | return True 9 | 10 | def mark(self, curt, graph, color): 11 | self.colors[curt] = color 12 | for child in graph[curt]: 13 | if self.colors[child] == 0 and not self.mark(child, graph, -color): 14 | return False 15 | elif self.colors[child] == self.colors[curt]: 16 | return False 17 | return True 18 | -------------------------------------------------------------------------------- /Microsoft/79. Word Search.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.direction = [(0, 1), (0, -1), (1, 0), (-1, 0)] 4 | 5 | def exist(self, board, word: str) -> bool: 6 | if not board or not board[0]: 7 | return False 8 | 9 | rows, cols = len(board), len(board[0]) 10 | visited = [[False for _ in range(cols)] for _ in range(rows)] 11 | 12 | for i in range(rows): 13 | for j in range(cols): 14 | if self.dfs(board, i, j, rows, cols, word, visited): 15 | return True 16 | 17 | return False 18 | 19 | def dfs(self, board, x, y, rows, cols, word, visited): 20 | if word == '': 21 | return True 22 | 23 | if not (0 <= x < rows and 0 <= y < cols): 24 | return False 25 | 26 | if board[x][y] == word[0] and not visited[x][y]: 27 | visited[x][y] = True 28 | 29 | for delta_x, delta_y in self.direction: 30 | if self.dfs(board, x + delta_x, y + delta_y, rows, cols, word[1:], visited): 31 | return True 32 | 33 | visited[x][y] = False 34 | 35 | return False 36 | -------------------------------------------------------------------------------- /Microsoft/794. Valid Tic-Tac-Toe State.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def validTicTacToe(self, board) -> bool: 3 | x_num, o_num = 0, 0 4 | 5 | for i in range(len(board)): 6 | for j in range(len(board[0])): 7 | if board[i][j] == 'X': 8 | x_num += 1 9 | elif board[i][j] == 'O': 10 | o_num += 1 11 | 12 | if o_num > x_num or x_num - o_num > 1: 13 | return False 14 | 15 | if self.check_win(board, 'O'): 16 | if self.check_win(board, 'X'): 17 | return False 18 | 19 | return o_num == x_num 20 | 21 | if self.check_win(board, 'X'): 22 | if self.check_win(board, 'O'): 23 | return False 24 | 25 | return x_num - 1 == o_num 26 | 27 | return True 28 | 29 | def check_win(self, board, player): 30 | # Row 31 | for i in range(len(board)): 32 | if board[i][0] == board[i][1] == board[i][2] == player: 33 | return True 34 | 35 | # Col 36 | for i in range(len(board)): 37 | if board[0][i] == board[1][i] == board[2][i] == player: 38 | return True 39 | 40 | # Diagonal 41 | if board[0][0] == board[1][1] == board[2][2] == player: 42 | return True 43 | if board[0][2] == board[1][1] == board[2][0] == player: 44 | return True 45 | return False 46 | -------------------------------------------------------------------------------- /Microsoft/8. String to Integer (atoi).py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.numbers = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, 4 | '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} 5 | def myAtoi(self, s: str) -> int: 6 | INT_MAX, INT_MIN = 2147483647, -2147483648 7 | 8 | s = s.strip() 9 | if not s: 10 | return 0 11 | 12 | negative = False 13 | if s[0] == '-': 14 | negative = True 15 | s = s[1:] 16 | elif s[0] == '+': 17 | s = s[1:] 18 | 19 | new_s = '' 20 | for char in s: 21 | if char.isdigit(): 22 | new_s += char 23 | else: 24 | break 25 | 26 | if not new_s: 27 | return 0 28 | 29 | result = 0 30 | for char in new_s: 31 | result = 10 * result + self.numbers[char] 32 | 33 | if negative: 34 | result = -result 35 | 36 | if result > INT_MAX: 37 | return INT_MAX 38 | elif result < INT_MIN: 39 | return INT_MIN 40 | else: 41 | return result 42 | -------------------------------------------------------------------------------- /Microsoft/836. Rectangle Overlap.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isRectangleOverlap(self, rec1, rec2) -> bool: 3 | # 左,右 4 | if rec1[2] <= rec2[0] or rec1[0] >= rec2[2]: 5 | return False 6 | # 上,下 7 | if rec1[1] >= rec2[3] or rec1[3] <= rec2[1]: 8 | return False 9 | return True 10 | -------------------------------------------------------------------------------- /Microsoft/863. All Nodes Distance K in Binary Tree.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class TreeNode: 4 | def __init__(self, x): 5 | self.val = x 6 | self.left = None 7 | self.right = None 8 | 9 | class Solution: 10 | def distanceK(self, root: TreeNode, target: TreeNode, K: int): 11 | if root is None: 12 | return [] 13 | 14 | parents = {} 15 | self.find_parents(root, parents) 16 | 17 | queue = deque([target]) 18 | visited = {target} 19 | 20 | distance = 0 21 | while queue and distance < K: 22 | for _ in range(len(queue)): 23 | node = queue.popleft() 24 | 25 | if node.left and node.left not in visited: 26 | queue.append(node.left) 27 | visited.add(node.left) 28 | if node.right and node.right not in visited: 29 | queue.append(node.right) 30 | visited.add(node.right) 31 | if node in parents and parents[node] not in visited: 32 | queue.append(parents[node]) 33 | visited.add(parents[node]) 34 | distance += 1 35 | 36 | return [node.val for node in queue] 37 | 38 | def find_parents(self, root, parents): 39 | if root is None: 40 | return 41 | 42 | if root.left: 43 | parents[root.left] = root 44 | self.find_parents(root.left, parents) 45 | if root.right: 46 | parents[root.right] = root 47 | self.find_parents(root.right, parents) 48 | -------------------------------------------------------------------------------- /Microsoft/909. Snakes and Ladders.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | class Solution: 3 | def snakesAndLadders(self, board) -> int: 4 | n = len(board) 5 | distance = {1: 0} 6 | queue = deque([1]) 7 | 8 | while queue: 9 | s = queue.popleft() 10 | 11 | if s == n * n: 12 | return distance[s] 13 | 14 | for next_step in range(s + 1, min(s + 6, n * n) + 1): 15 | r, c = self.get(next_step, n) 16 | # 快速通道 17 | if board[r][c] != -1: 18 | next_step = board[r][c] 19 | if next_step not in distance: 20 | distance[next_step] = distance[s] + 1 21 | queue.append(next_step) 22 | return -1 23 | 24 | def get(self, s, n): 25 | quotient, remainder = divmod(s - 1, n) 26 | 27 | row = n - 1 - quotient 28 | col = remainder if row % 2 != n % 2 else n - 1 - remainder 29 | 30 | return row, col 31 | -------------------------------------------------------------------------------- /Microsoft/93. Restore IP Addresses.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def restoreIpAddresses(self, s: str): 3 | if not s or len(s) > 12: 4 | return [] 5 | ips = [] 6 | 7 | self.dfs(s, 0, '', ips) 8 | 9 | return ips 10 | 11 | def dfs(self, s, part, ip, ips): 12 | if part == 4: 13 | if s == '': 14 | ips.append(ip[1:]) 15 | return 16 | 17 | for i in range(1, 4): 18 | if i <= len(s): 19 | if int(s[:i]) <= 255: 20 | self.dfs(s[i:], part + 1, ip + '.' + s[:i], ips) 21 | if s[0] == '0': 22 | break 23 | -------------------------------------------------------------------------------- /Microsoft/98. Validate Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def isValidBST(self, root: TreeNode) -> bool: 9 | if root is None: 10 | return True 11 | 12 | is_bst, _, _ = self.dfs(root) 13 | 14 | return is_bst 15 | 16 | def dfs(self, root): 17 | if root is None: 18 | return True, None, None 19 | 20 | left_is_bst, left_min, left_max = self.dfs(root.left) 21 | right_is_bst, right_min, right_max = self.dfs(root.right) 22 | 23 | if not left_is_bst or not right_is_bst: 24 | return False, None, None 25 | if left_max and left_max.val >= root.val: 26 | return False, None, None 27 | if right_min and right_min.val <= root.val: 28 | return False, None, None 29 | 30 | root_min = left_min or root 31 | root_max = right_max or root 32 | 33 | return True, root_min, root_max 34 | -------------------------------------------------------------------------------- /Microsoft/99. Recover Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | class Solution: 8 | def __init__(self): 9 | self.first, self.second = None, None 10 | self.prev = TreeNode(float('-inf')) 11 | 12 | def recoverTree(self, root: TreeNode) -> None: 13 | self.inorder(root) 14 | 15 | self.first.val, self.second.val = self.second.val, self.first.val 16 | 17 | def inorder(self, root): 18 | if root is None: 19 | return 20 | 21 | self.inorder(root.left) 22 | 23 | if not self.first and self.prev.val > root.val: 24 | self.first = self.prev 25 | if self.first and self.prev.val > root.val: 26 | self.second = root 27 | 28 | self.prev = root 29 | 30 | self.inorder(root.right) 31 | -------------------------------------------------------------------------------- /Notes/2020.1.22.md: -------------------------------------------------------------------------------- 1 | # 2020/1/22 2 | 3 | 436. Maximal Square 4 | 二维 dp,dp[i][j] -> 正方形边,dp[i][j] = min(top, left, top_left) + 1,注意边界情况 i == 1 or j === 1 return 1 5 | 6 | 122. Largest Rectangle in Histogram 7 | 单调栈,一直保持递增。遇到递减的: heights[stack[-1]] >= heights[i],就一直弹出一个 prev_height,找到左边界,更新 rectangle -> (i - heights[stack[-1]] - 1 | i) * heights[i],注意最后要加上 -1,在最后一次将所有都弹出 8 | 9 | 510. Maximal Rectangle 10 | 设置 heights 数组,统计每一列的高度,就可以转换成 122. Largest Rectangle in Histogram 的问题。每一行都做一次 122 的求解,对比最大 rectangle 11 | 12 | 697. Sum of Square Numbers 13 | 判断是否 < 0,判断是否可以开根号,将 sprt(num) 作为 upperbound,从 j = 1 -> upperbound 去找是否存在 i * i + j * j == num,j = int(sprt(num - i * i)) 14 | 15 | 64. Merge Sorted Array 16 | 设置 position 指针,两个数组从后往前判断哪个大,哪个大就加入到对应在的 position 位置 17 | 18 | 6. Merge Two Sorted Arrays 19 | 先处理 i < m and i < n 再处理 i < m 和 i < n 的情况,指针一起往前 20 | 21 | 839. Merge Two Sorted Interval Lists 22 | 还是和 Merge Two Sorted Arrays 一样,这次的判断条件是 l1[i1].start < l2[i2].start,然后 push_back。push_back 里要针对当前结果最后一个 interval 的 end 来处理: last.end < start -> 直接 append,否则 last.end = max(last.end, curt.end) 23 | 24 | 212. Space Replacement 25 | 计算 true length = length + 2 * space_counts,调协双指针:index = true_length - 1, i - length - 1,从后往前修改 string 26 | 27 | 56. Two Sum 28 | Super easssssy,用 dictionary 和双指针(比较麻烦)都能做 29 | 30 | 608. Two Sum II - Input array is sorted 31 | 双指针,nums[left] + nums[right] < target -> left += 1 else right -= 1, == target -> return [left + 1, right + 1] 32 | 33 | 607. Two Sum III - Data structure design 34 | 这里用一个 dictionary 去存 { num : count },每次要分是否 target - num == num 去判断。和 Two Sum 有点类似,但是这里多了去重的操作,其实大可以将他们变成数组,每次都用 Two Sum 去做,但是这样 worse case 可能复杂度变高了,例如 [2, 2, 2, 2...] 35 | 36 | 689. Two Sum IV - Input is a BST 37 | 中序遍历,遍历左节点的时候加入 target - left_root.val,在遍历到右节点的时候就判断 right_root.val 是否在 node_set 里即可 38 | 39 | 1797. optimalUtilization 40 | 双指针,left 在 A,right 在 B,初始 optimal 是 A[0] + B[0],每次 A[left] + B[right] 都和 optimal 对比,前提是 A[left] + B[right] <= K and > optimal,如果 > K 或者 right 有重复,就 right -= 1 41 | 42 | 609. Two Sum - Less than or equal to target 43 | 先 sorted 数组,在 A[left] + A[right] <= target 的时候 counts += right - left,left += 1,否则 right -= 1 44 | 45 | 443. Two Sum - Greater than target 46 | 和上题同理,取反即可 47 | 48 | 610. Two Sum - Difference equals to target 49 | nums -> pairs (nums, i), 排序 lambda x: x[0],abs(target),固定 i, j = i + 1 -> n - 1,如果 diff < target,j += 1, > target 就 break,相等就返回结果 50 | 51 | 587. Two Sum - Unique pairs 52 | 注意去重 53 | 54 | 382. Triangle Count 55 | i: n - 1 -> 0,nums[i] 作为 target,然后变成了 443. Greater than target 56 | 57 | 57. 3Sum 58 | two sum 基础上包一层 i: 0 -> n - 3,其中 target = -numbers[i], left = i + 1, right = length - 1 59 | 60 | 58. 4Sum 61 | 3Sum 基础上包一层 i: 0 -> n - 4 62 | 63 | 59. 3Sum Closest 64 | 3Sum 基础上每次都判断是否更 closer -------------------------------------------------------------------------------- /Notes/2020.1.23.md: -------------------------------------------------------------------------------- 1 | # 2020/1/23 2 | 3 | 657. Insert Delete GetRandom O(1) 4 | 插入和删除都要判断 corner case,删除是将最后元素提到 index 那,再 pop 5 | 6 | 954. Insert Delete GetRandom O(1) - Duplicates allowed 7 | 不同的是,self.positions = { val: set },删除的时候每次要 pop index,然后 self.nums[index] = None 8 | 9 | 426. Restore IP Addresses 10 | dfs,分成 4 个 part,当 part == 4 和 s == '' 的时候加入到结果,每次要判断 int(s[:i]) <= 255 11 | 12 | 17. Subsets 13 | 注意要先排序,每次 start -> len(nums) 14 | 15 | 1048. Longest String Chain 16 | 按 word 长度排序,对每个 word 都做 bfs,其中要用 memo 记录当前 word 的 Longest Chain 17 | 18 | 1209. Remove All Adjacent Duplicates in String II 19 | 使用 stack 去存 {char: counts},如果 stack and char in stack[-1].keys() and stack[-1][char] + 1 == k 就 pop,< k 就增加 counts。最后 result += char * counts 即可 20 | 21 | 1047. Remove All Adjacent Duplicates In String 22 | 也使用 stack 去 [char],如果 char == stack[-1] 则 pop,否则 append(char) 23 | 24 | 102. Linked List Cycle 25 | 快慢指针同时走,如果相遇则有 cycle 26 | 27 | 103. Linked List Cycle II 28 | 快慢指针同时走, slow = fast = head,相遇后,slow = head,然后快慢指针继续走,直到 slow == fast,return 29 | 30 | 380. Intersection of Two Linked Lists 31 | 获取两个链表的长度,然后逐次递减,然后双指针同时走,直到 node1 == node2 出现,就是 intersection 32 | 33 | 384. Longest Substring Without Repeating Characters 34 | dict 记录每个 char 最左边的 index,每次 left = max(left, cache[char] + 1),这里要 +1 因为cache[char]还是相同的,要过去一个位置,然后对比 right - left + 1 -------------------------------------------------------------------------------- /Notes/2020.1.24.md: -------------------------------------------------------------------------------- 1 | # 2020/1/24 2 | 3 | 928. Longest Substring with At Most Two Distinct Characters 4 | 使用 dict 去记录每个 char 最右边的 index,每次都更新 r - l 的值,如果 len(dict) > 2,那么更新 l 的值(在 dict 里找最小) 5 | 6 | 386. Longest Substring with At Most K Distinct Characters 7 | 将上题的 2 变成 k 即可 8 | 9 | 669. Coin Change 10 | dp -> 0 ~ amount,每次判断 for curt -> amount, curt - coin >= 0 时,就 dp[curt] = min(dp[curt], dp[curt - coin] + 1),看上一次 + 1 是否更少。注意初始化时都是 float('inf') 11 | 12 | 92. Backpack 13 | dp: n 行 m 列,n -> item, m -> size。 dp[i][j] 前i件物品,size == j 14 | 15 | 125. Backpack II 16 | 和前一题差不同就是 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + 1) 变成 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + V[i - 1]) 17 | 18 | 440. Backpack III 19 | 和前一题不同的是 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + V[i - 1]) 变成 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1] + V[i - 1]) ,因为第i个也可以继续选,所以是 dpi[i][xxxxx] 20 | 21 | 562. Backpack IV 22 | dp[i] 表示 fill 到 i 的时候有多少条路,所以 dp[i] = dp[i] + dp[i - num] 23 | 24 | 563. Backpack V 25 | 和上题代码差不多,但是这里是从后往前,上一题从前往后是可以一直累积路径,而从后往前则不能,也就是每个数只能用一次 26 | 27 | 749. John's backyard garden 28 | 这题和 Coin Change 差不多,只是不计算多少个,而是简单地判断 29 | 30 | 588. Partition Equal Subset Sum 31 | 先 sum(nums) -> target,判断 target % 2 == 1? -> False。然后 target // 2 -> m,再用 dp 做即可 32 | 33 | 134. LRU Cache 34 | Easy, Linked list + hash table 背背佳 -------------------------------------------------------------------------------- /Notes/2020.1.26.md: -------------------------------------------------------------------------------- 1 | # 2020/1/26 2 | 3 | doc1. Find Parent 4 | 统计每个节点的入度,再去看入度是 0 或者 1,然后加入 results 即可,这里要注意的是 parent 有可能也能成为 child 5 | 6 | doc2. Has Common 7 | 递归找 Parents,将 parents 都找出来遍历判断是否有相同节点(Parents) 8 | 9 | doc3. Highest Parent 10 | 递归找 Parents,每次都打擂台去更新结果即可 11 | 12 | doc4. Calculator 13 | 很简单的 Calculator,在开始之前要加 '+' 来完成最后一次的计算 14 | 15 | doc5. Basic Calculator 16 | 在前一题的基础上加一个 stack,遇到 '(' 将 result 和 sign 加入,result = 0, sign = 1 相当于重新算 result。遇到 ')' 计算当前的 result,然后算前一次的 sign 和与前一次的 result 相加,再 pop 掉两次 17 | 18 | doc6. Variable Calculator 19 | 在前一题的基础上加一个 var,遇到字母就 var += char,再加一个 flag 判断当前应该是 number 还是 self.map[var] 20 | 21 | doc7. Friend List 22 | 用边生成无向图 23 | 24 | doc8. Get Department Stat 25 | 直接写即可,只要判断存在有不同部门的人就 break 26 | 27 | doc9. Friends In One Place 28 | BFS 29 | 30 | doc10. Task Order 31 | [0, 1] 先修完 1 再修 0,图里应该是 1 的 neighbors 是 0, 1 -> 0 应该表示 1 的下一步是 0,而不是关系。还有初始化的时候要将入度为 0 的加到 queue 里。 32 | 33 | doc11. Enter Exit 34 | enter: 1, exit: -1,每次都计算状态,如果不是 0 就是 mismatch 35 | 36 | doc12. Find 3 Times 37 | 用 heap 来存时间,再次遍历的时候找 time + 60 的 index,看 index - i >= 3 ? -> 找到,break 38 | 39 | doc13. Domain Click 40 | 简单的计数,注意要从后往前连接即可 41 | 42 | doc14. Longest Continuous Common History 43 | 使用 dp,dp[i][j] 表示 user[i] 和 user[j] 前最长的 continuous common history,如果 user1[i - 1] == user2[j - 1],dp[i][j] = dp[i - 1][j - 1] + 1,这个是长度,更新长度的时候也要更新 right = i - 1,最后 right -> right - i 去 append(user[i]) 即可 44 | 45 | doc15. Meeting Room 46 | 先以 interval.start 来排序,lambda x: x.start,再比较 intervals[i].end > intervals[i + 1].start ? -> return False -------------------------------------------------------------------------------- /Notes/2020.1.27.md: -------------------------------------------------------------------------------- 1 | # 2020/1/27 2 | 3 | doc16. Merge Interval 4 | 先按 interval.start 来排序,设置 left, right,如果 right < interval.start,那么将 Interval(left, right) 加入,否则更新 right = max(right, interval.end),将最后一次 Interval(left, right) 加入 5 | 6 | doc17. Sparse Vector Class 7 | 并没有觉得什么难的 8 | 9 | 651. Binary Tree Vertical Order Traversal 10 | 使用 dictionary 来存,index: node,记 root: x, root.left: x - 1,root.right: x + 1,初始化 root -> 0,然后用 BFS 去遍历存好,再按顺序生成即可 11 | 12 | 363. Trapping Rain Water 13 | 每次累加 max - curt 14 | 15 | 453. Flatten Binary Tree to Linked List 16 | divide_conquer,每次返回 tail,如果 left_tail 不存在就返回,否则连接,注意要将 root.left 断开,返回 -> right_tail or left_tail or root 17 | 18 | 1534. Convert Binary Search Tree to Sorted Doubly Linked List 19 | first 和 prev 记录开头和结尾,使用 inorder 去做,left 看成是 prev,right 看成是 next 即可 20 | 21 | 362. Sliding Window Maximum 22 | 使用 deque,一直保证是单调递减的,如果 nums[dq[-1]] > nums[i] 就 dq.pop(),如果 dp[0] == i - k + 1 就是大于 k 了,就 popleft(),每次 results.append(nums[dq[0]) 就是最大值 23 | 24 | 131. The Skyline Problem 25 | 放弃了。。 -------------------------------------------------------------------------------- /Notes/2020.1.28.md: -------------------------------------------------------------------------------- 1 | # 2020/1/28 2 | 3 | 854. Closest Leaf in a Binary Tree 4 | dfs 遍历,将 parents 找全,找到疑似 k 的 node。从 node 开始做 BFS,分别加入左节点,右节点,parents 节点。如果遇到叶子节点就 return 5 | 6 | 189. First Missing Positive 7 | 遍历数组,将 A[A[i] - 1] 和 A[i] 进行交换,注意条件是 A[i] in bound,A[A[i] - 1] != A[i] 和 A[i] != i + 1。最后再遍历一次,遇到非法就 return i + 1 8 | 9 | 633. Find the Duplicate Number 10 | 使用快慢指针,slow, fast = nums[0], nums[nums[0]],相遇后,slow = 0 再次移动找到开始环的 index 11 | 12 | 196. Missing Number 13 | 和 189 差不多,就是条件变成了 i != nums[i],还有不能直接用 python 的方式去交换: A[A[i] - 1] != A[i] 和 A[i] != i + 1(错的) 14 | 15 | 570. Find the Missing Number II 16 | dfs 去找,用 used 去存是否被访问过了,所有不符合要求的返回 -1,如果符合要求就返回结果,每次截取 1 -> 2 个字符 17 | 18 | 362. Sliding Window Maximum 19 | 复习 20 | 21 | 928. Longest Substring with At Most Two Distinct Characters 22 | 用 dictionary 记录 longest substring 的 { char: index },如果 len(dict) > 2 就要更新 left = min(left, value),再更新 longest = max(longest, right - left + 1) 23 | 24 | 692. Sliding Window Unique Elements Sum 25 | 用一个 dictionary 来存放 { num: counts },遍历的时候先看 nums[i - k] 再看 nums[i]。要注意 window[nums[i]] == 1 的情况,分成 not unique 和 unique again 26 | 27 | 81. Find Median from Data Stream 28 | 左边是存 max_heap,右边存 min_heap,中位数就是 max_heap[0] 29 | 30 | 360. Sliding Window Median 31 | 先将前 k - 1 个元素加入 max_heap 和 min_heap,再 slide window,每次先加入,maintain balance,获取中位数,再移除 nums[i - k + 1] 32 | 33 | 604. Window Sum 34 | prefix sum 解决,先初始化 sums[0],再计算 sums[i] = sums[i - 1] + nums[i + k - 1] - nums[i - 1] -------------------------------------------------------------------------------- /Notes/2020.1.29.md: -------------------------------------------------------------------------------- 1 | # 2020/1/29 2 | 3 | 512. Decode Ways 4 | dp 解,dp[i] = dp[i - 2] + dp[i - 1],两种情况相加:当前看成是两个数字(10,20看成一个数字),或看成一个数字(不算 0) 5 | 6 | 657. Insert Delete GetRandom O(1) 7 | 复习,删除的时候将最后一个元素将要删除的元素覆盖,再 pop,同时更新 positions 8 | 9 | 954. Insert Delete GetRandom O(1) - Duplicates allowed 10 | 复习,和上一题不一样的是,self.positions = { val: set() },删除的时候直接 self.nums[index] = None 11 | 12 | 1534. Convert Binary Search Tree to Sorted Doubly Linked List 13 | 复习,将 left 看成 prev,将 right 看成 next。做 inorder,最后返回 first 14 | 15 | 651. Binary Tree Vertical Order Traversal 16 | 复习,BFS,node -> index,node.left -> index - 1,node.right -> index + 1 17 | 18 | 69. Binary Tree Level Order Traversal 19 | Easy BFS 20 | 21 | 363. Trapping Rain Water 22 | 复习,左右双指针 23 | 24 | 383. Container With Most Water 25 | 左右指针向中间靠,遍历所有情况即可,min(heights[left], heights[right]) * (right - left) 26 | 27 | 1310. Product of Array Except Self 28 | 对于 products[i] = 前 i - 1 相乘 * 后 i + 1 相乘,所以累乘起来就可以了 29 | 30 | 453. Flatten Binary Tree to Linked List 31 | 复习,注意最后要 return root 32 | 33 | 601. Flatten 2D Vector 34 | next() 的时候,如果 self.next_elem 是空,就先 has_next 一下。has_next 里先找到目标位置,再去判断目标位置是否合法,最后赋值返回 True/False 35 | 36 | 528. Flatten Nested List Iterator 37 | 这里本来是可以用 queue 的,但是如果 item 是 list 那么不能在 queue 前面追加,所以要用反向 stack 来做 38 | 39 | 242. Convert Binary Tree to Linked Lists by Depth 40 | 简单的 BFS 41 | 42 | 106. Convert Sorted List to Binary Search Tree 43 | 找中点,递归 dfs(head) 和 dfs(middle.next),注意要将 slow.next = None -------------------------------------------------------------------------------- /Notes/2020.1.30.md: -------------------------------------------------------------------------------- 1 | # 2020/1/30 2 | 3 | 547. Intersection of Two Arrays 4 | 三种方法:binary search, hash set, sort + 遍历 5 | 6 | 548. Intersection of Two Arrays II 7 | hash map 去计数,遍历另一个 array 就可以了 8 | 9 | 248. Count of Smaller Number 10 | 遍历 + binary search 11 | 12 | 6. Merge Two Sorted Arrays 13 | 两种方法:1. 一直排出 2. 一个循环来选中 14 | 15 | 64. Merge Sorted Array 16 | 将 B merge 到 A,从 A 的后面插入 17 | 18 | 165. Merge Two Sorted Lists 19 | 复习,超简单 20 | 21 | 104. Merge K Sorted Lists 22 | 三种方法: 23 | 1) Heap 24 | 2) 归并算法思想:merge by range -> merge 25 | 3) 相邻归并思想:merge by adjacent -> merge 26 | 27 | 839. Merge Two Sorted Interval Lists 28 | 用 push_back 去替换 append。其中,push_back 判断 results 是否为空,last.end < interval.start ? 29 | 30 | 981. Time Based Key-Value Store 31 | key 对应两个数组 values 和 times,在 times 里二查找到 index,返回 values[index] 32 | -------------------------------------------------------------------------------- /Notes/2020.1.31.md: -------------------------------------------------------------------------------- 1 | # 2020/1/31 2 | 3 | 1745. Monotonic Array 4 | 定义 inc 和 dec,如果遇到反例就变成 False,每次判断 inc 和 dec 是否都是 False,如果都是 False 就是有增有减,return False 5 | 6 | 838. Subarray Sum Equals K 7 | prefix_sum + dict。注意条件是 if ps - k in store,因为 p_large - p_small = k,后期应该是要看 p_large - k 是否在 store 里的 8 | 9 | 837. Palindromic Substrings 10 | 使用 dp 解法,dp[j][i] 是看 str[j:i + 1] 是否是回文串,条件是 j + 1, i - 1 的位置也是回文,或者 j - i <= 2 ,还有 str[i] == str[j] 11 | 12 | 551. Nested List Weight Sum 13 | DFS 解决 14 | 15 | 408. Add Binary 16 | 一开始想用 merge sorted arrays,但是其实每个元素可以这样获取:x = int(a[i]) if i >= 0 else 0,循环条件是 while i >= 0 or j >= 0 17 | 18 | 1704. Range Sum of BST 19 | 简单的分治法 20 | 21 | 945. Task Scheduler 22 | 最大的 frequency 是 k ,ans = (k - 1) * (n + 1) + p,p 有相同的频率 23 | 24 | 920. Meeting Rooms 25 | 按 interval.start 排序,遍历加判断 26 | 27 | 919. Meeting Rooms II 28 | 扫描线,将 start, end 变成数据点,start: + 1, end: - 1,每次看有多少个 meeting,比较需要多少个 room 29 | 30 | 760. Binary Tree Right Side View 31 | 获取每一层的最右节点,先遍历右节点,再遍历左节点 32 | 33 | 421. Simplify Path 34 | 将字符串以 '/' 分开,使用 stack,如果不是 '.' 和 '' 就加入,遇到 '..' 就 pop -------------------------------------------------------------------------------- /Notes/2020.2.1.md: -------------------------------------------------------------------------------- 1 | # 2020/2/1 2 | 3 | 137. Clone Graph 4 | 用 dict 记录 old node -> new node,要注意将 root = node,最后 return store[root],因为 node 变量会变 5 | 6 | 123. Word Search 7 | 遍历 + dfs 8 | 9 | 105. Copy List with Random Pointer 10 | 两种方法: 11 | 1) 用 dictionary 去存 12 | 2) oldNode -> newNode 去获取 13 | 14 | 95. Validate Binary Search Tree 15 | 分治法,每次递归获取 min_node, max_node 16 | 17 | 74. First Bad Version 18 | 二分法 19 | 20 | 62. Search in Rotated Sorted Array 21 | 二层对比:先 A[left] < A[mid],再比 A[left] <= target <= A[mid],都和 A[mid] 有关,第一次是 A[left],再一次是 A[right] 22 | 23 | 32. Minimum Window Substring 24 | 固定左边界 i,再去找 window 的右边界 j,不断比较 min_len 即可 25 | 26 | 17. Subsets 27 | dfs,注意要先排序,还有每次递归应该从 i 开始 -> self.dfs(nums, i + 1, curt, sets) 不是 self.dfs(nums, index + 1, curt, sets) 28 | 29 | 892. Alien Dictionary 30 | 按字母大小构图,拓扑排序。注意要用 heapify(queue) 来获取字符大小顺序。同时,每个字符都要加入图中,因为所有字符都要排序 31 | 32 | 362. Sliding Window Maximum 33 | 单调栈,注意每次加入的是 index,因为要 popleft 之前的时候需要 index 判断是否 window size 超过 k 34 | 35 | 121. Word Ladder II 36 | 先 BFS 从 end 到所有点,算距离,再 dfs 从 start 到 end,如果 distances[next_word] == distances[curt] - 1 才继续 dfs 37 | 38 | 653. Expression Add Operators 39 | dfs,有点难。要保存 last ,因为有可能 3 + 2 * 2 的时候要先算乘法。还要注意最后要 if x == 0: break 40 | -------------------------------------------------------------------------------- /Notes/2020.2.10.md: -------------------------------------------------------------------------------- 1 | # 2020/2/10 2 | 3 | 778. Pacific Atlantic Water Flow 4 | 从四周开始 DFS ,然后找两个 set 的交集即可 5 | 6 | 1647. Path Search 7 | 构图,对于 node: neighbors ,对 neighbors.sort()。全局的 visited 主要是为了防止出现环 8 | 9 | 1101. Maximum Width of Binary Tree 10 | 这里和 vertical traversal 不一样的是, root.left -> 2 * index, root.right -> 2 * index + 1 11 | 12 | 1353. Sum Root to Leaf Numbers 13 | 找出所有的数,再 sum 14 | 15 | 1612. Smallest Path 16 | dp 类似 unique path 17 | 18 | 790. Parser 19 | 不直接处理字符串,将字符串变成 list ,来处理 list 20 | 21 | 1015. Find Eventual Safe States 22 | 23 | 1003. Binary Tree Pruning 24 | 25 | 677. Number of Big Islands 26 | 27 | 619. Binary Tree Longest Consecutive Sequence III 28 | 29 | 652. Factorization 30 | 31 | 570. Find the Missing Number II -------------------------------------------------------------------------------- /Notes/2020.2.11.md: -------------------------------------------------------------------------------- 1 | # 2020/2/11 2 | 3 | 742 Closest Leaf in a Binary Tree 4 | 5 | 41 First Missing Positive 6 | 7 | 239 Sliding Window Maximum 8 | 9 | 91 Decode Ways 10 | 11 | 380 Insert Delete GetRandom O(1) 12 | 13 | 426 Convert Binary Search Tree to Sorted Doubly Linked List 14 | 15 | 350 Intersection of Two Arrays II 16 | 17 | 981 Time Based Key-Value Store 18 | 19 | 381 Insert Delete GetRandom O(1) - Duplicates allowed 20 | 21 | 314 Binary Tree Vertical Order Traversal 22 | 23 | 42 Trapping Rain Water 24 | 25 | 114 Flatten Binary Tree to Linked List 26 | 27 | 987 Vertical Order Traversal of a Binary Tree 28 | 29 | 196. Missing Number 30 | 31 | 570. Find the Missing Number II 32 | 33 | 633. Find the Duplicate Number 34 | 35 | 928. Longest Substring with At Most Two Distinct Characters 36 | 37 | 104. Merge K Sorted Lists 38 | 39 | 67. Binary Tree Inorder Traversal 40 | 三种解法:1. dfs 2. 用 stack 3. Morris 41 | 42 | 392. House Robber 43 | dp 解法 44 | 45 | 534. House Robber II 46 | 两次 dp,第一次去掉第一间房子,第二次去掉最后一间房子 47 | -------------------------------------------------------------------------------- /Notes/2020.2.12.md: -------------------------------------------------------------------------------- 1 | # 2020/2/12 2 | 3 | 复习 Databricks 题库 4 | 5 | 131. The Skyline Problem + 218. The Skyline Problem 6 | 7 | 总结 Databricks 题库 -------------------------------------------------------------------------------- /Notes/2020.2.13.md: -------------------------------------------------------------------------------- 1 | # 2020/2/13 2 | 3 | 复习 Databricks 题库 4 | 5 | 总结 Databricks 题库 6 | 7 | 1534. Convert Binary Search Tree to Sorted Doubly Linked List 8 | 分治法 9 | 10 | 378. Convert Binary Tree to Doubly Linked List 11 | 分治法即可,左边生成 doubly linked list,右边生成 doubly linked list,全在一起就可以了 12 | 13 | 1823. Longest Prefix of Array 14 | 遍历一下,如果有符合要求的就设置为 True,最后再检查一下 15 | 16 | 1822. Minimum Moves 17 | 遇到 'a' offset += 1 ,如果 offset == 3 说明要变了,所以 steps += 1,重置 offset = 0 18 | 19 | 1821. Min Deletions To Obtain String in Right Format 20 | 可以一开始先数 A 的数,就是假定要将所有的 A 都变成 B,然后再遍历,如果是 A 那么就不用变,所以 rhs -= 1 ,如果是 B,说明要加入新的 B 21 | 22 | 1820. Find Letter 23 | 两个 set 存放 lower 和 upper,从 upper 取数,每次都比较是否比 result 大 24 | 25 | 1819. Longest Semi Alternating Substring 26 | 这题比较无聊 -------------------------------------------------------------------------------- /Notes/2020.2.15.md: -------------------------------------------------------------------------------- 1 | # 2020/2/15 2 | 3 | 复习 Databricks 题库 4 | 5 | 加了 Inorder traversal 的总结 6 | 7 | 加了 House Bobber 的总结 8 | 9 | 535. House Robber III 10 | 11 | A: How to get a DP Path 12 | Q: 用 backtrack 数组去记录,backtrack[i] 应该记录上一个的坐标。当要获取路径的时候,就要关注哪个 Index 要被加入到路径,否则就忽略或者移到下一个坐标 13 | 14 | 加了 Merge K Sorted Lists 的总结 15 | -------------------------------------------------------------------------------- /Notes/2020.2.17.md: -------------------------------------------------------------------------------- 1 | # 2020/2/17 2 | 3 | 复习 Databricks 题库 4 | 5 | 准备明天的面试,BQ,项目介绍等 6 | -------------------------------------------------------------------------------- /Notes/2020.2.19.md: -------------------------------------------------------------------------------- 1 | # 2020/2/19 2 | 3 | 935. Cartesian Product 4 | dfs 组合问题,从每个 list 选一个数出来组成结果 5 | 6 | 1360. Symmetric Tree 7 | 对比 left.left 和 right.right 以及 left.right 和 right.left 8 | 9 | 1208. Target Sum 10 | 第一种是暴力 DFS 解法 11 | 第二种 DFS + memo, memo[(start, curt)] -> ways 12 | 13 | 1413. Tree 14 | BFS + 找 fathers,要注意用 visited 去存已访问过的点 15 | 16 | 1410. Matrix Water Injection 17 | 一道经典的小岛问题 18 | 19 | 1479. Can Reach The Endpoint 20 | 常规小岛问题 21 | 22 | 808. Movie Network 23 | 图 + BFS + heap,注意不要把开始的点也算进去 24 | 25 | 1386. Cable Car Ride 26 | DFS + memo, memo[x][y] = cost 27 | 28 | 878. Boundary of Binary Tree 29 | 找左边界,右边界,leaves 然后合在一起就可以了 30 | 31 | 1244. Minimum Genetic Mutation 32 | word ladder 的 BFS 经典题 33 | 34 | 164. Unique Binary Search Trees II 35 | 分治,start -> end -------------------------------------------------------------------------------- /Notes/2020.2.20.md: -------------------------------------------------------------------------------- 1 | # 2020/2/20 2 | 3 | 1374. Shortest Distance in 3D Space 4 | 3D 版本的 BFS 5 | 6 | 477. Surrounded Regions 7 | 先把从边界开始的 O 都标记为 W,这样非 W 的地方就全都需要标记为 X 8 | 9 | 814. Shortest Path in Undirected Graph 10 | 双向 BFS 11 | 12 | 750. Portal 13 | 典型的 BFS 14 | -------------------------------------------------------------------------------- /Notes/2020.2.21.md: -------------------------------------------------------------------------------- 1 | # 2020/2/21 2 | 3 | 348. Design Tic-Tac-Toe 4 | 左到右,上到下,左上到右下,右上到左下,如果可以遍历完,就返回 player 5 | 6 | 138. Coy List With Random Pointer 7 | 两种方法:1) 用 hash table 存关系 2) old node -> new node 8 | 9 | 5. Longest Palindromic Substring 10 | 中间开始向两边看 11 | 12 | 151. Reverse Words in a String 13 | 使用内部函数即可 14 | 15 | 794. Valid Tic-Tac-Toe State 16 | 判断 o_num 和 x_num 的关系,再判断如果某个玩家赢了之后的情况 17 | 18 | 273. Integer to English Words 19 | 枚举 + 递归,多种情况都要考虑,分成 < 20, tens, thousands, million, billion 20 | 21 | 146. LRU Cache 22 | Hash table + Linked list 23 | 24 | 42. Trapping Rain Water 25 | 两种方法,1) 双指针,2) 单调栈 26 | 27 | 134. Gas Station 28 | 一路走下去,遇到 gas_remain < 0 就从 i + 1 开始 29 | 30 | 443. String Compression 31 | 双指针做法,注意 chars[left + 1:left + 1 + len(len_str)] = len_str,这里要算的是 len_str 的长度 32 | 33 | 206. Reverse Linked List 34 | 很简单的一道题 -------------------------------------------------------------------------------- /Notes/2020.2.22.md: -------------------------------------------------------------------------------- 1 | # 2020/2/22 2 | 3 | 557. Reverse Words in a String III 4 | 比较直白的一道题 5 | 6 | 44. Wildcard Matching 7 | 两种方法:DFS + memo / DP。DFS + memo 要考虑多种情况,DP 只考虑当前情况 8 | 9 | 909. Snakes and Ladders 10 | BFS + Hash Table,比较难的地方是算坐标,这里要 s - 1 11 | 12 | 103. Binary Tree Zigzag Level Order Traversal 13 | 正常的 BFS order traversal,不同的是需要一个中间的 queue 去记录,而不是直接 popleft,还需要有一个 flag 记录顺序 14 | 15 | 54. Spiral Matrix 16 | 经典题 17 | 18 | 297. Serialize and Deserialize Binary Tree 19 | DFS 返回数组比较容易 20 | 21 | 769. Max Chunks To Make Sorted 22 | 找前缀最大和后缀最小, 每个区间结尾的位置必然是前缀Max小于下一个位置的后缀Min 23 | 24 | 768. Max Chunks To Make Sorted II 25 | 和前一题的解法一样 26 | 27 | 1185. Day of the Week 28 | 算两个时间点的天数差,再去取余,再去找星期几 29 | 30 | 1. Two Sum 31 | 很简单的一道题 32 | 33 | 22. Generate Parentheses 34 | 要注意的是 left num <= right num 35 | 36 | 470. Implement Rand10() Using Rand7() 37 | 比较 tricky 的一道题 38 | 39 | 200. Number Of Islands 40 | Easy~ 41 | 42 | 98. Validate Binary Search Tree 43 | 分治,要注意等于的情况也算是 False -------------------------------------------------------------------------------- /Notes/2020.2.23.md: -------------------------------------------------------------------------------- 1 | # 2020/2/23 2 | 3 | 535. Encode and Decode TinyURL 4 | 很奇怪的一道题 5 | 6 | 93. Restore IP Addresses 7 | 普通的 DFS 8 | 9 | 25. Reverse Nodes in k-Group 10 | 遍历一次,每次先找 n1 ->...-> nk,断开 nk -> nk_next,将 n1 -> ... -> nk 反转,再继续 11 | 12 | 431. Encode N-ary Tree to Binary Tree 13 | n-ary 可以生成 14 | ``` 15 | root 16 | / 17 | left 18 | \ 19 | rest nodes 20 | ``` 21 | 22 | 232. Implement Queue using Stacks 23 | 两个 stack 互相作用 24 | 25 | 127. Word Ladder 26 | 经典的 BFS 题 27 | 28 | 21. Merge Two Sorted Lists 29 | EZPZ 30 | 31 | 510. Inorder Successor in BST II 32 | 如果有右节点,就找右节点的最左节点,否则要一直找一个 parent,使得 parent.val > node.val 33 | 34 | 105. Construct Binary Tree from Preorder and Inorder Traversal 35 | 这里要注意的是 preorder 和 inorder 都只去掉 root 的元素就可以了 36 | 37 | 445. Add Two Numbers II 38 | 获取 number 相加,再生成 linked list 39 | 40 | 236. Lowest Common Ancestor of a Binary Tree 41 | 判断 root 是否是 p, q。再去看左右两边的结果 42 | 43 | 836. Rectangle Overlap 44 | 这道题要静下心来想,要注意等于的情况 45 | 46 | 225. Implement Stack using Queues 47 | 两个 queue,pop 和 top 的时候要看最后一个 pop 出来的元素即可 48 | 49 | 8. String to Integer (atoi) 50 | 首先 strip,看符号,去掉非数字,生成数字,判断是否 overflow 51 | 52 | 23. Merge k Sorted Lists 53 | EZ 54 | 55 | 53. Maximum Subarray 56 | prefix sum + 全局记录 min sum 和 max sum 57 | 58 | 116. Populating Next Right Pointers in Each Node 59 | BFS 分层法 -------------------------------------------------------------------------------- /Notes/2020.2.25.md: -------------------------------------------------------------------------------- 1 | # 2020/2/25 2 | 3 | 2. Add Two Numbers 4 | 使用 carry 贯穿 5 | 6 | 722. Remove Comments 7 | 考虑 open block 的情况 8 | 9 | 56. Merge Intervals 10 | 经典题 11 | 12 | 540. Single Element in a Sorted Array 13 | 二分法 14 | 15 | 99. Recover Binary Search Tree 16 | 找到 first = prev,和 second = root,交换这两个节点的值 -------------------------------------------------------------------------------- /Notes/2020.2.26.md: -------------------------------------------------------------------------------- 1 | # 2020/2/26 2 | 3 | 863. All Nodes Distance K in Binary Tree 4 | 传统 BFS + queue 5 | 6 | 450. Delete Node in a BST 7 | 分两种情况,第一,只有一个节点就直接接上,第二,两个节点找右节点的最左节点,交换值后更改树结构 8 | 9 | 33. Search in Rotated Sorted Array 10 | 二分法 11 | 12 | 121. Best Time to Buy and Sell Stock 13 | 遍历,找最小 price,和最大 profit 14 | 15 | 143. Reorder List 16 | 找中点,反序,合并 -------------------------------------------------------------------------------- /Notes/2020.2.27.md: -------------------------------------------------------------------------------- 1 | # 2020/2/27 2 | 3 | 340. Longest Substring with At Most K Distinct Characters 4 | 5 | 240. Search a 2D Matrix II 6 | 7 | 10. Regular Expression Matching -------------------------------------------------------------------------------- /Notes/2020.2.28.md: -------------------------------------------------------------------------------- 1 | # 2020/2/28 2 | 3 | 75. Sort Colors 4 | ndex 从左到右扫描每个数,如果碰到 0 就丢给 left,碰到 2 就丢给 right。碰到 1 就跳过不管 5 | 6 | 13. Roman to Integer 7 | 从右往左去算数字 8 | 9 | 133. Clone Graph 10 | 用一个 map 去存放关系即可 11 | 12 | 19. Remove Nth Node From End of List 13 | 注意要用 dummy node 14 | 15 | 7. Reverse Integer 16 | 注意 overflow 的情况 17 | -------------------------------------------------------------------------------- /Notes/2020.2.29.md: -------------------------------------------------------------------------------- 1 | # 2020/2/29 2 | 3 | 415. Add Strings 4 | 正常相加 5 | 6 | 346. Moving Average from Data Stream 7 | 用一个数组存 window 8 | 9 | 636. Exclusive Time of Functions 10 | 注意要加1,使得计算整个长度 11 | 12 | 207. Course Schedule 13 | BFS + 拓扑排序 14 | 15 | 168. Excel Sheet Column Title 16 | 注意要先减1再做转换 17 | 18 | 142. Linked List Cycle II -------------------------------------------------------------------------------- /Notes/2020.2.3.md: -------------------------------------------------------------------------------- 1 | # 2020/2/3 2 | 3 | doc1. Find Parent 4 | { child: num of parents } 5 | 时间:O(n + m),空间:O(n + m) 6 | 7 | doc2. Has Common 8 | 1. 构图,2. 找所有 parents,3. 从所有 parents 里找是否存在 parent 9 | 时间:O(n + m),空间:O(n + m) 10 | 11 | doc3. Highest Parent 12 | 1. 构图,2. dfs/bfs 遍历所以 parents,3. 每次都赋值 self.result 13 | 时间:O(n + m),空间:O(n + m) 14 | 15 | doc4. Naive Calculator 16 | 遇到数字,计算当前 num,遇到符号,先处理前面的结果,再算新 sign。最后要再算一次结果 17 | 时间:O(n),空间:O(1) 18 | 19 | doc5. Basic Calculator 20 | 遇到 '(',加入 result 和 sign,重置 result 和 sign。遇到 ')',先算括号里的 result,算 result * stack[-1] 和 result + stack[-1] 分别 pop,重置 sign 21 | 时间:O(n),空间:O(1) 22 | 23 | doc6. Variable Calculator 24 | 计算 result += sign * num -> result += sign * (num if is_num else self.map[var]) 25 | 时间:O(n),空间:O(1) 26 | 27 | doc7. Friend List 28 | 构图 29 | 时间:O(n + m),空间:O(n + m) 30 | 31 | doc8. Get Department Stat 32 | 构图,三层循环判断 33 | 时间:O(depart * employee * friend),空间:O(depart + employee + friend) 34 | 35 | doc9. Friends In One Place 36 | 构图,BFS 37 | 时间:O(n + m),空间:O(n + m) 38 | 39 | doc10. Task Order 40 | 构图,BFS + 拓扑 41 | 时间:O(n + m),空间:O(n + m) 42 | 43 | doc11. Enter Exit 44 | Enter: 1,Exit: -1,返回 status == 0 的人 45 | 时间:O(n),空间:O(n) 46 | 47 | doc12 Find 3 Times 48 | 遍历时间,每次从 i 开始找,二分去找 49 | 时间:O(name + times),空间:O(name + times) 50 | 51 | doc13. Domain Click 52 | 遍历,注意第一次的时候 53 | 时间:O(n + m),空间:O(n + m) 54 | 55 | doc14. Longest Continuous Common History 56 | dp,dp[i][j] 表示前 i 和 前 j 的最长的历史长度,同时,每次更新 right = i - 1 57 | 时间:O(n * m),空间:O(n * m) 58 | 59 | doc15. Meeting Room 60 | 扫描线,最后判断 rooms == 1? 61 | 62 | doc16. Merge Intervals 63 | 注意要先排序 64 | 65 | doc17. Sparse Vector Class 66 | 注意要用 self.get(i),不要 self.vector[i] 67 | -------------------------------------------------------------------------------- /Notes/2020.2.4.md: -------------------------------------------------------------------------------- 1 | # 2020/2/4 2 | 3 | 1. 复习 databricks karat doc 1 - 17 4 | 5 | 615. Course Schedule 6 | 拓扑排序,但是构图的时候不要用 set ,要用 list,因为有可能边会重复 7 | 8 | 616. Course Schedule II 9 | 还是拓扑 10 | 11 | 696. Course Schedule III 12 | 按 deadline 排序,用 heap 存放 -duration,如果当下超出 deadline,那么去掉一节 duration 最长的课 13 | 14 | 742. Closest Leaf in a Binary Tree 15 | BFS 的时候不要用 if-elif ,应该都是 if-if 16 | 17 | 41. First Missing Positive 18 | 将 nums[nums[i] - 1] 和 nums[i] 进行交换,最后要返回 i + 1 或者 n + 1 19 | 20 | 239. Sliding Window Maximum 21 | push 的时候要对比 nums[queue[-1]] 和 nums[i] 22 | 23 | 91. Decode Ways 24 | 双数(正常情况和 10, 20 情况) + 单数 25 | 26 | 380. Insert Delete GetRandom O(1) 27 | 删除的时候,记得要 del self.positions[val] 28 | 29 | 426. Convert Binary Search Tree to Sorted Doubly Linked List 30 | 要用 inorder 去做,中间要初始化 self.first 和连接 self.prev 和 root,再将 self.prev = root 传下去。最后还要将 self.first 和 self.prev 首尾相连 31 | 32 | 350. Intersection of Two Arrays II 33 | 用 dictionary 做 34 | 35 | 981. Time Based Key-Value Store 36 | 用两个数组存,找时间的时候用二分 37 | 38 | 381. Insert Delete GetRandom O(1) - Duplicates allowed 39 | 注意要用 if not self.positions[val],还有要用 random.choice(self.nums) -> 防止死循环 40 | 41 | 42. Trapping Rain Water 42 | 简单 43 | 44 | 114. Flatten Binary Tree to Linked List 45 | 返回 tail,如果有 left_tail 再继续下一步 46 | 47 | 314. Binary Tree Vertical Order Traversal 48 | root.left: -1 root.right: +1 49 | 50 | 987. Vertical Order Traversal of a Binary Tree 51 | 这题和上一题有点不一样,坐标不一样,root.left: x - 1, y + 1,root.right: x + 1, y + 1。同时要 sorted, key = lambda x: (x[0], x[1], x[2]) 52 | 将 mapping 数组变成 {index: [num...]},返回 store.values() 53 | -------------------------------------------------------------------------------- /Notes/2020.2.5.md: -------------------------------------------------------------------------------- 1 | # 2020/2/5 2 | 3 | 1. 复习 databricks karat doc 1 - 17 4 | 5 | 2. 复习 databricks leetcode 题库 6 | -------------------------------------------------------------------------------- /Notes/2020.2.6.md: -------------------------------------------------------------------------------- 1 | # 2020/2/6 2 | 3 | 1. 完成 Karat 面试 4 | 5 | 1181. Diameter of Binary Tree 6 | 全局存放 diameter 结果,每次返回单一边最大值 7 | 8 | 920. Meeting Rooms 9 | 排序加判断 10 | 11 | 838. Subarray Sum Equals K 12 | presum, x - y = k,先存 y 值,再找 k - x 值 13 | 14 | 595. Binary Tree Longest Consecutive Sequence 15 | 传 length 变量,临时长度为 length + 1,再将 length 传到下一层 16 | 17 | 547. Intersection of Two Arrays 18 | 记得两个数组都要先排序 19 | 20 | 451. Swap Nodes in Pairs 21 | 理清顺序即可 22 | 23 | 433. Number of Islands 24 | DFS 解法 25 | 26 | 1315. Summary Ranges 27 | 三指针 28 | -------------------------------------------------------------------------------- /Notes/2020.2.7.md: -------------------------------------------------------------------------------- 1 | # 2020/2/7 2 | 3 | 1281. Top K Frequent Elements 4 | 方法有三种: 5 | 1) 正常 Count + 排序 6 | 2) 正常 Count + heap 7 | 3) 正常 Count + quick select,这里要用 counts[values[(left + right) // 2]] 作为 pivot 8 | 9 | 1261. Longest Substring with At Least K Repeating Characters 10 | 以 counts[char] < k 分开,左右两边再去递归找 11 | 12 | 1235. Serialize and Deserialize BST 13 | 两种方法 14 | 1) DFS,分成 [left hand side, right hand side] 15 | 2) BFS,分成 [1, 2, 3, ....],要设置 index 从 1 到 len(order),每次 pop 一个 node 就 index + 1 16 | 17 | 363. Trapping Rain Water 18 | 19 | 137. Clone Graph 20 | 注意 corner case 21 | 22 | 107. Word Break 23 | dp 24 | 25 | 32. Minimum Window Substring 26 | 27 | 892. Alien Dictionary 28 | 拓扑排序 29 | 30 | 859. Max Stack 31 | popMax 的时候用一个 buffer 去装临时元素 32 | 33 | 582. Word Break II 34 | dfs + memo -------------------------------------------------------------------------------- /Notes/2020.2.8.md: -------------------------------------------------------------------------------- 1 | # 2020/2/8 2 | 3 | 90. k Sum II 4 | 简单的 dfs 5 | 6 | 127. Topological Sorting 7 | BFS ,DFS 两种方法 8 | -------------------------------------------------------------------------------- /Notes/2020.2.9.md: -------------------------------------------------------------------------------- 1 | # 2020/2/9 2 | 3 | 597. Subtree with Maximum Average 4 | DFS,递归结果返回 total, num 5 | 6 | 905. Nested List Weight Sum II 7 | 获取 BFS order,再从最后一层往前计算结果 8 | 9 | 1428. Keys and Rooms 10 | DFS 写法,用 set 去存是否已被访问过了 11 | 12 | 1162. Out of Boundary Paths 13 | DFS + memo, memo[(x, y, steps)] = paths,使用 DFS 在回溯的时候获取 paths 14 | 15 | 1220. Matchsticks to Square 16 | 计算 targets = [sum(nums) / 4] * 4,然后看是否能用完所有的火柴 17 | 18 | 376. Binary Tree Path Sum 19 | 这里要用 curt_sum 记录当前的结果,不能用 target - root.val 来递归,因为会出现重复,应在 not root.left and not root.right 的时候就终止 20 | 21 | 246. Binary Tree Path Sum II 22 | 复习 23 | 24 | 1020. All Paths From Source to Target 25 | 基础 DFS 26 | 27 | 1031. Is Graph Bipartite 28 | 二元着色,遍历所以节点去着色,如果 colors[i] == 0,尝试着色相反色,如果 colors[i] == colors[next] 则 return False 29 | 30 | 872. Kill Process 31 | 构图 + 遍历 32 | 33 | 1210. Increasing Subsequences 34 | 使用局部 visited,可以在区间中不会出现重复 35 | 36 | 650. Find Leaves of Binary Tree 37 | self.leaves = [[xxx], [yyyy]],leaves[i] 表示第 i 高度时候的叶子,注意高度是从 leaf -> root 38 | 39 | 596. Minimum Subtree 40 | 简单的 DFS 41 | 42 | 628. Maximum Subtree 43 | 和上一题反着来就行 44 | 45 | 881. Lonely Pixel II 46 | 对每一行进行扫描,获取该行的 col_counts 和 key,再看 key 的数量和每一列的 B 数量是否为 N 47 | -------------------------------------------------------------------------------- /Notes/2020.3.1.md: -------------------------------------------------------------------------------- 1 | # 2020/3/1 2 | 3 | 695. Max Area of Island 4 | 经典 BFS 5 | 6 | 253. Meeting Rooms II 7 | 扫描线 8 | 9 | 277. Find the Celebrity 10 | 11 | 24. Swap Nodes in Pairs 12 | 13 | 136. Single Number -------------------------------------------------------------------------------- /Notes/2020.3.12.md: -------------------------------------------------------------------------------- 1 | # 2020/3/12 2 | 3 | 347. Top K Frequent Elements 4 | 5 | 129. Sum Root to Leaf Numbers 6 | 7 | 688. Knight Probability in Chessboard 8 | 9 | 140. Word Break II -------------------------------------------------------------------------------- /Notes/2020.3.3.md: -------------------------------------------------------------------------------- 1 | # 2020/3/3 2 | 3 | 14. Longest Common Prefix 4 | dp 5 | 6 | 212. Word Search II 7 | Hash set + dfs 8 | 9 | 328. Odd Even Linked List 10 | 注意这里说的不是 value 的值 11 | 12 | 79. Word Search 13 | DFS + hash map 14 | 15 | 15. 3Sum 16 | -------------------------------------------------------------------------------- /Notes/2020.3.4.md: -------------------------------------------------------------------------------- 1 | # 2020/3/4 2 | 3 | 11. Container With Most Water 4 | 双指针 5 | 6 | 124. Binary Tree Maximum Path Sum 7 | 分治法 8 | 9 | 210. Course Schedule II 10 | 拓扑 11 | 12 | 78. Subsets 13 | 先排序后 DFS 14 | 15 | 235. Lowest Common Ancestor of a Binary Search Tree 16 | 简单的分治,判断两个节点是否在同一边或者在两边 17 | -------------------------------------------------------------------------------- /Notes/2020.3.5.md: -------------------------------------------------------------------------------- 1 | # 2020/3/5 2 | 3 | 242. Valid Anagram 4 | 5 | 287. Find the Duplicate Number 6 | 7 | 125. Valid Palindrome 8 | 9 | -------------------------------------------------------------------------------- /Notes/2020.3.6.md: -------------------------------------------------------------------------------- 1 | # 2020/3/6 2 | 3 | 165. Compare Version Numbers 4 | 从左到右对比 5 | 6 | 117. Populating Next Right Pointers in Each Node II 7 | 分层 BFS 8 | 9 | 160. Intersection of Two Linked Lists 10 | 11 | 179. Largest Number 12 | 两个 key 对比去排序 13 | 14 | 50. Pow(x, n) 15 | 递归解法 16 | -------------------------------------------------------------------------------- /Notes/2020.3.7.md: -------------------------------------------------------------------------------- 1 | # 2020/3/7 2 | 3 | 785. Is Graph Bipartite? 4 | 5 | 28. Implement strStr() 6 | 7 | 152. Maximum Product Subarray 8 | 9 | 186. Reverse Words in a String II 10 | 11 | 12 | -------------------------------------------------------------------------------- /Notes/2020.3.8.md: -------------------------------------------------------------------------------- 1 | # 2020/3/8 2 | 3 | 126. Word Ladder II 4 | 5 | 48. Rotate Image -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # leetcode-python 2 | Python solutions to coding questions in Leetcode 3 | -------------------------------------------------------------------------------- /problems/114. 二叉树展开为链表.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, val=0, left=None, right=None): 4 | self.val = val 5 | self.left = left 6 | self.right = right 7 | 8 | 9 | class Solution: 10 | def flatten(self, root: TreeNode) -> None: 11 | self.dfs(root) 12 | 13 | def dfs(self, root): 14 | if not root: 15 | return None 16 | 17 | left_max = self.dfs(root.left) 18 | right_max = self.dfs(root.right) 19 | 20 | if not left_max: 21 | return right_max or root 22 | 23 | left_max.right = root.right 24 | root.right = root.left 25 | root.left = None 26 | 27 | return right_max or left_max or root 28 | -------------------------------------------------------------------------------- /problems/199. Binary Tree Right Side View.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | from collections import deque 3 | from typing import List 4 | 5 | 6 | class TreeNode: 7 | def __init__(self, val=0, left=None, right=None): 8 | self.val = val 9 | self.left = left 10 | self.right = right 11 | 12 | 13 | class Solution: 14 | def rightSideView(self, root: TreeNode) -> List[int]: 15 | if root is None: 16 | return [] 17 | 18 | queue = deque([root]) 19 | right_side = [] 20 | 21 | while queue: 22 | level_length = len(queue) 23 | 24 | for i in range(level_length): 25 | node = queue.popleft() 26 | if i == level_length - 1: 27 | right_side.append(node.val) 28 | 29 | if node.left: 30 | queue.append(node.left) 31 | if node.right: 32 | queue.append(node.right) 33 | 34 | return right_side 35 | -------------------------------------------------------------------------------- /problems/200. Number of Islands(DFS).py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | DX = [1, 0, -1, 0] 3 | DY = [0, 1, 0, -1] 4 | 5 | def numIslands(self, grid) -> int: 6 | if not grid or not grid[0]: 7 | return 0 8 | 9 | islands = 0 10 | row, col = len(grid), len(grid[0]) 11 | 12 | for i in range(row): 13 | for j in range(col): 14 | if grid[i][j] == '1': 15 | self.dfs(grid, i, j, row, col) 16 | islands += 1 17 | 18 | return islands 19 | 20 | def dfs(self, grid, i, j, row, col): 21 | if not (0 <= i < row and 0 <= j < col and grid[i][j] == '1'): 22 | return 23 | 24 | grid[i][j] = '0' 25 | 26 | for delta in range(4): 27 | next_x, next_y = i + self.DX[delta], j + self.DY[delta] 28 | self.dfs(grid, next_x, next_y, row, col) 29 | -------------------------------------------------------------------------------- /problems/200. Number of Islands.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class Solution: 5 | DX = [1, 0, -1, 0] 6 | DY = [0, 1, 0, -1] 7 | 8 | def numIslands(self, grid) -> int: 9 | if not grid or not grid[0]: 10 | return 0 11 | 12 | count = 0 13 | 14 | for i in range(len(grid)): 15 | for j in range(len(grid[i])): 16 | if grid[i][j] == '1': 17 | self.bfs(grid, i, j) 18 | count += 1 19 | 20 | return count 21 | 22 | def bfs(self, grid, i, j): 23 | queue = deque([(i, j)]) 24 | grid[i][j] = '0' 25 | 26 | while queue: 27 | x, y = queue.popleft() 28 | 29 | for delta in range(4): 30 | next_x, next_y = x + self.DX[delta], y + self.DY[delta] 31 | 32 | if not self.isValid(grid, next_x, next_y): 33 | continue 34 | 35 | queue.append((next_x, next_y)) 36 | grid[next_x][next_y] = '0' 37 | 38 | def isValid(self, grid, x, y): 39 | return 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] == '1' 40 | -------------------------------------------------------------------------------- /problems/26. 删除排序数组中的重复项.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeDuplicates(self, nums) -> int: 3 | if not nums: 4 | return 0 5 | 6 | i, j = 0, 1 7 | while j < len(nums): 8 | if nums[i] != nums[j]: 9 | i += 1 10 | nums[i] = nums[j] 11 | j += 1 12 | 13 | return i + 1 14 | -------------------------------------------------------------------------------- /problems/27. 移除元素-2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def removeElement(self, nums: List[int], val: int) -> int: 6 | if not nums: 7 | return 0 8 | 9 | i, n = 0, len(nums) 10 | while i < n: 11 | if nums[i] == val: 12 | nums[i] = nums[n - 1] 13 | n -= 1 14 | else: 15 | i += 1 16 | 17 | return n 18 | -------------------------------------------------------------------------------- /problems/27. 移除元素.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def removeElement(self, nums: List[int], val: int) -> int: 6 | if not nums: 7 | return 0 8 | 9 | i = 0 10 | for j in range(len(nums)): 11 | if nums[j] != val: 12 | nums[i] = nums[j] 13 | i += 1 14 | 15 | return i 16 | -------------------------------------------------------------------------------- /problems/35. 搜索插入位置.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def searchInsert(self, nums: List[int], target: int) -> int: 6 | left, right = 0, len(nums) - 1 7 | 8 | while left + 1 < right: 9 | mid = (left + right) // 2 10 | 11 | if nums[mid] < target: 12 | left = mid 13 | elif nums[mid] > target: 14 | right = mid 15 | else: 16 | return mid 17 | 18 | if target > nums[right]: 19 | return right + 1 20 | if target == nums[right]: 21 | return right 22 | if target > nums[left]: 23 | return left + 1 24 | 25 | return left -------------------------------------------------------------------------------- /problems/415. 字符串相加.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addStrings(self, num1: str, num2: str) -> str: 3 | i, j, carry, ans = len(num1) - 1, len(num2) - 1, 0, "" 4 | 5 | while i >= 0 or j >= 0 or carry: 6 | val = carry 7 | 8 | if i >= 0: 9 | i, val = i - 1, val + int(num1[i]) 10 | if j >= 0: 11 | j, val = j - 1, val + int(num2[j]) 12 | 13 | carry, val = divmod(val, 10) 14 | ans = str(val) + ans 15 | 16 | return ans 17 | -------------------------------------------------------------------------------- /problems/6. ZigZag Conversion.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def convert(self, s: str, numRows: int) -> str: 3 | if not s or numRows == 1: 4 | return s 5 | 6 | rows = [] 7 | for i in range(min(numRows, len(s))): 8 | rows.append('') 9 | 10 | curRow, goingDown = 0, False 11 | for char in s: 12 | rows[curRow] += char 13 | 14 | if curRow == 0 or curRow == numRows - 1: 15 | goingDown = not goingDown 16 | 17 | curRow += 1 if goingDown else -1 18 | 19 | charList = [] 20 | for row in rows: 21 | charList += row 22 | 23 | return ''.join(charList) 24 | -------------------------------------------------------------------------------- /problems/9. Palindrome Number.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self, x: int) -> bool: 3 | if x < 0: 4 | return False 5 | 6 | input_num = x 7 | reverted_num = 0 8 | while x > 0: 9 | remainder = x % 10 10 | 11 | reverted_num = reverted_num * 10 + remainder 12 | 13 | x = x // 10 14 | 15 | return reverted_num == input_num 16 | -------------------------------------------------------------------------------- /problems/剑指 Offer 10- I. 斐波那契数列.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def fib(self, n: int) -> int: 3 | a, b = 0, 1 4 | for _ in range(n): 5 | a, b = b, a + b 6 | 7 | return a % 1000000007 8 | --------------------------------------------------------------------------------