├── .gitignore ├── LICENSE ├── README.md ├── bonus_top_interview_questions ├── 103. Binary Tree Zigzag Level Order Traversal.py ├── 108. Convert Sorted Array to Binary Search Tree.py ├── 116. Populating Next Right Pointers in Each Node.py ├── 118. Pascal's Triangle.py ├── 122. Best Time to Buy and Sell Stock II.py ├── 125. Valid Palindrome.py ├── 13. Roman to Integer.py ├── 130. Surrounded Regions.py ├── 134. Gas Station.py ├── 14. Longest Common Prefix.py ├── 140. Word Break II.py ├── 149. Max Points on a Line.py ├── 150. Evaluate Reverse Polish Notation.py ├── 162. Find Peak Element.py ├── 166. Fraction to Recurring Decimal.py ├── 171. Excel Sheet Column Number.py ├── 172. Factorial Trailing Zeroes.py ├── 179. Largest Number.py ├── 190. Reverse Bits.py ├── 191. Number of 1 Bits.py ├── 202. Happy Number.py ├── 204. Count Primes.py ├── 212. Word Search II.py ├── 217. Contains Duplicate.py ├── 218. The Skyline Problem.py ├── 227. Basic Calculator II.py ├── 237. Delete Node in a Linked List.py ├── 242. Valid Anagram.py ├── 26. Remove Duplicates from Sorted Array.py ├── 268. Missing Number.py ├── 28. Implement strStr().py ├── 289. Game of Life.py ├── 29. Divide Two Integers.py ├── 315. Count of Smaller Numbers After Self.py ├── 324. Wiggle Sort II.py ├── 326. Power of Three.py ├── 328. Odd Even Linked List.py ├── 329. Longest Increasing Path in a Matrix.py ├── 334. Increasing Triplet Subsequence.py ├── 341. Flatten Nested List Iterator.py ├── 350. Intersection of Two Arrays II.py ├── 36. Valid Sudoku.py ├── 371. Sum of Two Integers.py ├── 378. Kth Smallest Element in a Sorted Matrix.py ├── 38. Count and Say.py ├── 380. Insert Delete GetRandom O(1).py ├── 384. Shuffle an Array.py ├── 387. First Unique Character in a String.py ├── 395. Longest Substring with At Least K Repeating Characters.py ├── 412. Fizz Buzz.py ├── 44. Wildcard Matching.py ├── 454. 4Sum II.py ├── 50. Pow(x, n).py ├── 54. Spiral Matrix.py ├── 66. Plus One.py ├── 69. Sqrt(x).py ├── 7. Reverse Integer.py ├── 73. Set Matrix Zeroes.py ├── 8. String to Integer (atoi).py ├── 88. Merge Sorted Array.py └── 91. Decode Ways.py ├── foobar.py ├── irl.py └── solutions ├── 1. Two Sum.py ├── 10. Regular Expression Matching.py ├── 101. Symmetric Tree.py ├── 102. Binary Tree Level Order Traversal.py ├── 104. Maximum Depth of Binary Tree.py ├── 105. Construct Binary Tree from Preorder and Inorder Traversal.py ├── 11. Container With Most Water.py ├── 114. Flatten Binary Tree to Linked List.py ├── 121. Best Time to Buy and Sell Stock.py ├── 124. Binary Tree Maximum Path Sum.py ├── 127. Word Ladder.py ├── 128. Longest Consecutive Sequence.py ├── 131. Palindrome Partitioning.py ├── 136. Single Number.py ├── 138. Copy List with Random Pointer.py ├── 139. Word Break.py ├── 141. Linked List Cycle.py ├── 142. Linked List Cycle II.py ├── 146. LRU Cache.py ├── 148. Sort List.py ├── 15. 3Sum.py ├── 152. Maximum Product Subarray.py ├── 153. Find Minimum in Rotated Sorted Array.py ├── 155. Min Stack.py ├── 160. Intersection of Two Linked Lists.py ├── 169. Majority Element.py ├── 17. Letter Combinations of a Phone Number.py ├── 189. Rotate Array.py ├── 19. Remove Nth Node From End of List.py ├── 198. House Robber.py ├── 199. Binary Tree Right Side View.py ├── 2. Add Two Numbers.py ├── 20. Valid Parentheses.py ├── 200. Number of Islands.py ├── 206. Reverse Linked List.py ├── 207. Course Schedule.py ├── 208. Implement Trie (Prefix Tree).py ├── 21. Merge Two Sorted Lists.py ├── 210. Course Schedule II.py ├── 215. Kth Largest Element in an Array.py ├── 22. Generate Parentheses.py ├── 221. Maximal Square.py ├── 226. Invert Binary Tree.py ├── 23. Merge k Sorted Lists.py ├── 230. Kth Smallest Element in a BST.py ├── 234. Palindrome Linked List.py ├── 236. Lowest Common Ancestor of a Binary Tree.py ├── 238. Product of Array Except Self.py ├── 239. Sliding Window Maximum.py ├── 24. Swap Nodes in Pairs.py ├── 240. Search a 2D Matrix II.py ├── 25. Reverse Nodes in k-Group.py ├── 279. Perfect Squares.py ├── 283. Move Zeroes.py ├── 287. Find the Duplicate Number.py ├── 295. Find Median from Data Stream.py ├── 297. Serialize and Deserialize Binary Tree.py ├── 3. Longest Substring Without Repeating Characters.py ├── 300. Longest Increasing Subsequence.py ├── 31. Next Permutation.py ├── 32. Longest Valid Parentheses.py ├── 322. Coin Change.py ├── 33. Search in Rotated Sorted Array.py ├── 338. Counting Bits.py ├── 34. Find First and Last Position of Element in Sorted Array.py ├── 347. Top K Frequent Elements.py ├── 35. Search Insert Position.py ├── 39. Combination Sum.py ├── 394. Decode String.py ├── 4. Median of Two Sorted Arrays.py ├── 41. First Missing Positive.py ├── 416. Partition Equal Subset Sum.py ├── 42. Trapping Rain Water.py ├── 437. Path Sum III.py ├── 438. Find All Anagrams in a String.py ├── 448. Find All Numbers Disappeared in an Array.py ├── 45. Jump Game II.py ├── 46. Permutations.py ├── 48. Rotate Image.py ├── 49. Group Anagrams.py ├── 494. Target Sum.py ├── 5. Longest Palindromic Substring.py ├── 53. Maximum Subarray.py ├── 543. Diameter of Binary Tree.py ├── 55. Jump Game.py ├── 56. Merge Intervals.py ├── 560. Subarray Sum Equals K.py ├── 617. Merge Two Binary Trees.py ├── 62. Unique Paths.py ├── 64. Minimum Path Sum.py ├── 647. Palindromic Substrings.py ├── 70. Climbing Stairs.py ├── 72. Edit Distance.py ├── 739. Daily Temperatures.py ├── 74. Search a 2D Matrix.py ├── 75. Sort Colors.py ├── 76. Minimum Window Substring.py ├── 763. Partition Labels.py ├── 78. Subsets.py ├── 79. Word Search.py ├── 84. Largest Rectangle in Histogram.py ├── 85. Maximal Rectangle.py ├── 94. Binary Tree Inorder Traversal.py ├── 96. Unique Binary Search Trees.py └── 98. Validate Binary Search Tree.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jacopo Panerati 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/103. Binary Tree Zigzag Level Order Traversal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 20 ms, faster than 99.96% of Python3 online submissions for Binary Tree Zigzag Level Order Traversal. 3 | Memory Usage: 14.1 MB, less than 60.82% of Python3 online submissions for Binary Tree Zigzag Level Order Traversal. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: 16 | if root is None: 17 | return [] 18 | level_list = [root] 19 | level_depth = 0 20 | ans = [] 21 | while len(level_list) > 0: 22 | this_level_ints = [] 23 | next_level_list = [] 24 | for n in level_list: 25 | this_level_ints.append(n.val) 26 | if n.left is not None: 27 | next_level_list.append(n.left) 28 | if n.right is not None: 29 | next_level_list.append(n.right) 30 | if level_depth%2==0: 31 | ans.append(this_level_ints) 32 | else: 33 | ans.append(this_level_ints[::-1]) 34 | level_depth += 1 35 | level_list = next_level_list 36 | return ans 37 | 38 | def main(): 39 | sol = Solution() 40 | root = TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7))) 41 | print('Output:', sol.zigzagLevelOrder(root)) 42 | print('Expected:', [[3],[20,9],[15,7]]) 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/108. Convert Sorted Array to Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 115 ms, faster than 58.29% of Python3 online submissions for Convert Sorted Array to Binary Search Tree. 3 | Memory Usage: 15.8 MB, less than 6.22% of Python3 online submissions for Convert Sorted Array to Binary Search Tree. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: 16 | if len(nums)==0: 17 | return None 18 | elif len(nums)==1: 19 | return TreeNode(nums[0]) 20 | elif len(nums)==2: 21 | return TreeNode(nums[1],TreeNode(nums[0])) 22 | elif len(nums)==3: 23 | return TreeNode(nums[1],TreeNode(nums[0]),TreeNode(nums[2])) 24 | else: 25 | return TreeNode(nums[len(nums)//2], 26 | self.sortedArrayToBST(nums[:len(nums)//2]), 27 | self.sortedArrayToBST(nums[len(nums)//2+1:]) 28 | ) 29 | 30 | ans_list = [] 31 | 32 | def tree_print(root): 33 | if root is not None: 34 | ans_list.append(root.val) 35 | tree_print(root.left) 36 | tree_print(root.right) 37 | 38 | def main(): 39 | sol = Solution() 40 | ans = sol.sortedArrayToBST([-10,-3,0,5,9]) 41 | tree_print(ans) 42 | print('Output:', ans_list) 43 | print('Expected:', [0,-3,9,-10,5]) 44 | 45 | if __name__ == "__main__": 46 | main() 47 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/116. Populating Next Right Pointers in Each Node.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 76 ms, faster than 69.96% of Python3 online submissions for Populating Next Right Pointers in Each Node. 3 | Memory Usage: 15.7 MB, less than 49.50% of Python3 online submissions for Populating Next Right Pointers in Each Node. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Node: 9 | def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | self.next = next 14 | 15 | class Solution: 16 | def connect(self, root: 'Optional[Node]') -> 'Optional[Node]': 17 | if root is None: 18 | return None 19 | level_list = [root] 20 | while len(level_list) > 0: 21 | next_level_list = [] 22 | for n in level_list: 23 | if n.left is not None: 24 | next_level_list.append(n.left) 25 | if n.right is not None: 26 | next_level_list.append(n.right) 27 | for idx, n in enumerate(next_level_list[0:len(next_level_list)-1]): 28 | n.next = next_level_list[idx+1] 29 | level_list = next_level_list 30 | return root 31 | 32 | ans_list = [] 33 | 34 | def tree_print(root): 35 | if root is not None: 36 | ptr = root 37 | temp = [] 38 | while ptr is not None: 39 | temp.append(ptr.val) 40 | ptr = ptr.next 41 | ans_list.append(temp) 42 | tree_print(root.left) 43 | 44 | def main(): 45 | sol = Solution() 46 | inp = Node(1, Node(2, Node(4), Node(5)), Node(3, Node(6), Node(7))) 47 | ans = sol.connect(inp) 48 | tree_print(ans) 49 | print('Output:', ans_list) 50 | print('Expected:', [[1], [2,3], [4,5,6,7]]) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/118. Pascal's Triangle.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 39 ms, faster than 64.54% of Python3 online submissions for Pascal's Triangle. 3 | Memory Usage: 14 MB, less than 30.15% of Python3 online submissions for Pascal's Triangle. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def generate(self, numRows: int) -> List[List[int]]: 10 | ans = [] 11 | for r in range(numRows): 12 | ans.append([]) 13 | if r==0: 14 | ans[r].append(1) 15 | elif r==1: 16 | ans[r].append(1) 17 | ans[r].append(1) 18 | else: 19 | for i in range(r+1): 20 | if i==0 or i==r: 21 | ans[r].append(1) 22 | else: 23 | ans[r].append(ans[r-1][i-1]+ans[r-1][i]) 24 | return ans 25 | 26 | def main(): 27 | sol = Solution() 28 | print('Output:', sol.generate(5)) 29 | print('Expected:', [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/122. Best Time to Buy and Sell Stock II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 102 ms, faster than 33.65% of Python3 online submissions for Best Time to Buy and Sell Stock II. 3 | Memory Usage: 15.2 MB, less than 67.52% of Python3 online submissions for Best Time to Buy and Sell Stock II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maxProfit(self, prices: List[int]) -> int: 10 | profits = 0 11 | for idx in range(1,len(prices)): 12 | if prices[idx] > prices[idx-1]: 13 | profits += prices[idx]-prices[idx-1] 14 | return profits 15 | 16 | def main(): 17 | sol = Solution() 18 | print('Output:', sol.maxProfit([7,1,5,3,6,4])) 19 | print('Expected:', 7) 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/125. Valid Palindrome.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 107 ms, faster than 11.33% of Python3 online submissions for Valid Palindrome. 3 | Memory Usage: 15.5 MB, less than 24.06% of Python3 online submissions for Valid Palindrome. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def isPalindrome(self, s: str) -> bool: 10 | stripped_down_s = [] 11 | low = ['a'] 12 | for c in s: 13 | if c.isdigit(): 14 | stripped_down_s.append(c) 15 | elif c.isalpha(): 16 | if c.isupper(): 17 | stripped_down_s.append(c.lower()) 18 | elif c.islower(): 19 | stripped_down_s.append(c) 20 | length = len(stripped_down_s) 21 | if length <= 1: 22 | return True 23 | for i in range(length//2): 24 | if stripped_down_s[i] != stripped_down_s[length-1-i]: 25 | return False 26 | return True 27 | 28 | def main(): 29 | sol = Solution() 30 | print('Output:', sol.isPalindrome("A man, a plan, a canal: Panama")) 31 | print('Expected:', True) 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/13. Roman to Integer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 64 ms, faster than 59.87% of Python3 online submissions for Roman to Integer. 3 | Memory Usage: 13.9 MB, less than 82.92% of Python3 online submissions for Roman to Integer. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def romanToInt(self, s: str) -> int: 10 | mapping = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} 11 | new_s = [] 12 | for digit in s: 13 | new_s.append(mapping[digit]) 14 | print(new_s) 15 | ans = 0 16 | temp = 0 17 | for idx, val in enumerate(new_s): 18 | if idx == 0: 19 | temp = val 20 | continue 21 | if val == new_s[idx-1]: 22 | temp += val 23 | else: 24 | if val > new_s[idx-1]: 25 | ans -= temp 26 | temp = val 27 | else: 28 | ans += temp 29 | temp = val 30 | ans += temp 31 | return ans 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.romanToInt("III")) 36 | print('Expected:', 3) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/130. Surrounded Regions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 153 ms, faster than 80.27% of Python3 online submissions for Surrounded Regions. 3 | Memory Usage: 15.2 MB, less than 87.41% of Python3 online submissions for Surrounded Regions. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def solve(self, board: List[List[str]]) -> None: 10 | """ 11 | Do not return anything, modify board in-place instead. 12 | """ 13 | rows = len(board) 14 | cols = len(board[0]) 15 | save = [] 16 | for k in range(rows): 17 | save += (k, 0), (k, cols-1) 18 | for k in range(cols): 19 | save += (0, k), (rows-1, k) 20 | while len(save) > 0: 21 | i, j = save.pop() 22 | if (0 <= i < rows) and (0 <= j < cols) and (board[i][j] == 'O'): 23 | board[i][j] = 'S' 24 | save += (i, j-1), (i, j+1), (i-1, j), (i+1, j) 25 | for r in range(rows): 26 | for c in range(cols): 27 | if board[r][c] == 'S': 28 | board[r][c] = 'O' 29 | else: 30 | board[r][c] = 'X' 31 | 32 | def main(): 33 | sol = Solution() 34 | inp = [["O","X","X","O","X"],["X","O","O","X","O"],["X","O","X","O","X"],["O","X","O","O","O"],["X","X","O","X","O"]] 35 | sol.solve(inp) 36 | print('Output:', inp) 37 | print('Expected:', [["O","X","X","O","X"],["X","X","X","X","O"],["X","X","X","O","X"],["O","X","O","O","O"],["X","X","O","X","O"]]) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/134. Gas Station.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 716 ms, faster than 86.07% of Python3 online submissions for Gas Station. 3 | Memory Usage: 19.2 MB, less than 71.74% of Python3 online submissions for Gas Station. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: 11 | n = len(gas) 12 | total_surplus = 0 13 | surplus = 0 14 | start = 0 15 | for i in range(n): 16 | total_surplus += gas[i] - cost[i] 17 | surplus += gas[i] - cost[i] 18 | if surplus < 0: 19 | surplus = 0 20 | start = i + 1 21 | if total_surplus < 0: 22 | return -1 23 | else: 24 | return start 25 | 26 | def main(): 27 | sol = Solution() 28 | print('Output:', sol.canCompleteCircuit([1,2,3,4,5], [3,4,5,1,2])) 29 | print('Expected:', 3) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/14. Longest Common Prefix.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 40 ms, faster than 76.15% of Python3 online submissions for Longest Common Prefix. 3 | Memory Usage: 14.1 MB, less than 23.58% of Python3 online submissions for Longest Common Prefix. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def longestCommonPrefix(self, strs: List[str]) -> str: 10 | if len(strs) == 0: 11 | return '' 12 | if len(strs) == 1: 13 | return strs[0] 14 | for s in strs: 15 | if len(s) == 0: 16 | return '' 17 | idx = 0 18 | while True: 19 | for i, s in enumerate(strs): 20 | if idx > len(s)-1: 21 | return s 22 | if i==0: 23 | char = strs[i][idx] 24 | continue 25 | if s[idx] != char: 26 | return s[:idx] 27 | idx += 1 28 | 29 | def main(): 30 | sol = Solution() 31 | print('Output:', sol.longestCommonPrefix(["flower","flow","flight"])) 32 | print('Expected:', 'fl') 33 | 34 | if __name__ == "__main__": 35 | main() 36 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/140. Word Break II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 87.26% of Python3 online submissions for Word Break II. 3 | Memory Usage: 13.9 MB, less than 83.97% of Python3 online submissions for Word Break II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.cache = {} 11 | 12 | def wordBreak(self, s: str, wordDict: List[str]) -> List[str]: 13 | if s in self.cache.keys(): 14 | return self.cache[s] 15 | if len(s)==0: 16 | return [] 17 | ans = [] 18 | for word in wordDict: 19 | if not s.startswith(word): 20 | continue 21 | if len(word) == len(s): 22 | ans.append(word) 23 | else: 24 | all_possible_splits = self.wordBreak(s[len(word):], wordDict) 25 | for elem in all_possible_splits: 26 | elem = word + ' ' + elem 27 | ans.append(elem) 28 | self.cache[s] = ans 29 | return ans 30 | 31 | def main(): 32 | sol = Solution() 33 | print('Output:', sol.wordBreak("catsanddog", ["cat","cats","and","sand","dog"])) 34 | print('Expected:', ["cats and dog","cat sand dog"]) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/149. Max Points on a Line.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 440 ms, faster than 8.17% of Python3 online submissions for Max Points on a Line. 3 | Memory Usage: 14.9 MB, less than 28.30% of Python3 online submissions for Max Points on a Line. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maxPoints(self, points: List[List[int]]) -> int: 10 | if len(points)<3: 11 | return len(points) 12 | cache = {} 13 | for i in range(len(points)): 14 | for j in range(i+1, len(points)): 15 | one = points[i] 16 | two = points[j] 17 | a = one[1] - two[1] 18 | b = two[0] - one[0] 19 | c = one[0]*two[1] - two[0]*one[1] 20 | g = self.gcd(self.gcd(a, b), c) 21 | a /= g 22 | b /= g 23 | c /= g 24 | if (a,b,c) not in cache.keys(): 25 | cache[(a,b,c)] = 0 26 | ans = -1 27 | for i in range(len(points)): 28 | for k, v in cache.items(): 29 | if (k[0]*points[i][0]+k[1]*points[i][1]+k[2]) == 0.0: 30 | cache[k] += 1 31 | ans = max(ans, cache[k]) 32 | return ans 33 | 34 | def gcd(self, x, y): 35 | while y != 0: 36 | (x, y) = (y, x % y) 37 | return x 38 | 39 | def main(): 40 | sol = Solution() 41 | print('Output:', sol.maxPoints([[-6,-1],[3,1],[12,3]])) 42 | print('Expected:', 3) 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/150. Evaluate Reverse Polish Notation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 3730 ms, faster than 5.04% of Python3 online submissions for Evaluate Reverse Polish Notation. 3 | Memory Usage: 14.4 MB, less than 19.92% of Python3 online submissions for Evaluate Reverse Polish Notation. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def evalRPN(self, tokens: List[str]) -> int: 11 | active = tokens 12 | while len(active) > 1: 13 | for idx, t in enumerate(active): 14 | if t == '+': 15 | res = int(active[idx-2]) + int(active[idx-1]) 16 | active = active[:idx-2] + [res] + active[idx+1:] 17 | break 18 | if t == '-': 19 | res = int(active[idx-2]) - int(active[idx-1]) 20 | active = active[:idx-2] + [res] + active[idx+1:] 21 | break 22 | if t == '*': 23 | res = int(active[idx-2]) * int(active[idx-1]) 24 | active = active[:idx-2] + [res] + active[idx+1:] 25 | break 26 | if t == '/': 27 | res = int(int(active[idx-2]) / int(active[idx-1])) 28 | active = active[:idx-2] + [res] + active[idx+1:] 29 | break 30 | return active[0] 31 | 32 | def main(): 33 | sol = Solution() 34 | print('Output:', sol.evalRPN(["2","1","+","3","*"])) 35 | print('Expected:', 9) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/162. Find Peak Element.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 52 ms, faster than 77.08% of Python3 online submissions for Find Peak Element. 3 | Memory Usage: 14 MB, less than 86.09% of Python3 online submissions for Find Peak Element. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findPeakElement(self, nums: List[int]) -> int: 10 | if len(nums) <= 1: 11 | return 0 12 | if nums[0] > nums[1]: 13 | return 0 14 | if nums[len(nums)-1] > nums[len(nums)-2]: 15 | return len(nums)-1 16 | skip = [False] * len(nums) 17 | for idx in range(1,len(nums)-1): 18 | if skip[idx]: 19 | continue 20 | if nums[idx] > nums[idx-1] and nums[idx] > nums[idx+1]: 21 | return idx 22 | if nums[idx-1] > nums[idx] and nums[idx] > nums[idx+1]: 23 | skip[idx+1] = True 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.findPeakElement([1,2,3,1])) 28 | print('Expected:', 2) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/166. Fraction to Recurring Decimal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 41 ms, faster than 60.54% of Python3 online submissions for Fraction to Recurring Decimal. 3 | Memory Usage: 14 MB, less than 77.00% of Python3 online submissions for Fraction to Recurring Decimal. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def fractionToDecimal(self, numerator: int, denominator: int) -> str: 10 | if numerator == 0: 11 | return '0' 12 | ans = '' 13 | if (numerator < 0 and denominator > 0) or (numerator > 0 and denominator < 0): 14 | ans += '-' 15 | if numerator < 0: 16 | numerator = -numerator 17 | if denominator < 0: 18 | denominator = -denominator 19 | resto = numerator 20 | history = [] 21 | period = True 22 | while resto > 0: 23 | if resto < denominator: 24 | ans += '0' 25 | if period: 26 | ans += '.' 27 | period = False 28 | resto *= 10 29 | else: 30 | ans += str(resto // denominator) 31 | resto = resto%denominator 32 | if resto < denominator and resto != 0: 33 | if period: 34 | ans += '.' 35 | period = False 36 | resto *= 10 37 | if resto in history: 38 | for idx in range(len(history)): 39 | if history[idx] == resto: 40 | i = len(history) - idx 41 | ans = ans[:len(ans)-i] +'(' + ans[len(ans)-i:] + ')' 42 | break 43 | history.append(resto) 44 | return ans 45 | 46 | def main(): 47 | sol = Solution() 48 | print('Output:', sol.fractionToDecimal(22, 7)) 49 | print('Expected:', "3.(142857)") 50 | 51 | if __name__ == "__main__": 52 | main() 53 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/171. Excel Sheet Column Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 28 ms, faster than 97.72% of Python3 online submissions for Excel Sheet Column Number. 3 | Memory Usage: 13.9 MB, less than 15.03% of Python3 online submissions for Excel Sheet Column Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def titleToNumber(self, columnTitle: str) -> int: 10 | characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 11 | d = {} 12 | for x in range(len(characters)): 13 | d[characters[x]] = x+1 14 | ans = 0 15 | for c in columnTitle: 16 | ans = 26*ans + d[c] 17 | return ans 18 | 19 | def main(): 20 | sol = Solution() 21 | print('Output:', sol.titleToNumber("AB")) 22 | print('Expected:', 28) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/172. Factorial Trailing Zeroes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 108 ms, faster than 33.37% of Python3 online submissions for Factorial Trailing Zeroes. 3 | Memory Usage: 14.2 MB, less than 6.93% of Python3 online submissions for Factorial Trailing Zeroes. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def trailingZeroes(self, n: int) -> int: 10 | if n == 0: 11 | return 0 12 | else: 13 | return int(n/5 + self.trailingZeroes(n/5)) 14 | 15 | def main(): 16 | sol = Solution() 17 | print('Output:', sol.trailingZeroes(12)) 18 | print('Expected:', 2) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/179. Largest Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 69 ms, faster than 36.79% of Python3 online submissions for Largest Number. 3 | Memory Usage: 13.9 MB, less than 24.02% of Python3 online submissions for Largest Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import functools 8 | 9 | class Solution: 10 | def largestNumber(self, nums: List[int]) -> str: 11 | temp = [] 12 | for n in nums: 13 | temp.append(str(n)) 14 | def cmp(b, a): 15 | return ((a+b)>(b+a))-((a+b)<(b+a)) 16 | temp.sort(key = functools.cmp_to_key(cmp)) 17 | ans = '' 18 | for n in temp: 19 | ans += n 20 | if ans.startswith('00'): 21 | return '0' 22 | else: 23 | return ans 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.largestNumber([3,30,34,5,9])) 28 | print('Expected:', "9534330") 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/190. Reverse Bits.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 57 ms, faster than 25.80% of Python3 online submissions for Reverse Bits. 3 | Memory Usage: 13.9 MB, less than 58.76% of Python3 online submissions for Reverse Bits. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def reverseBits(self, n: int) -> int: 10 | binary = [0] * 32 11 | write_idx = 31 12 | while n > 0: 13 | binary[write_idx] = n%2 14 | n = n//2 15 | write_idx -= 1 16 | ans = 0 17 | for read_idx in range(31,-1,-1): 18 | ans = 2*ans + binary[read_idx] 19 | return ans 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:', sol.reverseBits(43261596)) 24 | print('Expected:', 964176192) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/191. Number of 1 Bits.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 89.11% of Python3 online submissions for Number of 1 Bits. 3 | Memory Usage: 13.8 MB, less than 57.30% of Python3 online submissions for Number of 1 Bits. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def hammingWeight(self, n: int) -> int: 10 | ans = 0 11 | while n > 0: 12 | ans += n%2 13 | n = n//2 14 | return ans 15 | 16 | def main(): 17 | sol = Solution() 18 | print('Output:', sol.hammingWeight(11)) 19 | print('Expected:', 3) 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/202. Happy Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 49 ms, faster than 52.60% of Python3 online submissions for Happy Number. 3 | Memory Usage: 13.9 MB, less than 23.80% of Python3 online submissions for Happy Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def isHappy(self, n: int) -> bool: 10 | history = [] 11 | while True: 12 | string = str(n) 13 | squares_sum = 0 14 | for digit in string: 15 | squares_sum += int(digit)*int(digit) 16 | n = squares_sum 17 | if n == 1: 18 | return True 19 | if n in history: 20 | return False 21 | history.append(n) 22 | 23 | def main(): 24 | sol = Solution() 25 | print('Output:', sol.isHappy(19)) 26 | print('Expected:', True) 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/204. Count Primes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 5834 ms, faster than 34.56% of Python3 online submissions for Count Primes. 3 | Memory Usage: 52.7 MB, less than 85.70% of Python3 online submissions for Count Primes. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def countPrimes(self, n: int) -> int: 11 | if n <= 2: 12 | return 0 13 | primes = [True] * n 14 | primes[0] = False 15 | primes[1] = False 16 | for i in range(2, int(math.sqrt(n)) + 1): 17 | if primes[i]: 18 | multiple = i**2 19 | while multiple < n: 20 | primes[multiple] = False 21 | multiple += i 22 | return sum(primes) 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.countPrimes(10)) 27 | print('Expected:', 4) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/212. Word Search II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1650 ms, faster than 62.61% of Python3 online submissions for Word Search II. 3 | Memory Usage: 15.6 MB, less than 70.61% of Python3 online submissions for Word Search II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findWords(self, board: List[List[str]], words: List[str]) -> List[str]: 10 | trie={} 11 | for word in words: 12 | temp=trie 13 | for character in word: 14 | if character not in temp: 15 | temp[character]={} 16 | temp=temp[character] 17 | temp['#']='#' 18 | self.res=[] 19 | self.rows = len(board) 20 | self.cols = len(board[0]) 21 | for i in range(self.rows): 22 | for j in range(self.cols): 23 | self.find(board,i,j,trie,[]) 24 | return self.res 25 | 26 | def find(self,board,i,j,trie,pre): 27 | if '#' in trie: 28 | del trie["#"] 29 | self.res.append(''.join(pre)) 30 | if i<0 or i>=self.rows or j<0 or j>=self.cols: 31 | return 32 | if board[i][j] in trie: 33 | save_char = board[i][j] 34 | board[i][j] = '$' 35 | pre.append(save_char) 36 | self.find(board,i+1,j,trie[save_char],pre) 37 | self.find(board,i,j+1,trie[save_char],pre) 38 | self.find(board,i-1,j,trie[save_char],pre) 39 | self.find(board,i,j-1,trie[save_char],pre) 40 | board[i][j] = save_char 41 | pre.pop() 42 | if not trie[board[i][j]]: 43 | del trie[board[i][j]] 44 | 45 | def main(): 46 | sol = Solution() 47 | print('Output:', sol.findWords([["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], ["oath","pea","eat","rain"])) 48 | print('Expected:', ["oath","eat"]) 49 | 50 | if __name__ == "__main__": 51 | main() 52 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/217. Contains Duplicate.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 584 ms, faster than 53.62% of Python3 online submissions for Contains Duplicate. 3 | Memory Usage: 25.8 MB, less than 95.96% of Python3 online submissions for Contains Duplicate. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def containsDuplicate(self, nums: List[int]) -> bool: 10 | cache = {} 11 | for n in nums: 12 | if n in cache.keys(): 13 | return True 14 | cache[n] = 1 15 | return False 16 | 17 | def main(): 18 | sol = Solution() 19 | print('Output:', sol.containsDuplicate([1,2,3,1])) 20 | print('Expected:', Truep) 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/218. The Skyline Problem.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 104 ms, faster than 99.68% of Python3 online submissions for The Skyline Problem. 3 | Memory Usage: 20.1 MB, less than 38.81% of Python3 online submissions for The Skyline Problem. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from heapq import heappush, heappop 8 | import math 9 | 10 | class Solution: 11 | def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]: 12 | events = [(L, -H, R) for L, R, H in buildings] + [(R, 0, 0) for _, R, _ in buildings] 13 | events.sort() 14 | res = [[0, 0]] 15 | live = [(0, math.inf)] 16 | for pos, negH, R in events: 17 | while live[0][1] <= pos: 18 | heappop(live) 19 | if negH != 0: 20 | heappush(live, (negH, R)) 21 | if res[-1][1] != -live[0][0]: 22 | res += [ [pos, -live[0][0]] ] 23 | return res[1:] 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.getSkyline([[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]])) 28 | print('Expected:', [[2,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/237. Delete Node in a Linked List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 40 ms, faster than 89.32% of Python3 online submissions for Delete Node in a Linked List. 3 | Memory Usage: 14.2 MB, less than 61.09% of Python3 online submissions for Delete Node in a Linked List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.next = None 12 | 13 | class Solution: 14 | def deleteNode(self, node): 15 | """ 16 | :type node: ListNode 17 | :rtype: void Do not return anything, modify node in-place instead. 18 | """ 19 | while node is not None: 20 | node.val = node.next.val 21 | if node.next.next == None: 22 | node.next = None 23 | node = node.next 24 | 25 | def main(): 26 | sol = Solution() 27 | n1 = ListNode(4) 28 | n2 = ListNode(5) 29 | n3 = ListNode(1) 30 | n4 = ListNode(9) 31 | n1.next = n2 32 | n2.next = n3 33 | n3.next = n4 34 | sol.deleteNode(n2) 35 | list_ans = [] 36 | head = n1 37 | while head is not None: 38 | list_ans.append(head.val) 39 | head = head.next 40 | print('Output:', list_ans) 41 | print('Expected:', [4,1,9]) 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/242. Valid Anagram.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 64 ms, faster than 61.38% of Python3 online submissions for Valid Anagram. 3 | Memory Usage: 14.5 MB, less than 70.90% of Python3 online submissions for Valid Anagram. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def isAnagram(self, s: str, t: str) -> bool: 10 | cache = {} 11 | for char in s: 12 | if char in cache.keys(): 13 | cache[char] += 1 14 | else: 15 | cache[char] = 1 16 | for char in t: 17 | if char not in cache.keys(): 18 | return False 19 | cache[char] -= 1 20 | if cache[char] < 0: 21 | return False 22 | for v in cache.values(): 23 | if v != 0: 24 | return False 25 | return True 26 | 27 | def main(): 28 | sol = Solution() 29 | print('Output:', sol.isAnagram("anagram", "nagaram")) 30 | print('Expected:', True) 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/26. Remove Duplicates from Sorted Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 88 ms, faster than 91.69% of Python3 online submissions for Remove Duplicates from Sorted Array. 3 | Memory Usage: 15.6 MB, less than 24.01% of Python3 online submissions for Remove Duplicates from Sorted Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def removeDuplicates(self, nums: List[int]) -> int: 10 | left_shift = 0 11 | for idx, val in enumerate(nums): 12 | if idx==0: 13 | continue 14 | if val == nums[idx-1]: 15 | left_shift += 1 16 | else: 17 | nums[idx-left_shift] = val 18 | return len(nums)-left_shift 19 | 20 | def main(): 21 | sol = Solution() 22 | inp = [1,1,2] 23 | ans = sol.removeDuplicates(inp) 24 | print('Output:', inp[:ans]) 25 | print('Expected:', [1,2]) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/268. Missing Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 246 ms, faster than 29.65% of Python3 online submissions for Missing Number. 3 | Memory Usage: 15.6 MB, less than 12.17% of Python3 online submissions for Missing Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def missingNumber(self, nums: List[int]) -> int: 10 | cache = {} 11 | for val in range(len(nums)+1): 12 | cache[val] = 1 13 | for n in nums: 14 | cache[n] = 0 15 | for k, v in cache.items(): 16 | if cache[k]==1: 17 | return k 18 | 19 | def main(): 20 | sol = Solution() 21 | print('Output:', sol.missingNumber([3,0,1])) 22 | print('Expected:', 2) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/28. Implement strStr().py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 116 ms, faster than 49.08% of Python3 online submissions for Implement strStr(). 3 | Memory Usage: 14.2 MB, less than 27.99% of Python3 online submissions for Implement strStr(). 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def strStr(self, haystack: str, needle: str) -> int: 10 | L1 = len(needle) 11 | L2 = len(haystack) 12 | if L1==0 or haystack==needle: 13 | return 0 14 | if L2==0 or L1 > L2: 15 | return -1 16 | for idx in range(len(haystack[:L2-L1+1])): 17 | if haystack[idx:idx+L1]==needle: 18 | return idx 19 | return -1 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:',sol.strStr("hello", "ll")) 24 | print('Expected:', 2) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/289. Game of Life.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 57 ms, faster than 28.89% of Python3 online submissions for Game of Life. 3 | Memory Usage: 14 MB, less than 52.07% of Python3 online submissions for Game of Life. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def gameOfLife(self, board: List[List[int]]) -> None: 10 | """ 11 | Do not return anything, modify board in-place instead. 12 | """ 13 | rows = len(board) 14 | cols = len(board[0]) 15 | flip = [] 16 | for i in range(rows): 17 | for j in range(cols): 18 | count = self.neighborCount(i, j, board) 19 | if (board[i][j]==1 and count<2) \ 20 | or (board[i][j]==1 and count>3) \ 21 | or (board[i][j]==0 and count==3): 22 | flip.append([i,j]) 23 | for pair in flip: 24 | if board[pair[0]][pair[1]] == 1: 25 | board[pair[0]][pair[1]] = 0 26 | else: 27 | board[pair[0]][pair[1]] = 1 28 | 29 | def neighborCount(self, i: int, j: int, board: List[List[int]]) -> int: 30 | rows = len(board) 31 | cols = len(board[0]) 32 | neighbors = [] 33 | for x in [i-1, i ,i+1]: 34 | for y in [j-1, j ,j+1]: 35 | if x >= 0 and x < rows and y >= 0 and y < cols: 36 | if not (x==i and y==j): 37 | neighbors.append(board[x][y]) 38 | return sum(neighbors) 39 | 40 | def main(): 41 | sol = Solution() 42 | inp = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]] 43 | sol.gameOfLife(inp) 44 | print('Output:', inp) 45 | print('Expected:', [[0,0,0],[1,0,1],[0,1,1],[0,1,0]]) 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/29. Divide Two Integers.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 12 ms, faster than 100.00% of Python3 online submissions for Divide Two Integers. 3 | Memory Usage: 14 MB, less than 40.31% of Python3 online submissions for Divide Two Integers. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def divide(self, dividend: int, divisor: int) -> int: 10 | invert = False 11 | if (divisor < 0 and dividend > 0) or (divisor > 0 and dividend < 0): 12 | invert = True 13 | if dividend < 0: 14 | dividend = -dividend 15 | if divisor < 0: 16 | divisor = -divisor 17 | ans = 0 18 | summation = divisor 19 | while dividend >= summation: 20 | current_ans = 1 21 | while (summation + summation) <= dividend: 22 | summation += summation 23 | current_ans += current_ans 24 | dividend -= summation 25 | summation = divisor 26 | ans += current_ans 27 | if invert: 28 | ans = -ans 29 | return min(2147483647, max(ans, -2147483648)) 30 | 31 | def main(): 32 | sol = Solution() 33 | print('Output:', sol.divide(7, -3)) 34 | print('Expected:', -2) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/315. Count of Smaller Numbers After Self.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 3284 ms, faster than 74.29% of Python3 online submissions for Count of Smaller Numbers After Self. 3 | Memory Usage: 33.2 MB, less than 76.39% of Python3 online submissions for Count of Smaller Numbers After Self. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def countSmaller(self, nums: List[int]) -> List[int]: 10 | self.nums = nums 11 | self.ans = [0] * len(nums) 12 | indexes = list(range(len(nums))) 13 | _ = self.sortIndices(indexes) 14 | return self.ans 15 | 16 | def sortIndices(self, indexes): 17 | half = len(indexes) // 2 18 | if half > 0: 19 | left = self.sortIndices(indexes[:half]) 20 | right = self.sortIndices(indexes[half:]) 21 | for i in range(len(indexes)-1,-1,-1): 22 | if len(right)==0 or \ 23 | (len(left)>0 and self.nums[left[-1]] > self.nums[right[-1]]): 24 | self.ans[left[-1]] += len(right) 25 | indexes[i] = left.pop() 26 | else: 27 | indexes[i] = right.pop() 28 | return indexes 29 | 30 | def main(): 31 | sol = Solution() 32 | print('Output:', sol.countSmaller([5,2,6,1])) 33 | print('Expected:', [2,1,1,0]) 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/324. Wiggle Sort II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 509 ms, faster than 14.68% of Python3 online submissions for Wiggle Sort II. 3 | Memory Usage: 17.6 MB, less than 10.60% of Python3 online submissions for Wiggle Sort II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def wiggleSort(self, nums: List[int]) -> None: 10 | """ 11 | Do not return anything, modify nums in-place instead. 12 | """ 13 | if len(nums)<=1: 14 | return 15 | temp = self.mergeSort(nums) 16 | for i in range(1, len(nums), 2): 17 | nums[i] = temp.pop() 18 | for i in range(0, len(nums), 2): 19 | nums[i] = temp.pop() 20 | 21 | def mergeSort(self, nums: List[int]) -> List[int]: 22 | if len(nums)==0 or len(nums)==1: 23 | return nums 24 | elif len(nums)==2: 25 | if nums[0] > nums[1]: 26 | return nums[::-1] 27 | else: 28 | return nums 29 | else: 30 | left = self.mergeSort(nums[:len(nums)//2]) 31 | right = self.mergeSort(nums[len(nums)//2:]) 32 | temp = [] 33 | i = 0 34 | j = 0 35 | while i < len(left) or j < len(right): 36 | if j==len(right): 37 | temp.append(left[i]) 38 | i += 1 39 | elif i==len(left): 40 | temp.append(right[j]) 41 | j += 1 42 | elif left[i] bool: 10 | if n == 1 or n == 3: 11 | return True 12 | val = 3 13 | while val < n: 14 | val *=3 15 | if val == n: 16 | return True 17 | return False 18 | 19 | def main(): 20 | sol = Solution() 21 | print('Output:', sol.isPowerOfThree(27)) 22 | print('Expected:', True) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/328. Odd Even Linked List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 62 ms, faster than 49.24% of Python3 online submissions for Odd Even Linked List. 3 | Memory Usage: 16.6 MB, less than 81.51% of Python3 online submissions for Odd Even Linked List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]: 15 | if head is None: 16 | return head 17 | if head.next is None: 18 | return head 19 | odd_ptr = head 20 | even_ptr = head.next 21 | even_head = even_ptr 22 | while odd_ptr is not None: 23 | old_odd = odd_ptr 24 | old_even = even_ptr 25 | if even_ptr is not None: 26 | odd_ptr = even_ptr.next 27 | if odd_ptr is not None: 28 | even_ptr = odd_ptr.next 29 | else: 30 | even_ptr = None 31 | else: 32 | odd_ptr = None 33 | even_ptr = None 34 | old_odd.next = odd_ptr 35 | if old_odd.next is None: 36 | old_odd.next = even_head 37 | if old_even is not None: 38 | old_even.next = even_ptr 39 | return head 40 | 41 | def main(): 42 | sol = Solution() 43 | head = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5))))) 44 | ans = sol.oddEvenList(head) 45 | list_ans = [] 46 | while ans is not None: 47 | list_ans.append(ans.val) 48 | ans = ans.next 49 | print('Output:', list_ans) 50 | print('Expected:', [1,3,5,2,4]) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/329. Longest Increasing Path in a Matrix.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 488 ms, faster than 85.56% of Python3 online submissions for Longest Increasing Path in a Matrix. 3 | Memory Usage: 16 MB, less than 58.01% of Python3 online submissions for Longest Increasing Path in a Matrix. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.cache = {} 11 | 12 | def longestIncreasingPath(self, matrix: List[List[int]]) -> int: 13 | ans = -1 14 | self.matrix = matrix 15 | self.rows = len(matrix) 16 | self.cols = len(matrix[0]) 17 | for i in range(self.rows): 18 | for j in range(self.cols): 19 | ans = max(ans, self.longestPathFrom(i,j)) 20 | return ans 21 | 22 | def longestPathFrom(self, i: int, j: int) -> int: 23 | if (i,j) in self.cache.keys(): 24 | return self.cache[(i,j)] 25 | ans = 1 26 | if i-1 >= 0: 27 | top = self.matrix[i-1][j] 28 | if top > self.matrix[i][j]: 29 | ans = max(ans, 1+self.longestPathFrom(i-1,j)) 30 | if i+1 < self.rows: 31 | bottom = self.matrix[i+1][j] 32 | if bottom > self.matrix[i][j]: 33 | ans = max(ans, 1+self.longestPathFrom(i+1,j)) 34 | if j-1 >= 0: 35 | left = self.matrix[i][j-1] 36 | if left > self.matrix[i][j]: 37 | ans = max(ans, 1+self.longestPathFrom(i,j-1)) 38 | if j+1 < self.cols: 39 | right = self.matrix[i][j+1] 40 | if right > self.matrix[i][j]: 41 | ans = max(ans, 1+self.longestPathFrom(i,j+1)) 42 | self.cache[(i,j)] = ans 43 | return ans 44 | 45 | def main(): 46 | sol = Solution() 47 | print('Output:', sol.longestIncreasingPath([[9,9,4],[6,6,8],[2,1,1]])) 48 | print('Expected:', 4) 49 | 50 | if __name__ == "__main__": 51 | main() 52 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/334. Increasing Triplet Subsequence.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 672 ms, faster than 66.56% of Python3 online submissions for Increasing Triplet Subsequence. 3 | Memory Usage: 24.6 MB, less than 48.46% of Python3 online submissions for Increasing Triplet Subsequence. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def increasingTriplet(self, nums: List[int]) -> bool: 11 | triplet_start = [math.inf, math.inf] 12 | for idx in range(len(nums)): 13 | if nums[idx] <= triplet_start[0]: 14 | triplet_start[0] = nums[idx] 15 | if nums[idx] > triplet_start[0] and nums[idx] <= triplet_start[1]: 16 | triplet_start[1] = nums[idx] 17 | if nums[idx] > triplet_start[0] and nums[idx] > triplet_start[1]: 18 | return True 19 | return False 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:', sol.increasingTriplet([20,100,10,12,5,13])) 24 | print('Expected:', True) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/350. Intersection of Two Arrays II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 56 ms, faster than 76.59% of Python3 online submissions for Intersection of Two Arrays II. 3 | Memory Usage: 14.1 MB, less than 27.08% of Python3 online submissions for Intersection of Two Arrays II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: 10 | ans = [] 11 | cache = {} 12 | for n in nums1: 13 | if n not in cache.keys(): 14 | cache[n] = 1 15 | else: 16 | cache[n] += 1 17 | for n in nums2: 18 | if n in cache.keys(): 19 | if cache[n] > 0: 20 | cache[n] -= 1 21 | ans.append(n) 22 | return ans 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.intersect([1,2,2,1], [2,2])) 27 | print('Expected:', [2, 2]) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/36. Valid Sudoku.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 231 ms, faster than 5.19% of Python3 online submissions for Valid Sudoku. 3 | Memory Usage: 13.9 MB, less than 48.77% of Python3 online submissions for Valid Sudoku. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from copy import deepcopy 8 | 9 | class Solution: 10 | def isValidSudoku(self, board: List[List[str]]) -> bool: 11 | bak_search_cache = {} 12 | for i in range(10): 13 | bak_search_cache[str(i)] = 1 14 | for row in range(len(board)): 15 | search_cache = deepcopy(bak_search_cache) 16 | for elem in board[row]: 17 | if elem != '.': 18 | search_cache[elem] -= 1 19 | if search_cache[elem] < 0: 20 | return False 21 | for col in range(len(board[0])): 22 | search_cache = deepcopy(bak_search_cache) 23 | for row in range(len(board)): 24 | val = board[row][col] 25 | if val != '.': 26 | search_cache[val] -= 1 27 | if search_cache[val] < 0: 28 | return False 29 | for big_row in range(3): 30 | for big_col in range(3): 31 | search_cache = deepcopy(bak_search_cache) 32 | for row in range(3): 33 | for col in range(3): 34 | val = board[row+3*big_row][col+3*big_col] 35 | if val != '.': 36 | search_cache[val] -= 1 37 | if search_cache[val] < 0: 38 | return False 39 | return True 40 | 41 | def main(): 42 | sol = Solution() 43 | print('Output:', sol.isValidSudoku([["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]])) 44 | print('Expected:', True) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/371. Sum of Two Integers.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 59 ms, faster than 11.31% of Python3 online submissions for Sum of Two Integers. 3 | Memory Usage: 13.9 MB, less than 66.37% of Python3 online submissions for Sum of Two Integers. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def getSum(self, a: int, b: int) -> int: 10 | MAX = 0x7FFFFFFF 11 | MIN = 0x80000000 12 | mask = 0xFFFFFFFF 13 | add = (a ^ b) & mask 14 | carry = ((a & b) << 1) & mask 15 | while carry != 0: 16 | new_add = (add ^ carry) & mask 17 | new_carry = ((add & carry) << 1) & mask 18 | add = new_add 19 | carry = new_carry 20 | if add <= MAX: 21 | return add 22 | else: 23 | return ~(add ^ mask) 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.getSum(2, 3)) 28 | print('Expected:', 5) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/378. Kth Smallest Element in a Sorted Matrix.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 204 ms, faster than 86.62% of Python3 online submissions for Kth Smallest Element in a Sorted Matrix. 3 | Memory Usage: 18.8 MB, less than 41.73% of Python3 online submissions for Kth Smallest Element in a Sorted Matrix. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def kthSmallest(self, matrix: List[List[int]], k: int) -> int: 10 | self.matrix = matrix 11 | self.rows = len(matrix) 12 | self.cols = len(matrix[0]) 13 | left = matrix[0][0] 14 | right = matrix[-1][-1] 15 | ans = -1 16 | while left <= right: 17 | mid = (left + right) // 2 18 | if self.countLessOrEqual(mid) >= k: 19 | ans = mid 20 | right = mid - 1 21 | else: 22 | left = mid + 1 23 | return ans 24 | 25 | def countLessOrEqual(self, x): 26 | counter = 0 27 | c = self.cols - 1 28 | for r in range(self.rows): 29 | while c >= 0 and self.matrix[r][c] > x: 30 | c -= 1 31 | counter += (c + 1) 32 | return counter 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.kthSmallest([[1,5,9],[10,11,13],[12,13,15]], 8)) 37 | print('Expected:', 13) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/38. Count and Say.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 44 ms, faster than 92.75% of Python3 online submissions for Count and Say. 3 | Memory Usage: 14.1 MB, less than 36.67% of Python3 online submissions for Count and Say. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def countAndSay(self, n: int) -> str: 10 | if n==1: 11 | return '1' 12 | else: 13 | string = self.countAndSay(n-1) 14 | if len(string)==1: 15 | return '1'+str(string[0]) 16 | say = '' 17 | counter = 1 18 | for idx, char in enumerate(string): 19 | if idx == 0: 20 | continue 21 | if char != string[idx-1]: 22 | say = say + str(counter) + str(string[idx-1]) 23 | counter = 1 24 | else: 25 | counter += 1 26 | if counter != 0: 27 | say = say + str(counter) + str(string[-1]) 28 | return say 29 | 30 | def main(): 31 | sol = Solution() 32 | print('Output:', sol.countAndSay(4)) 33 | print('Expected:', '1211') 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/380. Insert Delete GetRandom O(1).py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 544 ms, faster than 60.84% of Python3 online submissions for Insert Delete GetRandom O(1). 3 | Memory Usage: 61.1 MB, less than 89.71% of Python3 online submissions for Insert Delete GetRandom O(1). 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from random import randint 8 | 9 | class RandomizedSet: 10 | def __init__(self): 11 | self.val_set = {} 12 | self.keys = [] 13 | self.length = 0 14 | 15 | def insert(self, val: int) -> bool: 16 | ret = True 17 | if val in self.val_set.keys(): 18 | ret = False 19 | else: 20 | self.length += 1 21 | self.keys.append(val) 22 | self.val_set[val] = val 23 | return ret 24 | 25 | def remove(self, val: int) -> bool: 26 | ret = False 27 | if val in self.val_set.keys(): 28 | ret = True 29 | del self.val_set[val] 30 | self.keys.remove(val) 31 | self.length -= 1 32 | return ret 33 | 34 | def getRandom(self) -> int: 35 | pick = randint(0,self.length-1) 36 | return self.val_set[self.keys[pick]] 37 | 38 | def main(): 39 | obj = RandomizedSet() 40 | ret_1 = obj.insert(1) 41 | ret_2 = obj.remove(2) 42 | ret_3 = obj.insert(2) 43 | ret_4 = obj.getRandom() 44 | ret_5 = obj.remove(1) 45 | ret_6 = obj.insert(2) 46 | ret_7 = obj.getRandom() 47 | print('Output:', [ret_1, ret_2, ret_3, ret_4, ret_5, ret_6, ret_7]) 48 | print('Expected:', [True,False,True,2,True,False,2]) 49 | 50 | if __name__ == "__main__": 51 | main() 52 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/384. Shuffle an Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 341 ms, faster than 63.77% of Python3 online submissions for Shuffle an Array. 3 | Memory Usage: 19.6 MB, less than 94.64% of Python3 online submissions for Shuffle an Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from random import randint 8 | 9 | class Solution: 10 | 11 | def __init__(self, nums: List[int]): 12 | self.nums = nums 13 | self.bak = self.nums 14 | self.nums = self.shuffle() 15 | 16 | def reset(self) -> List[int]: 17 | return self.bak 18 | 19 | def shuffle(self) -> List[int]: 20 | ans = [] 21 | indices = list(range(len(self.nums))) 22 | while indices: 23 | idx = randint(0,len(indices)-1) 24 | ans.append(self.bak[indices[idx]]) 25 | indices.remove(indices[idx]) 26 | return ans 27 | 28 | def main(): 29 | obj = Solution([1,2,3]) 30 | ans_1 = obj.shuffle() 31 | ans_2 = obj.reset() 32 | ans_3 = obj.shuffle() 33 | print('Output:', [ans_1, ans_2, ans_3]) 34 | print('Expected:', [[3,2,1],[1,2,3],[2,1,3]]) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/387. First Unique Character in a String.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 239 ms, faster than 22.31% of Python3 online submissions for First Unique Character in a String. 3 | Memory Usage: 13.7 MB, less than 99.98% of Python3 online submissions for First Unique Character in a String. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def firstUniqChar(self, s: str) -> int: 10 | cache = {} 11 | for idx, char in enumerate(s): 12 | if char not in cache.keys(): 13 | cache[char] = [idx, 1] 14 | else: 15 | temp = cache[char] 16 | cache[char] = [temp[0], temp[1] + 1] 17 | for k, v in cache.items(): 18 | if v[1]==1: 19 | return v[0] 20 | return -1 21 | 22 | def main(): 23 | sol = Solution() 24 | print('Output:', sol.firstUniqChar("leetcode")) 25 | print('Expected:', 0) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/395. Longest Substring with At Least K Repeating Characters.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 86 ms, faster than 53.12% of Python3 online submissions for Longest Substring with At Least K Repeating Characters. 3 | Memory Usage: 14.4 MB, less than 16.35% of Python3 online submissions for Longest Substring with At Least K Repeating Characters. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def longestSubstring(self, s: str, k: int) -> int: 10 | counters = {} 11 | for char in s: 12 | if char not in counters.keys(): 13 | counters[char] = 1 14 | else: 15 | counters[char] += 1 16 | if all (count >= k for count in counters.values()): 17 | return len(s) 18 | else: 19 | chars_below_count = [] 20 | for key ,v in counters.items(): 21 | if v < k: 22 | chars_below_count.append(key) 23 | substrings = [] 24 | temp = '' 25 | for idx, char in enumerate(s): 26 | if char not in chars_below_count: 27 | temp += char 28 | else: 29 | if temp != '': 30 | substrings.append(temp) 31 | temp = '' 32 | substrings.append(temp) 33 | results = [] 34 | for subs in substrings: 35 | results.append(self.longestSubstring(subs,k)) 36 | if results: 37 | return max(results) 38 | else: 39 | return 0 40 | 41 | def main(): 42 | sol = Solution() 43 | print('Output:', sol.longestSubstring("bbaaacbd", 3)) 44 | print('Expected:', 3) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/412. Fizz Buzz.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 98.86% of Python3 online submissions for Fizz Buzz. 3 | Memory Usage: 15 MB, less than 88.44% of Python3 online submissions for Fizz Buzz. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def fizzBuzz(self, n: int) -> List[str]: 10 | ans = [] 11 | for i in range(1,n+1): 12 | flag1 = i%3 13 | flag2 = i%5 14 | if flag1==0 and flag2==0: 15 | ans.append("FizzBuzz") 16 | elif flag1==0: 17 | ans.append("Fizz") 18 | elif flag2==0: 19 | ans.append("Buzz") 20 | else: 21 | ans.append(str(i)) 22 | return ans 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.fizzBuzz(3)) 27 | print('Expected:', ["1","2","Fizz"]) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/44. Wildcard Matching.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 240 ms, faster than 83.26% of Python3 online submissions for Wildcard Matching. 3 | Memory Usage: 13.9 MB, less than 89.46% of Python3 online submissions for Wildcard Matching. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def isMatch(self, s: str, p: str) -> bool: 10 | length = len(s) 11 | if len(p) - p.count('*') > length: 12 | return False 13 | dp = [True] + [False]*length 14 | for character in p: 15 | if character != '*': 16 | for n in range(length-1,-1,-1): 17 | if dp[n]==True and (character == s[n] or character == '?'): 18 | dp[n+1] = True 19 | else: 20 | dp[n+1] = False 21 | else: 22 | for n in range(1, length+1): 23 | if dp[n-1] or dp[n]: 24 | dp[n] = True 25 | else: 26 | dp[n] = False 27 | if dp[0]==True and character == '*': 28 | dp[0] = True 29 | else: 30 | dp[0] = False 31 | return dp[-1] 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.isMatch("aa", "a")) 36 | print('Expected:', False) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/454. 4Sum II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1896 ms, faster than 7.52% of Python3 online submissions for 4Sum II. 3 | Memory Usage: 21.4 MB, less than 5.42% of Python3 online submissions for 4Sum II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int: 10 | first_half = {} 11 | second_half = {} 12 | length = len(nums1) 13 | for i in range(length): 14 | for j in range(length): 15 | total = nums1[i]+nums2[j] 16 | if total not in first_half.keys(): 17 | first_half[total] = [[i,j]] 18 | else: 19 | first_half[total].append([i,j]) 20 | for i in range(length): 21 | for j in range(length): 22 | total = nums3[i]+nums4[j] 23 | if total not in second_half.keys(): 24 | second_half[total] = [[i,j]] 25 | else: 26 | second_half[total].append([i,j]) 27 | ans = 0 28 | for total, pairs in first_half.items(): 29 | if -total in second_half.keys(): 30 | other_pairs = second_half[-total] 31 | ans += len(pairs)*len(other_pairs) 32 | return ans 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.fourSumCount([1,2], [-2,-1], [-1,2], [0,2])) 37 | print('Expected:', 2) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/50. Pow(x, n).py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 28 ms, faster than 95.51% of Python3 online submissions for Pow(x, n). 3 | Memory Usage: 13.9 MB, less than 74.72% of Python3 online submissions for Pow(x, n). 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def myPow(self, x: float, n: int) -> float: 10 | if n == 0: 11 | return 1 12 | if n < 0: 13 | x = 1/x 14 | n = -n 15 | ans = x 16 | if n%2==0: 17 | ans = self.myPow(ans*ans, n//2) 18 | else: 19 | ans = ans*self.myPow(ans, n-1) 20 | return ans 21 | 22 | def main(): 23 | sol = Solution() 24 | print('Output:', sol.myPow(2, 10)) 25 | print('Expected:', 1024) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/54. Spiral Matrix.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 27 ms, faster than 96.00% of Python3 online submissions for Spiral Matrix. 3 | Memory Usage: 14 MB, less than 9.73% of Python3 online submissions for Spiral Matrix. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def spiralOrder(self, matrix: List[List[int]]) -> List[int]: 10 | rows = len(matrix) 11 | if rows > 0: 12 | cols = len(matrix[0]) 13 | else: 14 | cols = 0 15 | if rows == 0 or cols == 0: 16 | return [] 17 | if rows == 1 and cols == 1: 18 | return [matrix[0][0]] 19 | ans = [] 20 | if rows == 1: 21 | for i in matrix[0]: 22 | ans.append(i) 23 | return ans 24 | if cols == 1: 25 | for i in matrix: 26 | ans.append(i[0]) 27 | return ans 28 | for i in range(cols): 29 | ans.append(matrix[0][i]) 30 | for i in range(1, rows): 31 | ans.append(matrix[i][cols-1]) 32 | for i in range(cols-2, -1, -1): 33 | ans.append(matrix[rows-1][i]) 34 | for i in range(rows-2, 0, -1): 35 | ans.append(matrix[i][0]) 36 | inside_matrix = [] 37 | for i in range(rows-2): 38 | inside_matrix.append([]) 39 | for j in range(cols-2): 40 | inside_matrix[i].append(matrix[i+1][j+1]) 41 | ans += self.spiralOrder(inside_matrix) 42 | return ans 43 | 44 | def main(): 45 | sol = Solution() 46 | print('Output:', sol.spiralOrder([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])) 47 | print('Expected:', [1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10]) 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/66. Plus One.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 42 ms, faster than 63.24% of Python3 online submissions for Plus One. 3 | Memory Usage: 13.9 MB, less than 67.96% of Python3 online submissions for Plus One. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def plusOne(self, digits: List[int]) -> List[int]: 10 | carry = 0 11 | for idx in range(len(digits)-1,-1,-1): 12 | if idx == len(digits)-1: 13 | this_val = digits[idx] + 1 14 | else: 15 | this_val = digits[idx] + carry 16 | if this_val < 10: 17 | digits[idx] = this_val 18 | carry = 0 19 | else: 20 | digits[idx] = 0 21 | carry = 1 22 | if carry == 1: 23 | digits = [1] + digits 24 | return digits 25 | 26 | def main(): 27 | sol = Solution() 28 | print('Output:',sol.plusOne([1,2,3])) 29 | print('Expected:', [1,2,4]) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/69. Sqrt(x).py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 2038 ms, faster than 16.45% of Python3 online submissions for Sqrt(x). 3 | Memory Usage: 13.9 MB, less than 66.65% of Python3 online submissions for Sqrt(x). 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def mySqrt(self, x: int) -> int: 10 | if x <= 1: 11 | return x 12 | for i in range(x+1): 13 | if i*i > x: 14 | return i-1 15 | 16 | def main(): 17 | sol = Solution() 18 | print('Output:',sol.mySqrt(4)) 19 | print('Expected:', 2) 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/7. Reverse Integer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 67 ms, faster than 9.95% of Python3 online submissions for Reverse Integer. 3 | Memory Usage: 13.9 MB, less than 72.31% of Python3 online submissions for Reverse Integer. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def reverse(self, x: int) -> int: 10 | if x < 0: 11 | negative = True 12 | x = -x 13 | else: 14 | negative = False 15 | ans = 0 16 | while x > 0: 17 | digit = x%10 18 | x = (x - digit)/10 19 | ans = 10*ans + digit 20 | if ans > 2**31: 21 | ans = 0 22 | if negative: 23 | ans = -ans 24 | return int(ans) 25 | 26 | def main(): 27 | sol = Solution() 28 | print('Output:', sol.reverse(123)) 29 | print('Expected:', 321) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/73. Set Matrix Zeroes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 156 ms, faster than 66.71% of Python3 online submissions for Set Matrix Zeroes. 3 | Memory Usage: 14.8 MB, less than 19.17% of Python3 online submissions for Set Matrix Zeroes. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def setZeroes(self, matrix: List[List[int]]) -> None: 10 | """ 11 | Do not return anything, modify matrix in-place instead. 12 | """ 13 | zeroed_rows = [] 14 | zeroed_cols = [] 15 | rows = len(matrix) 16 | cols = len(matrix[0]) 17 | for i in range(rows): 18 | for j in range(cols): 19 | if matrix[i][j]==0: 20 | if i not in zeroed_rows: 21 | zeroed_rows.append(i) 22 | if j not in zeroed_cols: 23 | zeroed_cols.append(j) 24 | for r in zeroed_rows: 25 | for c in range(cols): 26 | matrix[r][c]=0 27 | for c in zeroed_cols: 28 | for r in range(rows): 29 | matrix[r][c]=0 30 | 31 | def main(): 32 | sol = Solution() 33 | inp = [[1,1,1],[1,0,1],[1,1,1]] 34 | sol.setZeroes(inp) 35 | print('Output:', inp) 36 | print('Expected:', [[1,0,1],[0,0,0],[1,0,1]]) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/8. String to Integer (atoi).py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 40 ms, faster than 78.24% of Python3 online submissions for String to Integer (atoi). 3 | Memory Usage: 13.9 MB, less than 41.92% of Python3 online submissions for String to Integer (atoi). 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def myAtoi(self, s: str) -> int: 10 | digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] 11 | while len(s)>0 and s[0]==' ': 12 | s = s[1:] 13 | if s == '': 14 | return 0 15 | if s[0]=='-': 16 | negative = True 17 | s = s[1:] 18 | elif s[0]=='+': 19 | negative = False 20 | s = s[1:] 21 | else: 22 | negative = False 23 | ans = 0 24 | for c in s: 25 | if c not in digits: 26 | break 27 | else: 28 | ans = ans*10+int(c) 29 | if ans >= 2**31: 30 | if negative: 31 | ans = 2**31 32 | else: 33 | ans = 2**31-1 34 | break 35 | if negative: 36 | ans = -ans 37 | return ans 38 | 39 | def main(): 40 | sol = Solution() 41 | print('Output:', sol.myAtoi(" -42")) 42 | print('Expected:', -42) 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/88. Merge Sorted Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 66 ms, faster than 24.27% of Python3 online submissions for Merge Sorted Array. 3 | Memory Usage: 14.1 MB, less than 17.98% of Python3 online submissions for Merge Sorted Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: 10 | """ 11 | Do not return anything, modify nums1 in-place instead. 12 | """ 13 | read_idx1 = m-1 14 | read_idx2 = n-1 15 | write_idx = len(nums1)-1 16 | while read_idx1 >= 0 or read_idx2 >= 0: 17 | if read_idx2==-1: 18 | nums1[write_idx] = nums1[read_idx1] 19 | write_idx -= 1 20 | read_idx1 -= 1 21 | elif read_idx1==-1: 22 | nums1[write_idx] = nums2[read_idx2] 23 | write_idx -= 1 24 | read_idx2 -= 1 25 | elif nums1[read_idx1] > nums2[read_idx2]: 26 | nums1[write_idx] = nums1[read_idx1] 27 | write_idx -= 1 28 | read_idx1 -= 1 29 | else: 30 | nums1[write_idx] = nums2[read_idx2] 31 | write_idx -= 1 32 | read_idx2 -= 1 33 | 34 | def main(): 35 | sol = Solution() 36 | inp = [1,2,3,0,0,0] 37 | sol.merge(inp, 3, [2,5,6], 3) 38 | print('Output:', inp) 39 | print('Expected:', [1,2,2,3,5,6]) 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /bonus_top_interview_questions/91. Decode Ways.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 31 ms, faster than 93.16% of Python3 online submissions for Decode Ways. 3 | Memory Usage: 13.9 MB, less than 46.20% of Python3 online submissions for Decode Ways. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.cache = {} 11 | 12 | def numDecodings(self, s: str) -> int: 13 | if s in self.cache.keys(): 14 | return self.cache[s] 15 | if len(s)==1: 16 | if s=='0': 17 | return 0 18 | else: 19 | return 1 20 | else: 21 | if s[0]=='0': 22 | return 0 23 | else: 24 | take_one = self.numDecodings(s[1:]) 25 | if len(s)==2 and int(s[:2]) <=26: 26 | take_two = 1 27 | elif len(s)>2 and int(s[:2]) <=26: 28 | take_two = self.numDecodings(s[2:]) 29 | else: 30 | take_two = 0 31 | self.cache[s] = take_one + take_two 32 | return take_one + take_two 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.numDecodings("2101")) 37 | print('Expected:', 1) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/1. Two Sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 4308 ms, faster than 16.57% of Python3 online submissions for Two Sum. 3 | Memory Usage: 14.9 MB, less than 65.12% of Python3 online submissions for Two Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def twoSum(self, nums: List[int], target: int) -> List[int]: 10 | for i in range(len(nums)): 11 | for j in range(i+1,len(nums)): 12 | if nums[i] + nums[j] == target: 13 | return [i, j] 14 | 15 | def main(): 16 | sol = Solution() 17 | print('Output:', sol.twoSum([2,7,11,15], 9)) 18 | print('Expected:', [0, 1]) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /solutions/10. Regular Expression Matching.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 47 ms, faster than 89.57% of Python3 online submissions for Regular Expression Matching. 3 | Memory Usage: 15.2 MB, less than 6.45% of Python3 online submissions for Regular Expression Matching. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | 10 | cache = {} 11 | 12 | def isMatch(self, s: str, p: str) -> bool: 13 | if (s, p) in self.cache: 14 | return self.cache[(s, p)] 15 | length = len(s) 16 | if p == '': 17 | if length == 0: 18 | return True 19 | else: 20 | return False 21 | if p[-1] == '*': 22 | if self.isMatch(s, p[:-2]): 23 | self.cache[(s, p)] = True 24 | return True 25 | if length>0 and (s[-1]==p[-2] or p[-2]=='.') and self.isMatch(s[:-1], p): 26 | self.cache[(s, p)] = True 27 | return True 28 | if length>0 and (p[-1]==s[-1] or p[-1]=='.') and self.isMatch(s[:-1], p[:-1]): 29 | self.cache[(s, p)] = True 30 | return True 31 | self.cache[(s, p)] = False 32 | return False 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.isMatch('ab', '.*')) 37 | print('Expected:', True) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/101. Symmetric Tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 84.30% of Python3 online submissions for Symmetric Tree. 3 | Memory Usage: 14.2 MB, less than 79.09% of Python3 online submissions for Symmetric Tree. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def isSymmetric(self, root: Optional[TreeNode]) -> bool: 16 | pointers = [root] 17 | while len(pointers) > 0: 18 | new_pointers = [] 19 | values = [] 20 | for p in pointers: 21 | if p is not None: 22 | values.append(p.val) 23 | new_pointers.append(p.left) 24 | new_pointers.append(p.right) 25 | else: 26 | values.append(-101) 27 | pointers = new_pointers 28 | for i in range(int(len(values)/2)): 29 | if values[i] != values[len(values)-1-i]: 30 | return False 31 | return True 32 | 33 | def main(): 34 | sol = Solution() 35 | t = TreeNode(1,TreeNode(2,TreeNode(3,None,None),TreeNode(4,None,None)),TreeNode(2,TreeNode(4,None,None),TreeNode(3,None,None))) 36 | print('Output:', sol.isSymmetric(t)) 37 | print('Expected:', True) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/102. Binary Tree Level Order Traversal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 64.67% of Python3 online submissions for Binary Tree Level Order Traversal. 3 | Memory Usage: 14.7 MB, less than 25.77% of Python3 online submissions for Binary Tree Level Order Traversal. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: 16 | nodes = [root] 17 | ret = [] 18 | while len(nodes) > 0: 19 | new_nodes = [] 20 | temp = [] 21 | for n in nodes: 22 | if n is not None: 23 | temp.append(n.val) 24 | if n.left is not None: 25 | new_nodes.append(n.left) 26 | if n.right is not None: 27 | new_nodes.append(n.right) 28 | nodes = new_nodes 29 | if len(temp) > 0: 30 | ret.append(temp) 31 | return ret 32 | 33 | def main(): 34 | sol = Solution() 35 | t = TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7))) 36 | print('Output:', sol.levelOrder(t)) 37 | print('Expected:', [[3],[9,20],[15,7]]) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/104. Maximum Depth of Binary Tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 44 ms, faster than 54.69% of Python3 online submissions for Maximum Depth of Binary Tree. 3 | Memory Usage: 16.2 MB, less than 40.74% of Python3 online submissions for Maximum Depth of Binary Tree. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def maxDepth(self, root: Optional[TreeNode]) -> int: 16 | if root is None: 17 | return 0 18 | elif root.left is None and root.right is None: 19 | return 1 20 | else: 21 | return max(self.maxDepth(root.left),self.maxDepth(root.right) ) + 1 22 | 23 | def main(): 24 | sol = Solution() 25 | t = TreeNode(3,TreeNode(9,None,None),TreeNode(20,TreeNode(15,None,None),TreeNode(7,None,None))) 26 | print('Output:', sol.maxDepth(t)) 27 | print('Expected:', 3) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/105. Construct Binary Tree from Preorder and Inorder Traversal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 192 ms, faster than 39.67% of Python3 online submissions for Construct Binary Tree from Preorder and Inorder Traversal. 3 | Memory Usage: 88 MB, less than 37.36% of Python3 online submissions for Construct Binary Tree from Preorder and Inorder Traversal. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: 16 | if len(preorder) == 0: 17 | return None 18 | else: 19 | this_val = preorder[0] 20 | this_val_inorder_idx = inorder.index(this_val) 21 | return TreeNode(this_val, self.buildTree(preorder[1:this_val_inorder_idx+1], inorder[:this_val_inorder_idx]), self.buildTree(preorder[this_val_inorder_idx+1:], inorder[this_val_inorder_idx+1:])) 22 | 23 | list_ans = [] 24 | 25 | def printTree(head): 26 | if head is not None: 27 | list_ans.append(head.val) 28 | printTree(head.left) 29 | printTree(head.right) 30 | 31 | def main(): 32 | sol = Solution() 33 | printTree(sol.buildTree([3,9,20,15,7], [9,3,15,20,7])) 34 | print('Output:', list_ans) 35 | print('Expected:', [3,9,20,15,7]) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/11. Container With Most Water.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 6200 ms, faster than 5.01% of Python3 online submissions for Container With Most Water. 3 | Memory Usage: 27.5 MB, less than 57.22% of Python3 online submissions for Container With Most Water. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maxArea(self, height: List[int]) -> int: 10 | i = 0 11 | j = len(height) - 1 12 | used_min_vert = min(height[i], height[j]) 13 | max_water = (j - i) * used_min_vert 14 | while i+1 != j: 15 | if height[i] > height[j]: 16 | j -= 1 17 | if height[j] < used_min_vert: 18 | continue 19 | else: 20 | i +=1 21 | if height[i] < used_min_vert: 22 | continue 23 | if max(height[i:j]) < min(height[i], height[j]): 24 | break 25 | elif (max(height[i:j]) * (j - i)) < max_water: 26 | break 27 | else: 28 | used_min_vert = min(height[i], height[j]) 29 | water = (j - i) * used_min_vert 30 | if water > max_water: 31 | max_water = water 32 | return max_water 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.maxArea([2,3,10,5,7,8,9])) 37 | print('Expected:', 36) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/114. Flatten Binary Tree to Linked List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 80.89% of Python3 online submissions for Flatten Binary Tree to Linked List. 3 | Memory Usage: 15.4 MB, less than 15.00% of Python3 online submissions for Flatten Binary Tree to Linked List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | 16 | cache = [] 17 | main = 0 18 | 19 | def flatten(self, root: Optional[TreeNode]) -> None: 20 | """ 21 | Do not return anything, modify root in-place instead. 22 | """ 23 | this = False 24 | if self.main == 0: 25 | this = True 26 | self.cache = [] 27 | self.main = 1 28 | if root is not None: 29 | self.cache.append(root.val) 30 | self.flatten(root.left) 31 | self.flatten(root.right) 32 | if this: 33 | self.cache = self.cache[::-1] 34 | root.left = None 35 | nxt_r = None 36 | for i in self.cache[0:-1]: 37 | nxt_r = TreeNode(i, None, nxt_r) 38 | root.right = nxt_r 39 | 40 | def main(): 41 | sol = Solution() 42 | t = TreeNode(1, TreeNode(2, TreeNode(3), TreeNode(4)), TreeNode(5, None, TreeNode(6))) 43 | sol.flatten(t) 44 | list_ans = [] 45 | p = t 46 | while p is not None: 47 | list_ans.append(p.val) 48 | p = p.right 49 | print('Output:', list_ans) 50 | print('Expected:', [1,2,3,4,5,6]) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /solutions/121. Best Time to Buy and Sell Stock.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1024 ms, faster than 72.93% of Python3 online submissions for Best Time to Buy and Sell Stock. 3 | Memory Usage: 25.2 MB, less than 54.94% of Python3 online submissions for Best Time to Buy and Sell Stock. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maxProfit(self, prices: List[int]) -> int: 10 | max_profit = 0 11 | best_future_sell = prices[len(prices)-1] 12 | for idx in range(len(prices)-1): 13 | current_buying_price = prices[len(prices)-2-idx] 14 | profit = best_future_sell - current_buying_price 15 | if profit > max_profit: 16 | max_profit = profit 17 | if current_buying_price > best_future_sell: 18 | best_future_sell = current_buying_price 19 | return max_profit 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:', sol.maxProfit([7,1,5,3,6,4])) 24 | print('Expected:', 5) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /solutions/124. Binary Tree Maximum Path Sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 126 ms, faster than 48.44% of Python3 online submissions for Binary Tree Maximum Path Sum. 3 | Memory Usage: 21.4 MB, less than 66.36% of Python3 online submissions for Binary Tree Maximum Path Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class TreeNode: 10 | def __init__(self, val=0, left=None, right=None): 11 | self.val = val 12 | self.left = left 13 | self.right = right 14 | 15 | class Solution: 16 | def __init__(self): 17 | self.max_path = -math.inf 18 | 19 | def maxPathSum(self, root: Optional[TreeNode]) -> int: 20 | self.maxGain(root) 21 | return self.max_path 22 | 23 | def maxGain(self, node): 24 | if node is None: 25 | return 0 26 | left_gain = max(0, self.maxGain(node.left)) 27 | right_gain = max(0, self.maxGain(node.right)) 28 | current_max_path = node.val + left_gain + right_gain 29 | self.max_path = max(self.max_path, current_max_path) 30 | return node.val + max(left_gain, right_gain) 31 | 32 | def main(): 33 | sol = Solution() 34 | t = TreeNode(-10,TreeNode(9),TreeNode(20,TreeNode(15),TreeNode(7))) 35 | print('Output:', sol.maxPathSum(t)) 36 | print('Expected:', 42) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/127. Word Ladder.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 161 ms, faster than 82.67% of Python3 online submissions for Word Ladder. 3 | Memory Usage: 17.5 MB, less than 46.26% of Python3 online submissions for Word Ladder. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from collections import defaultdict 8 | from collections import deque 9 | 10 | class Solution: 11 | def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int: 12 | if endWord not in wordList or len(endWord)==0 or len(beginWord)==0 or len(wordList)==0: 13 | return 0 14 | L = len(beginWord) 15 | all_combo_dict = defaultdict(list) 16 | for word in wordList: 17 | for i in range(L): 18 | all_combo_dict[word[:i] + "*" + word[i+1:]].append(word) 19 | queue = deque([(beginWord, 1)]) 20 | visited = set() 21 | visited.add(beginWord) 22 | while len(queue)>0: 23 | current_word, level = queue.popleft() 24 | for i in range(L): 25 | intermediate_word = current_word[:i] + "*" + current_word[i+1:] 26 | for word in all_combo_dict[intermediate_word]: 27 | if word == endWord: 28 | return level + 1 29 | if word not in visited: 30 | visited.add(word) 31 | queue.append((word, level + 1)) 32 | return 0 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.ladderLength("hit", "cog", ["hot","dot","dog","lot","log","cog"])) 37 | print('Expected:', 5) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/128. Longest Consecutive Sequence.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 268 ms, faster than 70.75% of Python3 online submissions for Longest Consecutive Sequence. 3 | Memory Usage: 29.5 MB, less than 17.90% of Python3 online submissions for Longest Consecutive Sequence. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def longestConsecutive(self, nums: List[int]) -> int: 10 | if len(nums) == 0: 11 | return 0 12 | table = {} 13 | max_seq = 1 14 | for i in nums: 15 | if i in table.keys(): 16 | continue 17 | current_seq = 1 18 | flag_a, flag_b = False, False 19 | if i - 1 in table.keys(): 20 | current_seq = current_seq + table[i - 1] 21 | flag_a = True 22 | if i + 1 in table.keys(): 23 | current_seq = current_seq + table[i + 1] 24 | flag_b = True 25 | table[i] = current_seq 26 | if flag_a: 27 | table[i - table[i-1]] = current_seq 28 | if flag_b: 29 | table[i + table[i+1]] = current_seq 30 | if current_seq > max_seq: 31 | max_seq = current_seq 32 | return max_seq 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.longestConsecutive([9,1,4,7,3,-1,0,5,8,-1,6])) 37 | print('Expected:', 7) 38 | 39 | if __name__ == "__main__": 40 | main() -------------------------------------------------------------------------------- /solutions/131. Palindrome Partitioning.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 878 ms, faster than 55.75% of Python3 online submissions for Palindrome Partitioning. 3 | Memory Usage: 37.8 MB, less than 6.83% of Python3 online submissions for Palindrome Partitioning. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution(object): 9 | def partition(self, s): 10 | ret = [] 11 | if len(s) == 0: 12 | ret.append([]) 13 | else: 14 | for i in range(len(s)): 15 | if s[:i+1] == s[:i+1][::-1]: 16 | for suf in self.partition(s[i+1:]): 17 | ret.append([s[:i+1]] + suf) 18 | return ret 19 | 20 | def main(): 21 | sol = Solution() 22 | print('Output:', sol.partition('aab')) 23 | print('Expected:', [["a","a","b"],["aa","b"]]) 24 | 25 | if __name__ == "__main__": 26 | main() 27 | -------------------------------------------------------------------------------- /solutions/136. Single Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 132 ms, faster than 70.60% of Python3 online submissions for Single Number. 3 | Memory Usage: 16.7 MB, less than 61.03% of Python3 online submissions for Single Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def singleNumber(self, nums: List[int]) -> int: 10 | twice = {nums[0]: False} 11 | for i in range(1,len(nums)): 12 | if nums[i] in twice: 13 | twice[nums[i]] = True 14 | else: 15 | twice[nums[i]] = False 16 | for i in twice: 17 | if twice[i] == False: 18 | return i 19 | 20 | def main(): 21 | sol = Solution() 22 | print('Output:', sol.singleNumber([2,2,1])) 23 | print('Expected:', 1) 24 | 25 | if __name__ == "__main__": 26 | main() 27 | -------------------------------------------------------------------------------- /solutions/138. Copy List with Random Pointer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 49 ms, faster than 58.17% of Python3 online submissions for Copy List with Random Pointer. 3 | Memory Usage: 14.8 MB, less than 85.55% of Python3 online submissions for Copy List with Random Pointer. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Node: 9 | def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): 10 | self.val = int(x) 11 | self.next = next 12 | self.random = random 13 | 14 | class Solution: 15 | def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]': 16 | if head is None: 17 | return None 18 | old_to_new_ptrs = {} 19 | new_head = Node(head.val, random=head.random) 20 | old_to_new_ptrs[head] = new_head 21 | ptr1 = head.next 22 | ptr2 = new_head 23 | while ptr1 is not None: 24 | temp = Node(ptr1.val, random=ptr1.random) 25 | ptr2.next = temp 26 | old_to_new_ptrs[ptr1] = temp 27 | ptr1 = ptr1.next 28 | ptr2 = ptr2.next 29 | ptr2 = new_head 30 | while ptr2 is not None: 31 | if ptr2.random is not None: 32 | ptr2.random = old_to_new_ptrs[ptr2.random] 33 | ptr2 = ptr2.next 34 | return new_head 35 | 36 | def main(): 37 | sol = Solution() 38 | n2 = Node(2) 39 | n1 = Node(1,next=n2) 40 | n0 = Node(0,next=n1) 41 | n1.random = n0 42 | ans = sol.copyRandomList(n0) 43 | output = [] 44 | while ans is not None: 45 | if ans.random is not None: 46 | output.append([ans.val, ans.random.val]) 47 | else: 48 | output.append([ans.val, None]) 49 | ans = ans.next 50 | print('Output:', output) 51 | print('Expected:', [[0, None], [1, 0], [2, None]]) 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /solutions/139. Word Break.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 48 ms, faster than 68.93% of Python3 online submissions for Word Break. 3 | Memory Usage: 14 MB, less than 83.01% of Python3 online submissions for Word Break. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def wordBreak(self, s: str, wordDict: List[str]) -> bool: 10 | breakable_up_to_idx = [True] 11 | for i in range(len(s)): 12 | appendable_word_to_breakable_str = False 13 | for j in range(i+1): 14 | if (breakable_up_to_idx[j] == True) and (s[j:i+1] in wordDict): 15 | appendable_word_to_breakable_str = True 16 | if appendable_word_to_breakable_str: 17 | breakable_up_to_idx.append(True) 18 | else: 19 | breakable_up_to_idx.append(False) 20 | return breakable_up_to_idx[len(s)] 21 | 22 | def main(): 23 | sol = Solution() 24 | print('Output:', sol.wordBreak("leetcode", ["leet","code"])) 25 | print('Expected:', True) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /solutions/141. Linked List Cycle.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 4552 ms, faster than 5.04% of Python3 online submissions for Linked List Cycle. 3 | Memory Usage: 17.7 MB, less than 24.84% of Python3 online submissions for Linked List Cycle. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.next = None 12 | 13 | class Solution: 14 | def hasCycle(self, head: Optional[ListNode]) -> bool: 15 | nodes = [] 16 | while head is not None: 17 | nodes.append(head) 18 | head = head.next 19 | for n in nodes: 20 | if head == n: 21 | return True 22 | return False 23 | 24 | def main(): 25 | n1 = ListNode(3) 26 | n2 = ListNode(2) 27 | n3 = ListNode(0) 28 | n4 = ListNode(4) 29 | n1.next = n2 30 | n2.next = n3 31 | n3.next = n4 32 | n4.next = n2 33 | sol = Solution() 34 | print('Output:', sol.hasCycle(n1)) 35 | print('Expected:', True) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/142. Linked List Cycle II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1626 ms, faster than 5.01% of Python3 online submissions for Linked List Cycle II. 3 | Memory Usage: 17.3 MB, less than 73.61% of Python3 online submissions for Linked List Cycle II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.next = None 12 | 13 | class Solution: 14 | def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: 15 | cache = [] 16 | while head is not None: 17 | cache.append(head) 18 | head = head.next 19 | if head in cache: 20 | return head 21 | return None 22 | 23 | def main(): 24 | n1 = ListNode(1) 25 | n2 = ListNode(2) 26 | n3 = ListNode(3) 27 | n4 = ListNode(4) 28 | n1.next = n2 29 | n2.next = n3 30 | n3.next = n4 31 | n4.next = n2 32 | sol = Solution() 33 | ans = sol.detectCycle(n1) 34 | print('Output:',ans.val) 35 | print('Expected:', 2) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/146. LRU Cache.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 5452 ms, faster than 5.00% of Python3 online submissions for LRU Cache. 3 | Memory Usage: 75.2 MB, less than 76.44% of Python3 online submissions for LRU Cache. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class LRUCache: 9 | 10 | def __init__(self, capacity: int): 11 | self.capacity = capacity 12 | self.used = 0 13 | self.cache = {} 14 | self.age = {} 15 | self.time = 0 16 | 17 | def get(self, key: int) -> int: 18 | self.time += 1 19 | ans = -1 20 | if key in self.cache.keys(): 21 | self.age[key] = self.time 22 | ans = self.cache[key] 23 | return ans 24 | 25 | def put(self, key: int, value: int) -> None: 26 | self.time += 1 27 | if key not in self.cache.keys(): 28 | if self.used == self.capacity: 29 | oldest_key = min(self.age, key=self.age.get) 30 | self.cache.pop(oldest_key) 31 | self.age.pop(oldest_key) 32 | else: 33 | self.used += 1 34 | self.cache[key] = value 35 | self.age[key] = self.time 36 | 37 | def main(): 38 | ans = [] 39 | cache = LRUCache(2) 40 | cache.put(1,1) 41 | cache.put(2,2) 42 | ans.append(cache.get(1)) 43 | cache.put(3,3) 44 | ans.append(cache.get(2)) 45 | cache.put(4,4) 46 | ans.append(cache.get(1)) 47 | ans.append(cache.get(3)) 48 | ans.append(cache.get(4)) 49 | print('Output:', ans) 50 | print('Expected:', [1,-1,-1,3,4]) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /solutions/148. Sort List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 6845 ms, faster than 5.03% of Python3 online submissions for Sort List. 3 | Memory Usage: 28.7 MB, less than 99.95% of Python3 online submissions for Sort List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]: 15 | if head is None: 16 | return None 17 | temp = [] 18 | save_head = head 19 | while head is not None: 20 | temp.append(head.val) 21 | head = head.next 22 | ordered = self.sortList2(temp) 23 | head = save_head 24 | idx = 0 25 | while head is not None: 26 | head.val = ordered[idx] 27 | idx += 1 28 | head = head.next 29 | return save_head 30 | 31 | def sortList2(self, l: List[int]) -> List[int]: 32 | if len(l) <= 1: 33 | return l 34 | else: 35 | head = self.sortList2(l[:len(l)//2]) 36 | tail = self.sortList2(l[len(l)//2:]) 37 | new = [] 38 | while len(head) > 0 or len(tail) > 0: 39 | if len(head) == 0: 40 | new.append(tail[0]) 41 | tail = tail[1:] 42 | elif len(tail) == 0: 43 | new.append(head[0]) 44 | head = head[1:] 45 | elif head[0] < tail[0]: 46 | new.append(head[0]) 47 | head = head[1:] 48 | else: 49 | new.append(tail[0]) 50 | tail = tail[1:] 51 | return new 52 | 53 | def main(): 54 | sol = Solution() 55 | inp = ListNode(4, ListNode(2, ListNode(1, ListNode(3)))) 56 | ans = sol.sortList(inp) 57 | list_ans = [] 58 | while ans is not None: 59 | list_ans.append(ans.val) 60 | ans = ans.next 61 | print('Output:', list_ans) 62 | print('Expected:', [1,2,3,4]) 63 | 64 | if __name__ == "__main__": 65 | main() 66 | -------------------------------------------------------------------------------- /solutions/15. 3Sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1444 ms, faster than 39.82% of Python3 online submissions for 3Sum. 3 | Memory Usage: 17.4 MB, less than 73.99% of Python3 online submissions for 3Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def threeSum(self, nums: List[int]) -> List[List[int]]: 10 | nums = sorted(nums) 11 | ans = [] 12 | for i in range(len(nums)): 13 | j = i + 1 14 | k = len(nums) - 1 15 | if i != 0 and nums[i] == nums[i-1]: 16 | continue 17 | else: 18 | while j < k: 19 | if (k != len(nums)-1) and (nums[k] == nums[k+1]): 20 | k -= 1 21 | elif (nums[i] + nums[j] + nums[k]) > 0: 22 | k -= 1 23 | elif (nums[i] + nums[j] + nums[k]) < 0: 24 | j += 1 25 | else: 26 | ans.append([nums[i], nums[j], nums[k]]) 27 | j += 1 28 | k -= 1 29 | return ans 30 | def main(): 31 | sol = Solution() 32 | print('Output:', sol.threeSum([-1,0,1,2,-1,-4])) 33 | print('Expected:', [[-1,-1,2],[-1,0,1]]) 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /solutions/152. Maximum Product Subarray.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 84 ms, faster than 92.88% of Python3 online submissions for Maximum Product Subarray. 3 | Memory Usage: 16 MB, less than 5.67% of Python3 online submissions for Maximum Product Subarray. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maxProduct(self, nums: List[int]) -> int: 10 | if len(nums)==1: 11 | return nums[0] 12 | if len(nums)==2: 13 | return max(nums[0], max(nums[1], nums[0]*nums[1])) 14 | prod_up_to = [] 15 | prod_from = [] 16 | prod_so_far = 1 17 | for i in range(len(nums)): 18 | if prod_so_far == 0: 19 | prod_up_to.append(1*nums[i]) 20 | else: 21 | prod_up_to.append(prod_so_far*nums[i]) 22 | prod_so_far = prod_up_to[-1] 23 | if i < (len(nums) - 1): 24 | prod_from.append(-99-i) 25 | prod_so_far = 1 26 | len_prod_from = len(prod_from) 27 | for i in range(len_prod_from): 28 | if prod_so_far == 0: 29 | prod_from[len_prod_from-i-1] = nums[-1-i] 30 | else: 31 | prod_from[len_prod_from-i-1] = prod_so_far*nums[-1-i] 32 | prod_so_far = prod_from[len_prod_from-i-1] 33 | return max(max(prod_up_to), int(max(prod_from))) 34 | 35 | def main(): 36 | sol = Solution() 37 | print('Output:', sol.maxProduct([-1,-2,-3,0])) 38 | print('Expected:', 6) 39 | 40 | if __name__ == "__main__": 41 | main() 42 | -------------------------------------------------------------------------------- /solutions/153. Find Minimum in Rotated Sorted Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 44 ms, faster than 85.59% of Python3 online submissions for Find Minimum in Rotated Sorted Array. 3 | Memory Usage: 14.2 MB, less than 67.29% of Python3 online submissions for Find Minimum in Rotated Sorted Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findMin(self, nums: List[int]) -> int: 10 | if len(nums) == 0: 11 | return 12 | if len(nums) == 1: 13 | return nums[0] 14 | if len(nums) == 2: 15 | return min(nums[0], nums[1]) 16 | if len(nums) == 3: 17 | return min(min(nums[0], nums[1]),nums[2]) 18 | left = nums[:len(nums)//2] 19 | right = nums[len(nums)//2:] 20 | if right[0] > right[-1]: 21 | return self.findMin(right) 22 | elif left[0] > left[-1]: 23 | return self.findMin(left) 24 | else: 25 | return min(left[0],right[0]) 26 | 27 | def main(): 28 | sol = Solution() 29 | print('Output:', sol.findMin([3,4,5,1,2])) 30 | print('Expected:', 1) 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /solutions/155. Min Stack.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 60 ms, faster than 81.76% of Python3 online submissions for Min Stack. 3 | Memory Usage: 17.9 MB, less than 98.52% of Python3 online submissions for Min Stack. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class MinStack: 9 | 10 | def __init__(self): 11 | self.data = [] 12 | self.num_data = 0 13 | self.min = None 14 | 15 | def push(self, val: int) -> None: 16 | self.data.append(val) 17 | if self.min == None: 18 | self.min = val 19 | elif val < self.min: 20 | self.min = val 21 | 22 | def pop(self) -> None: 23 | temp1 = self.data[0:self.num_data-1] 24 | temp2 = self.data[self.num_data-1] 25 | self.data = temp1 26 | new_min = None 27 | if temp2 == self.min: 28 | for i in range(len(temp1)): 29 | if new_min == None: 30 | new_min = temp1[i] 31 | elif temp1[i] < new_min: 32 | new_min = temp1[i] 33 | self.min = new_min 34 | 35 | def top(self) -> int: 36 | return self.data[self.num_data-1] 37 | 38 | def getMin(self) -> int: 39 | return self.min 40 | 41 | def main(): 42 | obj = MinStack() 43 | obj.push(-2) 44 | obj.push(0) 45 | obj.push(-3) 46 | print('Output:', [obj.getMin(), obj.pop(), obj.top(), obj.getMin()]) 47 | print('Expected:', [-3, None, 0, -2]) 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /solutions/160. Intersection of Two Linked Lists.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 168 ms, faster than 49.62% of Python3 online submissions for Intersection of Two Linked Lists. 3 | Memory Usage: 29.6 MB, less than 36.80% of Python3 online submissions for Intersection of Two Linked Lists. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.next = None 12 | 13 | class Solution: 14 | def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: 15 | if headA == headB: 16 | return headA 17 | a_ptr = [] 18 | b_ptr = [] 19 | while headA is not None: 20 | a_ptr.append(headA) 21 | headA = headA.next 22 | while headB is not None: 23 | b_ptr.append(headB) 24 | headB = headB.next 25 | for i in range(max(len(a_ptr), len(b_ptr))): 26 | a = a_ptr[len(a_ptr)-1-i] if (len(a_ptr)-1-i) >= 0 else None 27 | b = b_ptr[len(b_ptr)-1-i] if (len(b_ptr)-1-i) >= 0 else None 28 | if a != b: 29 | if i == 0: 30 | return None 31 | else: 32 | return a_ptr[len(a_ptr)-i] 33 | else: 34 | return None 35 | 36 | def main(): 37 | n1a = ListNode(4) 38 | n2a = ListNode(1) 39 | # 40 | n1b = ListNode(5) 41 | n2b = ListNode(6) 42 | n3b = ListNode(1) 43 | # 44 | n1 = ListNode(8) 45 | n2 = ListNode(4) 46 | n3 = ListNode(5) 47 | # 48 | n1a.next = n2a 49 | n2a.next = n1 50 | # 51 | n1b.next = n2b 52 | n2b.next = n3b 53 | n3b.next = n1 54 | # 55 | n1.next = n2 56 | n2.next = n3 57 | # 58 | sol = Solution() 59 | ans = sol.getIntersectionNode(n1a, n1b) 60 | print('Output:', ans.val) 61 | print('Expected:', 8) 62 | 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /solutions/169. Majority Element.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 184 ms, faster than 32.94% of Python3 online submissions for Majority Element. 3 | Memory Usage: 15.5 MB, less than 82.92% of Python3 online submissions for Majority Element. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def majorityElement(self, nums: List[int]) -> int: 10 | counts = {} 11 | if len(nums) == 1: 12 | return nums[0] 13 | for i in nums: 14 | if i not in counts: 15 | counts[i] = 1 16 | else: 17 | counts[i] += 1 18 | if counts[i] > len(nums)/2: 19 | return i 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:', sol.majorityElement([3,2,3])) 24 | print('Expected:', 3) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /solutions/17. Letter Combinations of a Phone Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 64.53% of Python3 online submissions for Letter Combinations of a Phone Number. 3 | Memory Usage: 14.1 MB, less than 86.61% of Python3 online submissions for Letter Combinations of a Phone Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def letterCombinations(self, digits: str) -> List[str]: 10 | letters = [[], 11 | ['a', 'b', 'c'], 12 | ['d', 'e', 'f'], 13 | ['g', 'h', 'i'], 14 | ['j', 'k', 'l'], 15 | ['m', 'n', 'o'], 16 | ['p', 'q', 'r', 's'], 17 | ['t', 'u', 'v'], 18 | ['w', 'x', 'y', 'z'], 19 | ] 20 | digits_list = list(digits) 21 | output = [] 22 | for idx, d in enumerate(digits_list): 23 | if len(output) == 0: 24 | for j in letters[int(d)-1]: 25 | output.append(j) 26 | else: 27 | new_output = [] 28 | for k in output: 29 | for j in letters[int(d)-1]: 30 | new_output.append(k+j) 31 | output = new_output 32 | return output 33 | 34 | def main(): 35 | sol = Solution() 36 | print('Output:', sol.letterCombinations('23')) 37 | print('Expected:', ["ad","ae","af","bd","be","bf","cd","ce","cf"]) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/189. Rotate Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 364 ms, faster than 41.99% of Python3 online submissions for Rotate Array. 3 | Memory Usage: 25.3 MB, less than 83.97% of Python3 online submissions for Rotate Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def rotate(self, nums: List[int], k: int) -> None: 10 | """ 11 | Do not return anything, modify nums in-place instead. 12 | """ 13 | length = len(nums) 14 | if k == 0 or k == length: 15 | return 16 | k = k % length 17 | for i in range((length-k)//2): 18 | temp = nums[i] 19 | nums[i] = nums[length-k-1-i] 20 | nums[length-k-1-i] = temp 21 | for i in range(k//2): 22 | offset = length-k 23 | temp = nums[i+offset] 24 | nums[i+offset] = nums[k-1-i+offset] 25 | nums[k-1-i+offset] = temp 26 | for i in range(length//2): 27 | temp = nums[i] 28 | nums[i] = nums[length-1-i] 29 | nums[length-1-i] = temp 30 | 31 | def main(): 32 | sol = Solution() 33 | inp = [1,2,3,4,5,6,7,8,9,10] 34 | sol.rotate(inp, 3) 35 | print('Output:', inp) 36 | print('Expected:', [8,9,10,1,2,3,4,5,6,7]) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/19. Remove Nth Node From End of List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 92.79% of Python3 online submissions for Remove Nth Node From End of List. 3 | Memory Usage: 13.9 MB, less than 60.85% of Python3 online submissions for Remove Nth Node From End of List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]: 15 | if head is None: 16 | return None 17 | else: 18 | temp = head 19 | pos = 0 20 | while temp is not None: 21 | pos += 1 22 | temp = temp.next 23 | remove = pos - n + 1 24 | if remove == 1: 25 | return head.next 26 | else: 27 | temp = head 28 | pos = 0 29 | while temp is not None: 30 | pos += 1 31 | if pos+1 == remove: 32 | next_node = temp.next 33 | temp.next = next_node.next 34 | temp = temp.next 35 | return head 36 | 37 | def main(): 38 | sol = Solution() 39 | l = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5))))) 40 | ans = sol.removeNthFromEnd(l, 2) 41 | list_ans = [] 42 | p = ans 43 | while p is not None: 44 | list_ans.append(p.val) 45 | p = p.next 46 | print('Output:', list_ans) 47 | print('Expected:', [1,2,3,5]) 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /solutions/198. House Robber.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 24 ms, faster than 99.02% of Python3 online submissions for House Robber. 3 | Memory Usage: 14 MB, less than 45.67% of Python3 online submissions for House Robber. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | 10 | def __init__(self): 11 | self.cache = {} 12 | 13 | def rob(self, nums: List[int], idx: int=0) -> int: 14 | if idx in self.cache.keys(): 15 | return self.cache[idx] 16 | temp = nums[idx:] 17 | length = len(temp) 18 | if length==1: 19 | val = temp[0] 20 | return val 21 | elif length==2: 22 | val = max(temp[0], temp[1]) 23 | return val 24 | else: 25 | temp1 = temp[0]+self.rob(nums, idx+2) 26 | self.cache[idx+2] = temp1-temp[0] 27 | temp2 = self.rob(nums, idx+1) 28 | self.cache[idx+1] = temp2 29 | val = max(temp1, temp2) 30 | return val 31 | 32 | def main(): 33 | sol = Solution() 34 | print('Output:', sol.rob([6,6,4,8,4,3,3,10])) 35 | print('Expected:', 27) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/199. Binary Tree Right Side View.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 44.03% of Python3 online submissions for Binary Tree Right Side View. 3 | Memory Usage: 14.4 MB, less than 21.58% of Python3 online submissions for Binary Tree Right Side View. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def rightSideView(self, root: Optional[TreeNode]) -> List[int]: 16 | if root == None: 17 | return [] 18 | nodes = [root] 19 | vals_by_level = [] 20 | while len(nodes) > 0: 21 | new_nodes = [] 22 | temp = [] 23 | for n in nodes: 24 | temp.append(n.val) 25 | if n.left is not None: 26 | new_nodes.append(n.left) 27 | if n.right is not None: 28 | new_nodes.append(n.right) 29 | vals_by_level.append(temp) 30 | nodes = new_nodes 31 | ret = [] 32 | for l in vals_by_level: 33 | ret.append(l[-1]) 34 | return ret 35 | 36 | def main(): 37 | sol = Solution() 38 | t = TreeNode(1, TreeNode(2, None, TreeNode(5)), TreeNode(3, None, TreeNode(4))) 39 | print('Output:', sol.rightSideView(t)) 40 | print('Expected:', [1,3,4]) 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /solutions/2. Add Two Numbers.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 64 ms, faster than 90.63% of Python3 online submissions for Add Two Numbers. 3 | Memory Usage: 14.3 MB, less than 73.63% of Python3 online submissions for Add Two Numbers. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: 15 | cur = ListNode() 16 | init = cur 17 | carry = 0 18 | while True: 19 | l1_val = l1.val if l1 is not None else 0 20 | l2_val = l2.val if l2 is not None else 0 21 | cur.val = l1_val + l2_val + carry 22 | carry = 0 23 | if cur.val >= 10: 24 | carry = 1 25 | cur.val = cur.val - 10 26 | l1 = l1.next if l1 is not None else None 27 | l2 = l2.next if l2 is not None else None 28 | if l1 is None and l2 is None and carry == 0: 29 | break 30 | cur.next = ListNode() 31 | cur = cur.next 32 | return init 33 | 34 | def main(): 35 | sol = Solution() 36 | l1 = ListNode(2, ListNode(4, ListNode(3))) 37 | l2 = ListNode(5, ListNode(6, ListNode(4))) 38 | ans = sol.addTwoNumbers(l1, l2) 39 | list_ans = [] 40 | p = ans 41 | while p is not None: 42 | list_ans.append(p.val) 43 | p = p.next 44 | print('Output:', list_ans) 45 | print('Expected:', [7,0,8]) 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /solutions/20. Valid Parentheses.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 56 ms, faster than 9.04% of Python3 online submissions for Valid Parentheses. 3 | Memory Usage: 14.4 MB, less than 7.90% of Python3 online submissions for Valid Parentheses. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def isValid(self, s: str) -> bool: 10 | s = list(s) 11 | stack = [] 12 | for i in range(len(s)): 13 | if s[i] in ['(', '[', '{' ]: 14 | stack.append(s[i]) 15 | elif s[i] == ')': 16 | if len(stack) == 0: 17 | return False 18 | if stack[len(stack)-1] == '(': 19 | stack = stack[0:len(stack)-1] 20 | else: 21 | return False 22 | elif s[i] == ']': 23 | if len(stack) == 0: 24 | return False 25 | if stack[len(stack)-1] == '[': 26 | stack = stack[0:len(stack)-1] 27 | else: 28 | return False 29 | elif s[i] == '}': 30 | if len(stack) == 0: 31 | return False 32 | if stack[len(stack)-1] == '{': 33 | stack = stack[0:len(stack)-1] 34 | else: 35 | return False 36 | if len(stack) == 0: 37 | return True 38 | else: 39 | return False 40 | 41 | def main(): 42 | sol = Solution() 43 | print('Output:', sol.isValid("()")) 44 | print('Expected:', True) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /solutions/200. Number of Islands.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 488 ms, faster than 35.46% of Python3 online submissions for Number of Islands. 3 | Memory Usage: 23.8 MB, less than 9.86% of Python3 online submissions for Number of Islands. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | 10 | def __init__(self): 11 | self.rows = None 12 | self.cols = None 13 | self.temp = [] 14 | self.explored = {} 15 | 16 | def numIslands(self, grid: List[List[str]]) -> int: 17 | self.rows = len(grid) 18 | self.cols = len(grid[0]) 19 | counter = 0 20 | for i in range(self.rows): 21 | for j in range(self.cols): 22 | if grid[i][j] == '1': 23 | name = str(i)+'-'+str(j) 24 | if name in self.explored.keys(): 25 | continue 26 | counter += 1 27 | self.temp = [] 28 | self.findAllConnectedLand(grid, i, j) 29 | for s in self.temp: 30 | self.explored[s] = True 31 | return(counter) 32 | 33 | def findAllConnectedLand(self, grid: List[List[str]], i: int, j: int): 34 | this_name = str(i)+'-'+str(j) 35 | if this_name in self.temp: 36 | return 37 | else: 38 | self.temp.append(this_name) 39 | if i-1 >= 0 and grid[i-1][j]=='1' and str(i-1)+'-'+str(j) not in self.temp: 40 | self.findAllConnectedLand(grid, i-1, j) 41 | if i+1 < self.rows and grid[i+1][j]=='1' and str(i+1)+'-'+str(j) not in self.temp: 42 | self.findAllConnectedLand(grid, i+1, j) 43 | if j-1 >= 0 and grid[i][j-1]=='1' and str(i)+'-'+str(j-1) not in self.temp: 44 | self.findAllConnectedLand(grid, i, j-1) 45 | if j+1 < self.cols and grid[i][j+1]=='1' and str(i)+'-'+str(j+1) not in self.temp: 46 | self.findAllConnectedLand(grid, i, j+1) 47 | 48 | def main(): 49 | sol = Solution() 50 | print('Output:', sol.numIslands([["1","1","1"],["0","1","0"],["1","1","1"]])) 51 | print('Expected:', 1) 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /solutions/206. Reverse Linked List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 40 ms, faster than 42.39% of Python3 online submissions for Reverse Linked List. 3 | Memory Usage: 15.7 MB, less than 25.23% of Python3 online submissions for Reverse Linked List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: 15 | this = head 16 | ptr_to_previous = None 17 | counter = -1 18 | while this is not None: 19 | counter += 1 20 | if this.next is None: 21 | this.next = ptr_to_previous 22 | return this 23 | else: 24 | nxt = this.next 25 | this.next = ptr_to_previous 26 | ptr_to_previous = this 27 | this = nxt 28 | 29 | def main(): 30 | sol = Solution() 31 | l = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5))))) 32 | ans = sol.reverseList(l) 33 | list_ans = [] 34 | while ans is not None: 35 | list_ans.append(ans.val) 36 | ans = ans.next 37 | print('Output:', list_ans) 38 | print('Expected:', [5,4,3,2,1]) 39 | 40 | if __name__ == "__main__": 41 | main() 42 | -------------------------------------------------------------------------------- /solutions/207. Course Schedule.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 104 ms, faster than 85.03% of Python3 online submissions for Course Schedule. 3 | Memory Usage: 16.6 MB, less than 59.08% of Python3 online submissions for Course Schedule. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.prereq_of = None 11 | self.cache = None 12 | 13 | def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: 14 | self.prereq_of = [[] for _ in range(numCourses)] 15 | self.cache = [None for _ in range(numCourses)] 16 | for p in prerequisites: 17 | self.prereq_of[p[0]].append(p[1]) 18 | for course in range(numCourses): 19 | if not self.doableCourse(course): 20 | return False 21 | return True 22 | 23 | def doableCourse(self, i): 24 | if self.cache[i] is not None: 25 | return self.cache[i] 26 | self.cache[i] = False 27 | for j in self.prereq_of[i]: 28 | if not self.doableCourse(j): 29 | return False 30 | self.cache[i] = True 31 | return True 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.canFinish(2, [[1,0],[0,1]])) 36 | print('Expected:', False) 37 | 38 | if __name__ == "__main__": 39 | main() -------------------------------------------------------------------------------- /solutions/21. Merge Two Sorted Lists.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 28 ms, faster than 98.36% of Python3 online submissions for Merge Two Sorted Lists. 3 | Memory Usage: 14.1 MB, less than 96.31% of Python3 online submissions for Merge Two Sorted Lists. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def mergeTwoLists(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: 15 | l1 = l1 16 | l2 = l2 17 | if l1 is None and l2 is None: 18 | return None 19 | elif l1 is None: 20 | return l2 21 | elif l2 is None: 22 | return l1 23 | else: 24 | head = ListNode() 25 | cur = head 26 | while l1 is not None or l2 is not None: 27 | if l1 is None: 28 | cur.next = l2 29 | break 30 | elif l2 is None: 31 | cur.next = l1 32 | break 33 | else: 34 | new = ListNode() 35 | if l1.val <= l2.val: 36 | new.val = l1.val 37 | l1 = l1.next 38 | else: 39 | new.val = l2.val 40 | l2 = l2.next 41 | cur.next = new 42 | cur = new 43 | return head.next 44 | 45 | def main(): 46 | sol = Solution() 47 | l1 = ListNode(1, ListNode(2, ListNode(4, None))) 48 | l2 = ListNode(1, ListNode(3, ListNode(4, None))) 49 | ans = sol.mergeTwoLists(l1, l2) 50 | list_ans = [] 51 | while ans is not None: 52 | list_ans.append(ans.val) 53 | ans = ans.next 54 | print('Output:', list_ans) 55 | print('Expected:', [1,1,2,3,4,4]) 56 | 57 | if __name__ == "__main__": 58 | main() 59 | -------------------------------------------------------------------------------- /solutions/210. Course Schedule II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 118 ms, faster than 73.32% of Python3 online submissions for Course Schedule II. 3 | Memory Usage: 16.8 MB, less than 44.34% of Python3 online submissions for Course Schedule II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.prereq_of = None 11 | self.cache = None 12 | self.order = [] 13 | 14 | def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]: 15 | self.prereq_of = [[] for _ in range(numCourses)] 16 | self.cache = [None for _ in range(numCourses)] 17 | for p in prerequisites: 18 | self.prereq_of[p[0]].append(p[1]) 19 | for course in range(numCourses): 20 | if not self.doableCourse(course): 21 | return [] 22 | return self.order 23 | 24 | def doableCourse(self, i): 25 | if self.cache[i] is not None: 26 | return self.cache[i] 27 | self.cache[i] = False 28 | for j in self.prereq_of[i]: 29 | if not self.doableCourse(j): 30 | return False 31 | self.cache[i] = True 32 | self.order.append(i) 33 | return True 34 | 35 | def main(): 36 | sol = Solution() 37 | print('Output:', sol.findOrder(4, [[1,0],[2,0],[3,1],[3,2]])) 38 | print('Expected:', [0,2,1,3]) 39 | 40 | if __name__ == "__main__": 41 | main() -------------------------------------------------------------------------------- /solutions/215. Kth Largest Element in an Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 2856 ms, faster than 5.05% of Python3 online submissions for Kth Largest Element in an Array. 3 | Memory Usage: 15.2 MB, less than 48.73% of Python3 online submissions for Kth Largest Element in an Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findKthLargest(self, nums: List[int], k: int) -> int: 10 | counter = 0 11 | while True: 12 | largest = nums[0] 13 | largest_idx = 0 14 | for idx, n in enumerate(nums[1:]): 15 | if n > largest: 16 | largest_idx = idx+1 17 | largest = n 18 | nums = nums[:largest_idx] + nums[largest_idx+1:] 19 | counter += 1 20 | if counter == k: 21 | return largest 22 | 23 | def main(): 24 | sol = Solution() 25 | print('Output:', sol.findKthLargest([3,2,1,5,6,4], 2)) 26 | print('Expected:', 5) 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /solutions/22. Generate Parentheses.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 87.16% of Python3 online submissions for Generate Parentheses. 3 | Memory Usage: 14.6 MB, less than 41.07% of Python3 online submissions for Generate Parentheses. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def generateParenthesis(self, n: int) -> List[str]: 10 | ret = ['('] 11 | opened = [1] 12 | closed = [0] 13 | steps = 1 14 | while steps < (2*n): 15 | new_ret = [] 16 | new_opened = [] 17 | new_closed = [] 18 | for idx, s in enumerate(ret): 19 | if opened[idx] < n: 20 | new_ret.append(s+'(') 21 | new_opened.append(opened[idx] + 1) 22 | new_closed.append(closed[idx]) 23 | if opened[idx] > closed[idx]: 24 | new_ret.append(s+')') 25 | new_opened.append(opened[idx]) 26 | new_closed.append(closed[idx] + 1) 27 | ret = new_ret 28 | opened = new_opened 29 | closed = new_closed 30 | steps += 1 31 | return ret 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.generateParenthesis(3)) 36 | print('Expected:', ["((()))","(()())","(())()","()(())","()()()"]) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/221. Maximal Square.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 859 ms, faster than 34.17% of Python3 online submissions for Maximal Square. 3 | Memory Usage: 16.5 MB, less than 69.25% of Python3 online submissions for Maximal Square. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from copy import deepcopy 8 | 9 | class Solution: 10 | def maximalSquare(self, matrix: List[List[str]]) -> int: 11 | rows = len(matrix) 12 | cols = len(matrix[0]) 13 | cache = deepcopy(matrix) 14 | ones = False 15 | for i in range(rows): 16 | for j in range(cols): 17 | cache[i][j] = int(cache[i][j]) 18 | if cache[i][j]==1 and not ones: 19 | ones = True 20 | if not ones: 21 | return 0 22 | max_edge = 1 23 | for i in range(1, rows): 24 | for j in range(1, cols): 25 | if int(cache[i][j]) == 1: 26 | val_1 = min(cache[i-1][j-1], cache[i-1][j]) 27 | val_2 = min(val_1, cache[i][j-1]) 28 | cache[i][j] = val_2 + 1 29 | max_edge = max(max_edge, cache[i][j]) 30 | return max_edge**2 31 | 32 | def main(): 33 | sol = Solution() 34 | print('Output:', sol.maximalSquare([["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]])) 35 | print('Expected:', 4) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/226. Invert Binary Tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 24 ms, faster than 97.42% of Python3 online submissions for Invert Binary Tree. 3 | Memory Usage: 14.2 MB, less than 76.47% of Python3 online submissions for Invert Binary Tree. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: 16 | if root is None: 17 | return root 18 | else: 19 | return TreeNode(root.val, self.invertTree(root.right), self.invertTree(root.left)) 20 | 21 | def main(): 22 | sol = Solution() 23 | t = TreeNode(4, TreeNode(2, TreeNode(1), TreeNode(3)), TreeNode(7, TreeNode(6), TreeNode(9))) 24 | ans = sol.invertTree(t) 25 | list_ans = [] 26 | ptrs = [ans] 27 | while len(ptrs) > 0: 28 | new_ptrs = [] 29 | for p in ptrs: 30 | if p is not None: 31 | list_ans.append(p.val) 32 | new_ptrs.append(p.left) 33 | new_ptrs.append(p.right) 34 | ptrs = new_ptrs 35 | print('Output:', list_ans) 36 | print('Expected:', [4,7,2,9,6,3,1]) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/23. Merge k Sorted Lists.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 7612 ms, faster than 5.00% of Python3 online submissions for Merge k Sorted Lists. 3 | Memory Usage: 17.6 MB, less than 80.72% of Python3 online submissions for Merge k Sorted Lists. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class ListNode: 10 | def __init__(self, val=0, next=None): 11 | self.val = val 12 | self.next = next 13 | 14 | class Solution: 15 | def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: 16 | ans = None 17 | running_ptr = None 18 | while True: 19 | non_inf_val = False 20 | min_idx = -1 21 | min_val = math.inf 22 | for i in range(len(lists)): 23 | if lists[i] is not None: 24 | non_inf_val = True 25 | if lists[i].val < min_val: 26 | min_val = lists[i].val 27 | min_idx = i 28 | if non_inf_val == False: 29 | break 30 | to_add = lists[min_idx] 31 | lists[min_idx] = lists[min_idx].next 32 | if ans == None: 33 | ans = to_add 34 | running_ptr = ans 35 | else: 36 | running_ptr.next = to_add 37 | running_ptr = running_ptr.next 38 | return ans 39 | 40 | def main(): 41 | n11 = ListNode(1) 42 | n12 = ListNode(4) 43 | n13 = ListNode(5) 44 | n11.next = n12 45 | n12.next = n13 46 | n21 = ListNode(1) 47 | n22 = ListNode(3) 48 | n23 = ListNode(4) 49 | n21.next = n22 50 | n22.next = n23 51 | n31 = ListNode(2) 52 | n32 = ListNode(6) 53 | n31.next = n32 54 | inp = [n11, n21, n31] 55 | sol = Solution() 56 | ans = sol.mergeKLists(inp) 57 | list_ans = [] 58 | while ans is not None: 59 | list_ans.append(ans.val) 60 | ans = ans.next 61 | print('Output:', list_ans) 62 | print('Expected:', [1,1,2,3,4,4,5,6]) 63 | 64 | if __name__ == "__main__": 65 | main() 66 | -------------------------------------------------------------------------------- /solutions/230. Kth Smallest Element in a BST.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 52 ms, faster than 64.15% of Python3 online submissions for Kth Smallest Element in a BST. 3 | Memory Usage: 18.1 MB, less than 60.89% of Python3 online submissions for Kth Smallest Element in a BST. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | 16 | def kthSmallest(self, root: Optional[TreeNode], k: int) -> int: 17 | self.k = k 18 | self.vals = [] 19 | self.ans = None 20 | self.depthFirst(root) 21 | return self.ans 22 | 23 | def depthFirst(self, root: Optional[TreeNode]): 24 | if self.ans is not None: 25 | return 26 | if root is not None: 27 | self.depthFirst(root.left) 28 | self.vals.append(root.val) 29 | if len(self.vals) == self.k: 30 | self.ans = self.vals[-1] 31 | self.depthFirst(root.right) 32 | 33 | def main(): 34 | sol = Solution() 35 | t = TreeNode(3, TreeNode(1, None, TreeNode(2)), TreeNode(4)) 36 | print('Output:', sol.kthSmallest(t, 1)) 37 | print('Expected:', 1) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /solutions/234. Palindrome Linked List.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 816 ms, faster than 64.11% of Python3 online submissions for Palindrome Linked List. 3 | Memory Usage: 47.3 MB, less than 38.55% of Python3 online submissions for Palindrome Linked List. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def isPalindrome(self, head: Optional[ListNode]) -> bool: 15 | l = [] 16 | ptr = head 17 | while ptr is not None: 18 | l.append(ptr.val) 19 | ptr = ptr.next 20 | for i in range(int(len(l)//2)): 21 | if l[i] != l[len(l)-1-i]: 22 | return False 23 | return True 24 | 25 | def main(): 26 | sol = Solution() 27 | l = ListNode(1, ListNode(2, ListNode(2, ListNode(1)))) 28 | print('Output:', sol.isPalindrome(l)) 29 | print('Expected:', True) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /solutions/236. Lowest Common Ancestor of a Binary Tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 80 ms, faster than 33.51% of Python3 online submissions for Lowest Common Ancestor of a Binary Tree. 3 | Memory Usage: 25.7 MB, less than 45.85% of Python3 online submissions for Lowest Common Ancestor of a Binary Tree. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.left = None 12 | self.right = None 13 | 14 | class Solution: 15 | def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': 16 | self.p = p 17 | self.q = q 18 | self.pathToP = None 19 | self.pathToQ = None 20 | self.printPathsRec(root, [], 0) 21 | return next((a for a in self.pathToP[::-1] if a in self.pathToQ[::-1]), None) 22 | 23 | def printPathsRec(self, root, path, pathLen): 24 | if root is not None: 25 | if(len(path) > pathLen): 26 | # path[pathLen] = root.val 27 | path[pathLen] = root 28 | else: 29 | # path.append(root.val) 30 | path.append(root) 31 | pathLen = pathLen + 1 32 | if root == self.p: 33 | self.pathToP = path[:pathLen] 34 | if root == self.q: 35 | self.pathToQ = path[:pathLen] 36 | if root.left is not None or root.right is not None: 37 | self.printPathsRec(root.left, path, pathLen) 38 | self.printPathsRec(root.right, path, pathLen) 39 | else: 40 | pass 41 | # print(path[:pathLen]) 42 | 43 | def main(): 44 | sol = Solution() 45 | a = TreeNode(1) 46 | b = TreeNode(2) 47 | a.left = b 48 | ans = sol.lowestCommonAncestor(a, a, b) 49 | print('Output:', ans.val) 50 | print('Expected:', 1) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /solutions/238. Product of Array Except Self.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 240 ms, faster than 68.27% of Python3 online submissions for Product of Array Except Self. 3 | Memory Usage: 21.2 MB, less than 47.96% of Python3 online submissions for Product of Array Except Self. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def productExceptSelf(self, nums: List[int]) -> List[int]: 10 | val = 1 11 | zeros = 0 12 | for i in nums: 13 | if i != 0: 14 | val *= i 15 | if i == 0: 16 | zeros += 1 17 | ret = [] 18 | for i in nums: 19 | if zeros > 1: 20 | ret.append(0) 21 | elif zeros == 1: 22 | if i != 0: 23 | ret.append(0) 24 | else: 25 | ret.append(val) 26 | else: 27 | ret.append(int(val/i)) 28 | return ret 29 | 30 | def main(): 31 | sol = Solution() 32 | print('Output:', sol.productExceptSelf([1,2,3,4])) 33 | print('Expected:', [24,12,8,6]) 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /solutions/239. Sliding Window Maximum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 2888 ms, faster than 27.94% of Python3 online submissions for Sliding Window Maximum. 3 | Memory Usage: 29.7 MB, less than 79.09% of Python3 online submissions for Sliding Window Maximum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | from collections import deque 8 | 9 | class Solution: 10 | def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: 11 | window_indices = deque() 12 | ans = [] 13 | for i in range(len(nums)): 14 | if len(window_indices)>0 and window_indices[0] == i-k: 15 | window_indices.popleft() 16 | while len(window_indices)>0: 17 | if nums[window_indices[-1]] < nums[i]: 18 | window_indices.pop() 19 | else: 20 | break 21 | window_indices.append(i) 22 | if i >= k-1: 23 | ans.append(nums[window_indices[0]]) 24 | return ans 25 | 26 | def main(): 27 | sol = Solution() 28 | print('Output:', sol.maxSlidingWindow([1,3,-1,-3,5,3,6,7], 3)) 29 | print('Expected:', [3,3,5,5,6,7]) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /solutions/24. Swap Nodes in Pairs.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 47 ms, faster than 45.19% of Python3 online submissions for Swap Nodes in Pairs. 3 | Memory Usage: 13.9 MB, less than 43.00% of Python3 online submissions for Swap Nodes in Pairs. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]: 15 | if head is None: 16 | return None 17 | elif head.next is None: 18 | return head 19 | else: 20 | old_head = head 21 | old_rest_of = head.next.next 22 | head = head.next 23 | head.next = old_head 24 | head.next.next = self.swapPairs(old_rest_of) 25 | return head 26 | 27 | def main(): 28 | sol = Solution() 29 | l = ListNode(1, ListNode(2, ListNode(3, ListNode(4, None)))) 30 | ans = sol.swapPairs(l) 31 | list_ans = [] 32 | while ans is not None: 33 | list_ans.append(ans.val) 34 | ans = ans.next 35 | print('Output:', list_ans) 36 | print('Expected:', [2,1,4,3]) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/240. Search a 2D Matrix II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 211 ms, faster than 64.53% of Python3 online submissions for Search a 2D Matrix II. 3 | Memory Usage: 20.4 MB, less than 55.02% of Python3 online submissions for Search a 2D Matrix II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: 10 | rows = len(matrix) 11 | columns = len(matrix[0]) 12 | row, col = rows-1, columns-1 13 | for r in range(rows): 14 | if matrix[r][0] <= target and matrix[r][-1] >= target: 15 | search_in = matrix[r][:] 16 | while True: 17 | if search_in[len(search_in)//2] == target: 18 | return True 19 | elif len(search_in)==1: 20 | break 21 | elif search_in[len(search_in)//2] > target: 22 | search_in = search_in[:len(search_in)//2] 23 | else: 24 | search_in = search_in[len(search_in)//2:] 25 | return False 26 | 27 | def main(): 28 | sol = Solution() 29 | print('Output:', sol.searchMatrix([[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], 5)) 30 | print('Expected:', True) 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /solutions/25. Reverse Nodes in k-Group.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 44 ms, faster than 98.29% of Python3 online submissions for Reverse Nodes in k-Group. 3 | Memory Usage: 15.3 MB, less than 43.64% of Python3 online submissions for Reverse Nodes in k-Group. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class ListNode: 9 | def __init__(self, val=0, next=None): 10 | self.val = val 11 | self.next = next 12 | 13 | class Solution: 14 | def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]: 15 | counter = 0 16 | ans = head 17 | ptr = head 18 | while ptr is not None: 19 | counter += 1 20 | if counter == k: 21 | rest_of_list = ptr.next 22 | ptr.next = None 23 | ans = self.invertList(head) 24 | now_end_of_prefix = head 25 | now_end_of_prefix.next = self.reverseKGroup(rest_of_list,k) 26 | break 27 | ptr = ptr.next 28 | return ans 29 | 30 | def invertList(self, head: Optional[ListNode]) -> Optional[ListNode]: 31 | if head is None: 32 | return None 33 | if head.next is None: 34 | return head 35 | this = head 36 | nxt = this.next 37 | first = True 38 | while this is not None and nxt is not None: 39 | old_this = this 40 | old_nxt = nxt 41 | this = nxt 42 | nxt = nxt.next 43 | if first: 44 | old_this.next = None 45 | first = False 46 | old_nxt.next = old_this 47 | return this 48 | 49 | def main(): 50 | sol = Solution() 51 | inp = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5, ListNode(6)))))) 52 | ans = sol.reverseKGroup(inp, 2) 53 | list_ans = [] 54 | while ans is not None: 55 | list_ans.append(ans.val) 56 | ans = ans.next 57 | print('Output:', list_ans) 58 | print('Expected:', [2,1,4,3,6,5]) 59 | 60 | if __name__ == "__main__": 61 | main() 62 | -------------------------------------------------------------------------------- /solutions/279. Perfect Squares.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1546 ms, faster than 64.71% of Python3 online submissions for Perfect Squares. 3 | Memory Usage: 205.1 MB, less than 5.05% of Python3 online submissions for Perfect Squares. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def numSquares(self, n: int) -> int: 11 | values = [] 12 | for i in range(1,math.floor(math.sqrt(n))+1): 13 | values.append(i**2) 14 | if n in values: 15 | return 1 16 | steps = 1 17 | attempts = values 18 | while True: 19 | new_attempts = [] 20 | steps += 1 21 | for a in attempts: 22 | for v in values: 23 | if a+v == n: 24 | return steps 25 | elif a+v < n: 26 | new_attempts.append(a+v) 27 | elif a+v > n: 28 | break 29 | attempts = new_attempts 30 | 31 | def main(): 32 | sol = Solution() 33 | print('Output:', sol.numSquares(12)) 34 | print('Expected:', 3) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /solutions/283. Move Zeroes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 5308 ms, faster than 5.00% of Python3 online submissions for Move Zeroes. 3 | Memory Usage: 15.2 MB, less than 98.92% of Python3 online submissions for Move Zeroes. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def moveZeroes(self, nums: List[int]) -> None: 10 | """ 11 | Do not return anything, modify nums in-place instead. 12 | """ 13 | write_zero_at = len(nums)-1 14 | 15 | for i in range(len(nums)): 16 | if nums[len(nums)-1-i] == 0: 17 | write_zero_at = len(nums)-1-i-1 18 | else: 19 | break 20 | i = 0 21 | while i < write_zero_at: 22 | if nums[i] == 0: 23 | for j in range(i+1,write_zero_at+1): 24 | nums[j-1] = nums[j] 25 | nums[write_zero_at] = 0 26 | write_zero_at -= 1 27 | else: 28 | i += 1 29 | 30 | def main(): 31 | sol = Solution() 32 | inp = [0,1,0,3,12] 33 | sol.moveZeroes(inp) 34 | print('Output:', inp) 35 | print('Expected:', [1,3,12,0,0]) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/287. Find the Duplicate Number.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 596 ms, faster than 90.25% of Python3 online submissions for Find the Duplicate Number. 3 | Memory Usage: 31.8 MB, less than 13.84% of Python3 online submissions for Find the Duplicate Number. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findDuplicate(self, nums: List[int]) -> int: 10 | seen = {} 11 | for n in nums: 12 | if n in seen.keys(): 13 | return n 14 | else: 15 | seen[n] = 'a' 16 | 17 | def main(): 18 | sol = Solution() 19 | print('Output:', sol.findDuplicate([1,3,4,2,2])) 20 | print('Expected:', 2) 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /solutions/295. Find Median from Data Stream.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 655 ms, faster than 68.01% of Python3 online submissions for Find Median from Data Stream. 3 | Memory Usage: 36.5 MB, less than 13.49% of Python3 online submissions for Find Median from Data Stream. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import heapq as hq 8 | 9 | class MedianFinder: 10 | 11 | def __init__(self): 12 | self.low = [] 13 | self.high = [] 14 | 15 | def addNum(self, num: int) -> None: 16 | hq.heappush(self.low, -num) 17 | hq.heappush(self.high, -hq.heappop(self.low)) 18 | if len(self.high) > len(self.low): 19 | hq.heappush(self.low, -hq.heappop(self.high)) 20 | 21 | def findMedian(self) -> float: 22 | if len(self.low) > len(self.high): 23 | return -self.low[0] 24 | return (-self.low[0] + self.high[0])/2 25 | 26 | def main(): 27 | obj = MedianFinder() 28 | obj.addNum(1) 29 | obj.addNum(2) 30 | ans_1 = obj.findMedian() 31 | obj.addNum(3) 32 | ans_2 = obj.findMedian() 33 | print('Output:', ans_1, ans_2) 34 | print('Expected:', 1.5, 2) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /solutions/3. Longest Substring Without Repeating Characters.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 84 ms, faster than 38.85% of Python3 online submissions for Longest Substring Without Repeating Characters. 3 | Memory Usage: 14.5 MB, less than 25.40% of Python3 online submissions for Longest Substring Without Repeating Characters. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def lengthOfLongestSubstring(self, s: str) -> int: 10 | s = list(s) 11 | start = 0 12 | length = 0 13 | max_length = 0 14 | for idx, l in enumerate(s): 15 | if l in s[start:idx]: 16 | start = s.index(l, start, idx) + 1 17 | length = len(s[start:idx]) + 1 18 | else: 19 | length += 1 20 | if length > max_length: 21 | max_length = length 22 | return max_length 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.lengthOfLongestSubstring("abcabcbb")) 27 | print('Expected:', 3) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/300. Longest Increasing Subsequence.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 88 ms, faster than 92.41% of Python3 online submissions for Longest Increasing Subsequence. 3 | Memory Usage: 14.4 MB, less than 32.18% of Python3 online submissions for Longest Increasing Subsequence. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def lengthOfLIS(self, nums: List[int]) -> int: 10 | sequence = [] 11 | for val in nums: 12 | pos = self.insert(sequence, val) 13 | if pos == len(sequence): 14 | sequence.append(val) 15 | else: 16 | sequence[pos] = val 17 | return len(sequence) 18 | 19 | def insert(self, subseq, val): 20 | lo = 0 21 | hi = len(subseq)-1 22 | while lo <= hi: 23 | mid = lo + (hi-lo)//2 24 | if val > subseq[mid]: 25 | lo = mid + 1 26 | elif val < subseq[mid]: 27 | hi = mid - 1 28 | elif val == subseq[mid]: 29 | return mid 30 | return lo 31 | 32 | def main(): 33 | sol = Solution() 34 | print('Output:', sol.lengthOfLIS([10,9,2,5,3,7,101,18])) 35 | print('Expected:', 4) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/31. Next Permutation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 48 ms, faster than 72.20% of Python3 online submissions for Next Permutation. 3 | Memory Usage: 13.9 MB, less than 89.21% of Python3 online submissions for Next Permutation. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def nextPermutation(self, nums: List[int]) -> None: 10 | """ 11 | Do not return anything, modify nums in-place instead. 12 | """ 13 | for i in range(len(nums)-1, -1, -1): 14 | if i == 0: 15 | nums[:] = nums[:][::-1] 16 | break 17 | elif nums[i] > nums[i-1]: 18 | target_idx = i 19 | for j in range(len(nums[i:])): 20 | if nums[i+j] > nums[i-1]: 21 | target_idx = i+j 22 | elif (i+j+1) == len(nums) or nums[i+j+1] < nums[i-1]: 23 | break 24 | temp = nums[i-1] 25 | nums[i-1] = nums[target_idx] 26 | nums[target_idx] = temp 27 | nums[i:] = nums[i:][::-1] 28 | break 29 | 30 | def main(): 31 | sol = Solution() 32 | nums = [1,1,5] 33 | sol.nextPermutation(nums) 34 | print('Output:', nums) 35 | print('Expected:', [1, 5, 1]) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/32. Longest Valid Parentheses.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 75 ms, faster than 35.53% of Python3 online submissions for Longest Valid Parentheses. 3 | Memory Usage: 14 MB, less than 94.23% of Python3 online submissions for Longest Valid Parentheses. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def longestValidParentheses(self, s: str) -> int: 10 | stack = [0] 11 | longest = 0 12 | for c in s: 13 | if c == '(': 14 | stack.append(0) 15 | else: 16 | if len(stack)>1: 17 | val = stack.pop() 18 | stack[-1] += val + 2 19 | longest = max(longest, stack[-1]) 20 | else: 21 | stack = [0] 22 | return longest 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.longestValidParentheses("()(()")) 27 | print('Expected:', 2) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/322. Coin Change.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 2208 ms, faster than 38.39% of Python3 online submissions for Coin Change. 3 | Memory Usage: 14.1 MB, less than 69.45% of Python3 online submissions for Coin Change. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def coinChange(self, coins: List[int], amount: int) -> int: 11 | num_coins = [0] + [math.inf for i in range(amount)] 12 | for target_val in range(1, amount+1): 13 | for coin_val in coins: 14 | if target_val - coin_val >= 0: 15 | num_coins[target_val] = min(num_coins[target_val], num_coins[target_val-coin_val] + 1) 16 | if num_coins[-1] == math.inf: 17 | return -1 18 | else: 19 | return num_coins[-1] 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:', sol.coinChange([1,2,5], 11)) 24 | print('Expected:', 3) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /solutions/33. Search in Rotated Sorted Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 97.81% of Python3 online submissions for Search in Rotated Sorted Array. 3 | Memory Usage: 14.1 MB, less than 96.40% of Python3 online submissions for Search in Rotated Sorted Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def search(self, nums: List[int], target: int, offset: int=0) -> int: 10 | if len(nums) == 1: 11 | if nums[0] == target: 12 | return offset 13 | else: 14 | return -1 15 | elif len(nums) == 2: 16 | if nums[0] == target: 17 | return offset 18 | elif nums[1] == target: 19 | return offset + 1 20 | else: 21 | return -1 22 | else: 23 | left_start = nums[:len(nums)//2][0] 24 | left_end = nums[:len(nums)//2][-1] 25 | right_start = nums[len(nums)//2:][0] 26 | right_end = nums[len(nums)//2:][-1] 27 | if left_end >= left_start: 28 | rotation_on_left = False 29 | else: 30 | rotation_on_left = True 31 | if right_end >= right_start: 32 | rotation_on_right = False 33 | else: 34 | rotation_on_right = True 35 | if not rotation_on_left and target >= left_start and target <= left_end: 36 | return self.search(nums[:len(nums)//2], target, offset) # L 37 | elif not rotation_on_right and target >= right_start and target <= right_end: 38 | return self.search(nums[len(nums)//2:], target, offset+len(nums)//2) #R 39 | elif rotation_on_left and (target > right_end or target < right_start): 40 | return self.search(nums[:len(nums)//2], target, offset) # L 41 | else: 42 | return self.search(nums[len(nums)//2:], target, offset+len(nums)//2) #R 43 | 44 | def main(): 45 | sol = Solution() 46 | print('Output:', sol.search([4,5,6,7,0,1,2], 0)) 47 | print('Expected:', 4) 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /solutions/338. Counting Bits.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 107 ms, faster than 68.02% of Python3 online submissions for Counting Bits. 3 | Memory Usage: 20.7 MB, less than 83.65% of Python3 online submissions for Counting Bits. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def countBits(self, n: int) -> List[int]: 11 | if n == 0: 12 | return [0] 13 | else: 14 | ans = [0, 1] 15 | for i in range(int(math.log2(n))): 16 | ans = ans + [i+1 for i in ans] 17 | return ans[:n+1] 18 | 19 | def main(): 20 | sol = Solution() 21 | print('Output:', sol.countBits(5)) 22 | print('Expected:', [0,1,1,2,1,2]) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /solutions/347. Top K Frequent Elements.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 108 ms, faster than 42.41% of Python3 online submissions for Top K Frequent Elements. 3 | Memory Usage: 18.8 MB, less than 38.77% of Python3 online submissions for Top K Frequent Elements. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def topKFrequent(self, nums: List[int], k: int) -> List[int]: 10 | cache = {} 11 | for item in nums: 12 | if item in cache.keys(): 13 | cache[item] += 1 14 | else: 15 | cache[item] = 1 16 | sorted_cache = {k: v for k, v in sorted(cache.items(), key=lambda item: item[1], reverse=True)} 17 | ret = [] 18 | for key, val in sorted_cache.items(): 19 | ret.append(key) 20 | if len(ret) == k: 21 | return ret 22 | 23 | def main(): 24 | sol = Solution() 25 | print('Output:', sol.topKFrequent([1,1,1,2,2,3], 2)) 26 | print('Expected:', [1,2]) 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /solutions/35. Search Insert Position.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 48 ms, faster than 79.03% of Python3 online submissions for Search Insert Position. 3 | Memory Usage: 15.3 MB, less than 24.33% of Python3 online submissions for Search Insert Position. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def searchInsert(self, nums: List[int], target: int) -> int: 10 | search_in = nums 11 | base = 0 12 | if target < nums[0]: 13 | return 0 14 | elif target > nums[len(nums)-1]: 15 | return len(nums) 16 | else: 17 | while len(search_in) > 0: 18 | left = search_in[:len(search_in)//2] 19 | right = search_in[len(search_in)//2:] 20 | if target == search_in[len(search_in)//2]: 21 | return base + len(search_in)//2 22 | elif target < search_in[len(search_in)//2] and target > search_in[len(search_in)//2 - 1]: 23 | return base + len(search_in)//2 24 | elif target < search_in[len(search_in)//2]: 25 | search_in = left 26 | elif target > search_in[len(search_in)//2]: 27 | base += len(left) 28 | search_in = right 29 | return base 30 | 31 | def main(): 32 | sol = Solution() 33 | print('Output:', sol.searchInsert([1,3,5,6], 5)) 34 | print('Expected:', 2) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /solutions/39. Combination Sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1116 ms, faster than 5.04% of Python3 online submissions for Combination Sum. 3 | Memory Usage: 15.1 MB, less than 6.27% of Python3 online submissions for Combination Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: 10 | ret = [] 11 | candidates = sorted(candidates) 12 | for i in candidates: 13 | if i > target: 14 | continue 15 | elif i == target: 16 | ret.append([i]) 17 | else: 18 | lists = [[i]] 19 | while len(lists) > 0: 20 | new_lists = [] 21 | for l in lists: 22 | for j in range(0,len(candidates)): 23 | temp_list = l + [candidates[j]] 24 | temp_list = sorted(temp_list) 25 | if sum(temp_list) == target: 26 | if temp_list not in ret: 27 | ret.append(temp_list) 28 | elif sum(temp_list) < target: 29 | new_lists.append(temp_list) 30 | lists = new_lists 31 | return ret 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.combinationSum([2,3,6,7], 7)) 36 | print('Expected:', [[2,2,3],[7]]) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/394. Decode String.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 61.05% of Python3 online submissions for Decode String. 3 | Memory Usage: 14.5 MB, less than 19.91% of Python3 online submissions for Decode String. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def decodeString(self, s: str) -> str: 10 | while True: 11 | no_par = True 12 | for idx, c in enumerate(s): 13 | exit = False 14 | if c == ']': 15 | no_par = False 16 | start = idx 17 | while True: 18 | if s[start] == '[': 19 | init_num = start 20 | while True: 21 | init_num -= 1 22 | if not s[init_num].isnumeric(): 23 | init_num += 1 24 | break 25 | repetitions = int(s[init_num:start]) 26 | replacement = '' 27 | for i in range(repetitions): 28 | replacement += s[start+1:idx] 29 | new_s = s[:init_num] + replacement + s[idx+1:] 30 | exit = True 31 | break 32 | start -= 1 33 | if exit: 34 | start = 0 35 | s = new_s 36 | break 37 | if no_par: 38 | break 39 | return s 40 | 41 | def main(): 42 | sol = Solution() 43 | print('Output:', sol.decodeString("3[a2[c]]")) 44 | print('Expected:', "accaccacc") 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /solutions/4. Median of Two Sorted Arrays.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 158 ms, faster than 31.95% of Python3 online submissions for Median of Two Sorted Arrays. 3 | Memory Usage: 14.1 MB, less than 79.59% of Python3 online submissions for Median of Two Sorted Arrays. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: 10 | merge = [] 11 | i, j = 0, 0 12 | while i < len(nums1) or j < len(nums2): 13 | if i == len(nums1): 14 | merge.append(nums2[j]) 15 | j += 1 16 | elif j == len(nums2): 17 | merge.append(nums1[i]) 18 | i += 1 19 | elif nums1[i] < nums2[j]: 20 | merge.append(nums1[i]) 21 | i += 1 22 | else: 23 | merge.append(nums2[j]) 24 | j += 1 25 | return self.findMedian(merge) 26 | 27 | def findMedian(self, nums: List[int]) -> float: 28 | if len(nums)%2==0: 29 | return (nums[len(nums)//2-1] + nums[len(nums)//2])/2 30 | else: 31 | return nums[len(nums)//2] 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.findMedianSortedArrays([1,2,4,7,8], [2,3,8])) 36 | print('Expected:', 3.5) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/41. First Missing Positive.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 864 ms, faster than 94.50% of Python3 online submissions for First Missing Positive. 3 | Memory Usage: 77.2 MB, less than 6.99% of Python3 online submissions for First Missing Positive. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def firstMissingPositive(self, nums: List[int]) -> int: 10 | cache = {} 11 | for n in nums: 12 | cache[n] = True 13 | for val in range(1,len(nums)+2): 14 | if val in cache.keys(): 15 | continue 16 | else: 17 | return val 18 | 19 | def main(): 20 | sol = Solution() 21 | print('Output:', sol.firstMissingPositive([7,8,9,11,12])) 22 | print('Expected:', 1) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /solutions/416. Partition Equal Subset Sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 458 ms, faster than 81.17% of Python3 online submissions for Partition Equal Subset Sum. 3 | Memory Usage: 14.3 MB, less than 80.86% of Python3 online submissions for Partition Equal Subset Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def canPartition(self, nums: List[int]) -> bool: 10 | if sum(nums)%2 != 0 or len(nums)<2: 11 | return False 12 | target = sum(nums)//2 13 | sums = {} 14 | sums[0] = True 15 | for i in range(len(nums)): 16 | if target-nums[i] in sums.keys(): 17 | return True 18 | else: 19 | new_sums = {} 20 | for k in sums.keys(): 21 | new_sums[k] = True 22 | if k+nums[i] < target: 23 | new_sums[k+nums[i]] = True 24 | sums = new_sums 25 | return False 26 | 27 | def main(): 28 | sol = Solution() 29 | print('Output:', sol.canPartition([1,5,11,5])) 30 | print('Expected:', True) 31 | 32 | if __name__ == "__main__": 33 | main() -------------------------------------------------------------------------------- /solutions/42. Trapping Rain Water.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 120 ms, faster than 63.33% of Python3 online submissions for Trapping Rain Water. 3 | Memory Usage: 16 MB, less than 15.76% of Python3 online submissions for Trapping Rain Water. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def trap(self, height: List[int]) -> int: 10 | highest_left = [0]*len(height) 11 | highest_right = [0]*len(height) 12 | temp_hi = 0 13 | for i in range(len(height)): 14 | highest_left[i] = temp_hi 15 | temp_hi = max(temp_hi, height[i]) 16 | temp_hi = 0 17 | for i in range(len(height)): 18 | highest_right[len(height)-i-1] = temp_hi 19 | temp_hi = max(temp_hi, height[len(height)-i-1]) 20 | rain = [0]*len(height) 21 | for i in range(len(height)): 22 | rain[i] = max(0,min(highest_left[i], highest_right[i])-height[i]) 23 | return sum(rain) 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.trap([0,1,0,2,1,0,1,3,2,1,2,1])) 28 | print('Expected:', 6) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /solutions/437. Path Sum III.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 689 ms, faster than 26.71% of Python3 online submissions for Path Sum III. 3 | Memory Usage: 15.4 MB, less than 51.69% of Python3 online submissions for Path Sum III. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def __init__(self): 16 | self.counter = 0 17 | self.path = [] 18 | self.sums_up_to = [] 19 | 20 | def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int: 21 | if root is not None: 22 | self.path.append(root.val) 23 | for i in range(len(self.sums_up_to)): 24 | self.sums_up_to[i] += root.val 25 | self.sums_up_to.append(root.val) 26 | for i in range(len(self.sums_up_to)): 27 | if self.sums_up_to[i]==targetSum: 28 | self.counter += 1 29 | self.pathSum(root.left, targetSum) 30 | self.pathSum(root.right, targetSum) 31 | self.path.pop() 32 | for i in range(len(self.sums_up_to)): 33 | self.sums_up_to[i] -= self.sums_up_to[-1] 34 | self.sums_up_to.pop() 35 | return self.counter 36 | 37 | def main(): 38 | sol = Solution() 39 | inp = TreeNode(10, TreeNode(5, TreeNode(3, TreeNode(3, TreeNode(-2))), TreeNode(2, None, TreeNode(1))), TreeNode(-3, None, TreeNode(11))) 40 | print('Output:', sol.pathSum(inp, 8)) 41 | print('Expected:', 3) 42 | 43 | if __name__ == "__main__": 44 | main() -------------------------------------------------------------------------------- /solutions/438. Find All Anagrams in a String.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 204 ms, faster than 55.01% of Python3 online submissions for Find All Anagrams in a String. 3 | Memory Usage: 15.5 MB, less than 6.71% of Python3 online submissions for Find All Anagrams in a String. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.cache = {} 11 | 12 | def findAnagrams(self, s: str, p: str) -> List[int]: 13 | for ch in p: 14 | if ch in self.cache.keys(): 15 | self.cache[ch] += 1 16 | else: 17 | self.cache[ch] = 1 18 | ans = [] 19 | for i in range(len(s)-len(p)+1): 20 | if i == 0: 21 | for ch in s[i:i+len(p)]: 22 | if ch in self.cache.keys(): 23 | self.cache[ch] -= 1 24 | else: 25 | if s[i-1] in self.cache.keys(): 26 | self.cache[s[i-1]] += 1 27 | if s[i+len(p)-1] in self.cache.keys(): 28 | self.cache[s[i+len(p)-1]] -= 1 29 | if self.check(): 30 | ans.append(i) 31 | return ans 32 | 33 | def check(self) -> bool: 34 | if all(v==0 for v in self.cache.values()): 35 | return True 36 | return False 37 | 38 | def main(): 39 | sol = Solution() 40 | print('Output:', sol.findAnagrams("cbaebabacd", "abc")) 41 | print('Expected:', [0, 6]) 42 | 43 | if __name__ == "__main__": 44 | main() -------------------------------------------------------------------------------- /solutions/448. Find All Numbers Disappeared in an Array.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 352 ms, faster than 61.54% of Python3 online submissions for Find All Numbers Disappeared in an Array. 3 | Memory Usage: 22.2 MB, less than 58.46% of Python3 online submissions for Find All Numbers Disappeared in an Array. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def findDisappearedNumbers(self, nums: List[int]) -> List[int]: 10 | ret = [] 11 | ret2 = [] 12 | for i in range(len(nums)): 13 | ret.append(i+1) 14 | for i in range(len(nums)): 15 | ret[nums[i]-1] = 0 16 | for i in range(len(ret)): 17 | if ret[i] != 0: 18 | ret2.append(ret[i]) 19 | return ret2 20 | 21 | def main(): 22 | sol = Solution() 23 | print('Output:', sol.findDisappearedNumbers([4,3,2,7,8,2,3,1])) 24 | print('Expected:', [5,6]) 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /solutions/45. Jump Game II.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 2413 ms, faster than 31.09% of Python3 online submissions for Jump Game II. 3 | Memory Usage: 15.2 MB, less than 48.71% of Python3 online submissions for Jump Game II. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | 10 | def jump(self, nums: List[int]) -> int: 11 | if len(nums) <= 1: 12 | return 0 13 | steps = 0 14 | earliest_idx = -1 15 | while earliest_idx != 0: 16 | steps += 1 17 | l = len(nums) 18 | for i in range(l): 19 | if nums[i] >= (l-1-i): 20 | earliest_idx = i 21 | break 22 | nums = nums[:earliest_idx+1] 23 | return steps 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.jump([2,3,1,1,4])) 28 | print('Expected:', 2) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /solutions/46. Permutations.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 44 ms, faster than 44.87% of Python3 online submissions for Permutations. 3 | Memory Usage: 14.4 MB, less than 45.94% of Python3 online submissions for Permutations. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def permute(self, nums: List[int]) -> List[List[int]]: 10 | if len(nums) == 1: 11 | return [[nums[0]]] 12 | else: 13 | ret = [] 14 | for i in range(len(nums)): 15 | init = nums[i] 16 | per_of_rest = self.permute(self.removeJth(nums,i)) 17 | for per in per_of_rest: 18 | ret.append([init]+per) 19 | return ret 20 | 21 | def removeJth(self, nums: List[int], j: int) -> List[int]: 22 | if len(nums) <= 1: 23 | return [] 24 | else: 25 | return nums[:j] + nums[j+1:] 26 | 27 | def main(): 28 | sol = Solution() 29 | print('Output:', sol.permute([1,2,3])) 30 | print('Expected:', [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]) 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /solutions/48. Rotate Image.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 67.35% of Python3 online submissions for Rotate Image. 3 | Memory Usage: 14.3 MB, less than 60.70% of Python3 online submissions for Rotate Image. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def rotate(self, matrix: List[List[int]]) -> None: 10 | """ 11 | Do not return anything, modify matrix in-place instead. 12 | """ 13 | N = len(matrix) 14 | for i in range(N): 15 | for j in range(i,N): 16 | matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] 17 | for i in range(N): 18 | matrix[i].reverse() 19 | 20 | def main(): 21 | sol = Solution() 22 | inp = [[1,2,3],[4,5,6],[7,8,9]] 23 | sol.rotate(inp) 24 | print('Output:', inp) 25 | print('Expected:', [[7,4,1],[8,5,2],[9,6,3]]) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /solutions/49. Group Anagrams.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 8116 ms, faster than 5.00% of Python3 online submissions for Group Anagrams. 3 | Memory Usage: 17.7 MB, less than 57.79% of Python3 online submissions for Group Anagrams. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def groupAnagrams(self, strs: List[str]) -> List[List[str]]: 10 | sorted_strs = [] 11 | idx = [] 12 | for i, s in enumerate(strs): 13 | sorted_strs.append(self.generateHash(s)) 14 | idx.append(i) 15 | ret = [] 16 | while len(idx) > 0: 17 | temp = [strs[idx[0]]] 18 | new_idx = [] 19 | for q, i in enumerate(idx[1:]): 20 | if sorted_strs[idx[0]] == sorted_strs[i]: 21 | temp.append(strs[i]) 22 | else: 23 | new_idx.append(i) 24 | idx = new_idx 25 | ret.append(temp) 26 | return ret 27 | 28 | def generateHash(self, string): 29 | prod = 1 30 | sum = 0 31 | for i in string: 32 | prod *=ord(i) 33 | sum +=ord(i) 34 | return prod + sum 35 | 36 | def main(): 37 | sol = Solution() 38 | print('Output:', sol.groupAnagrams(["eat","tea","tan","ate","nat","bat"])) 39 | print('Expected:', [["bat"],["nat","tan"],["ate","eat","tea"]]) 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /solutions/494. Target Sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 527 ms, faster than 33.49% of Python3 online submissions for Target Sum. 3 | Memory Usage: 15.1 MB, less than 51.66% of Python3 online submissions for Target Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.cache = {} 11 | 12 | def findTargetSumWays(self, nums: List[int], target: int, idx: int=0) -> int: 13 | if (target, idx) in self.cache.keys(): 14 | return self.cache[(target, idx)] 15 | ans = 0 16 | if len(nums[idx:])==1: 17 | if nums[idx]==target: 18 | ans += 1 19 | if nums[idx]==-target: 20 | ans +=1 21 | return ans 22 | else: 23 | v1 = self.findTargetSumWays(nums, target-nums[idx], idx+1) 24 | self.cache[(target-nums[idx], idx+1)] = v1 25 | v2 = self.findTargetSumWays(nums, target+nums[idx], idx+1) 26 | self.cache[(target+nums[idx], idx+1)] = v2 27 | return v1 + v2 28 | 29 | def main(): 30 | sol = Solution() 31 | print('Output:', sol.findTargetSumWays([1,1,1,1,1], 3)) 32 | print('Expected:', 5) 33 | 34 | if __name__ == "__main__": 35 | main() 36 | -------------------------------------------------------------------------------- /solutions/5. Longest Palindromic Substring.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 3055 ms, faster than 27.68% of Python3 online submissions for Longest Palindromic Substring. 3 | Memory Usage: 14.5 MB, less than 35.37% of Python3 online submissions for Longest Palindromic Substring. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def longestPalindrome(self, s: str) -> str: 10 | max_pal = s[0] 11 | for idx, char in enumerate(list(s)): 12 | temp_pal = char 13 | start = idx 14 | end = idx 15 | while True: 16 | start -= 1 17 | end += 1 18 | if (start < 0) or (end >= len(s)) or (s[start] != s[end]): 19 | break 20 | else: 21 | temp_pal = s[start:end+1] 22 | if len(temp_pal) > len(max_pal): 23 | max_pal = temp_pal 24 | start = idx + 1 25 | end = idx 26 | while True: 27 | start -= 1 28 | end += 1 29 | if (start < 0) or (end >= len(s)) or (s[start] != s[end]): 30 | break 31 | else: 32 | temp_pal = s[start:end+1] 33 | if len(temp_pal) > len(max_pal): 34 | max_pal = temp_pal 35 | return max_pal 36 | 37 | def main(): 38 | sol = Solution() 39 | print('Output:', sol.longestPalindrome("babad")) 40 | print('Expected:', "bab") 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /solutions/53. Maximum Subarray.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 672 ms, faster than 95.54% of Python3 online submissions for Maximum Subarray. 3 | Memory Usage: 28.8 MB, less than 33.53% of Python3 online submissions for Maximum Subarray. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maxSubArray(self, nums: List[int]) -> int: 10 | running_sum = nums[0] 11 | max_sum = running_sum 12 | for i in range(1,len(nums)): 13 | if max_sum < 0 and nums[i] > max_sum: 14 | running_sum = nums[i] 15 | max_sum = running_sum 16 | elif running_sum + nums[i] <= 0: 17 | running_sum = 0 18 | else: 19 | running_sum += nums[i] 20 | if running_sum > max_sum: 21 | max_sum = running_sum 22 | return max_sum 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.maxSubArray([-2,1,-3,4,-1,2,1,-5,4])) 27 | print('Expected:', 6) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/543. Diameter of Binary Tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 472 ms, faster than 6.80% of Python3 online submissions for Diameter of Binary Tree. 3 | Memory Usage: 16 MB, less than 93.37% of Python3 online submissions for Diameter of Binary Tree. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int: 16 | if (root is None) or (root.left is None and root.right is None): 17 | return 0 18 | elif root.left is None: 19 | return max(self.diameterOfBinaryTree(root.right), self.depthOfBinaryTree(root.right)+1) 20 | elif root.right is None: 21 | return max(self.diameterOfBinaryTree(root.left), self.depthOfBinaryTree(root.left) + 1) 22 | else: 23 | l_dia = self.diameterOfBinaryTree(root.left) 24 | r_dia = self.diameterOfBinaryTree(root.right) 25 | l_dep = self.depthOfBinaryTree(root.left) 26 | r_dep = self.depthOfBinaryTree(root.right) 27 | choices = [l_dia, r_dia, l_dep + r_dep + 2] 28 | return max(choices) 29 | 30 | def depthOfBinaryTree(self, root: Optional[TreeNode]) -> int: 31 | if (root is None) or (root.left is None and root.right is None): 32 | return 0 33 | elif root.left is None: 34 | return self.depthOfBinaryTree(root.right) + 1 35 | elif root.right is None: 36 | return self.depthOfBinaryTree(root.left) + 1 37 | else: 38 | max_d = max(self.depthOfBinaryTree(root.right), self.depthOfBinaryTree(root.left)) 39 | return max_d + 1 40 | 41 | def main(): 42 | sol = Solution() 43 | t = TreeNode(1, TreeNode(2, TreeNode(4), TreeNode(5)), TreeNode(3)) 44 | print('Output:', sol.diameterOfBinaryTree(t)) 45 | print('Expected:', 3) 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /solutions/55. Jump Game.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 536 ms, faster than 76.84% of Python3 online submissions for Jump Game. 3 | Memory Usage: 15.2 MB, less than 62.63% of Python3 online submissions for Jump Game. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def canJump(self, nums: List[int]) -> bool: 10 | length = len(nums) 11 | if len(nums) <= 1: 12 | return True 13 | for i in range(length): 14 | if nums[i] >= length-i-1: 15 | return True 16 | if nums[i] == 0: 17 | preceedings = nums[:i] 18 | not_found = True 19 | for j in range(i): 20 | if preceedings[j] > (i-j): 21 | not_found = False 22 | break 23 | if not_found: 24 | return False 25 | return True 26 | 27 | def main(): 28 | sol = Solution() 29 | print('Output:', sol.canJump([4,2,0,0,1,1,4,4,4,0,4,0])) 30 | print('Expected:', True) 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /solutions/56. Merge Intervals.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 136 ms, faster than 99.03% of Python3 online submissions for Merge Intervals. 3 | Memory Usage: 18.8 MB, less than 25.39% of Python3 online submissions for Merge Intervals. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def merge(self, intervals: List[List[int]]) -> List[List[int]]: 10 | intervals = sorted(intervals, key=lambda x: x[0]) 11 | ans = [] 12 | current_start = intervals[0][0] 13 | current_end = intervals[0][1] 14 | for val in intervals[1:]: 15 | if val[0] <= current_end: 16 | current_end = max(current_end, val[1]) 17 | else: 18 | ans.append([current_start, current_end]) 19 | current_start = val[0] 20 | current_end = val[1] 21 | ans.append([current_start, current_end]) 22 | return ans 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.merge([[1,3],[2,6],[8,10],[15,18]])) 27 | print('Expected:', [[1,6],[8,10],[15,18]]) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/560. Subarray Sum Equals K.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 4308 ms, faster than 16.57% of Python3 online submissions for Two Sum. 3 | Memory Usage: 14.9 MB, less than 65.12% of Python3 online submissions for Two Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def subarraySum(self, nums: List[int], k: int) -> int: 10 | ans = 0 11 | sum_before_current = 0 12 | num_paths_to_sum = {} 13 | num_paths_to_sum[0] = 1 14 | for i in range(len(nums)): 15 | current_sum = sum_before_current + nums[i] 16 | if current_sum-k in num_paths_to_sum.keys(): 17 | ans = ans + num_paths_to_sum[current_sum-k] 18 | if current_sum not in num_paths_to_sum.keys(): 19 | num_paths_to_sum[current_sum] = 1 20 | else: 21 | num_paths_to_sum[current_sum] = num_paths_to_sum[current_sum]+1 22 | sum_before_current = current_sum 23 | return ans 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.subarraySum([1, 1, 1], 2)) 28 | print('Expected:', 2) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /solutions/617. Merge Two Binary Trees.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 76 ms, faster than 98.05% of Python3 online submissions for Merge Two Binary Trees. 3 | Memory Usage: 15.6 MB, less than 28.24% of Python3 online submissions for Merge Two Binary Trees. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: 16 | if root1 is None: 17 | return root2 18 | elif root2 is None: 19 | return root1 20 | else: 21 | return TreeNode(root1.val + root2.val, self.mergeTrees(root1.left, root2.left), self.mergeTrees(root1.right, root2.right)) 22 | 23 | def main(): 24 | sol = Solution() 25 | t1 = TreeNode(1, TreeNode(3, TreeNode(5)), TreeNode(2)) 26 | t2 = TreeNode(2, TreeNode(1, None, TreeNode(4)), TreeNode(3, None, TreeNode(7))) 27 | ans = sol.mergeTrees(t1, t2) 28 | list_ans = [] 29 | ptrs = [ans] 30 | while len(ptrs) > 0: 31 | new_ptrs = [] 32 | for p in ptrs: 33 | if p is not None: 34 | list_ans.append(p.val) 35 | new_ptrs.append(p.left) 36 | new_ptrs.append(p.right) 37 | ptrs = new_ptrs 38 | print('Output:', list_ans) 39 | print('Expected:', [3,4,5,5,4,7]) 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /solutions/62. Unique Paths.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 36 ms, faster than 26.38% of Python3 online submissions for Unique Paths. 3 | Memory Usage: 14.2 MB, less than 66.78% of Python3 online submissions for Unique Paths. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def uniquePaths(self, m: int, n: int) -> int: 10 | x_max = n-1 11 | y_max = m-1 12 | nodes_at_dist = [[0,0]] 13 | counters = [1] 14 | dist = x_max + y_max 15 | num_paths = 0 16 | d = 1 17 | while d <= dist + 1: 18 | temp = [] 19 | temp_cnt = [] 20 | if d == dist + 1: 21 | return counters[0] 22 | for n_idx, n in enumerate(nodes_at_dist): 23 | if n[0]+1 <= x_max: 24 | nxt = [n[0]+1, n[1]] 25 | if not nxt in temp: 26 | temp.append(nxt) 27 | temp_cnt.append(counters[n_idx]) 28 | else: 29 | j = temp.index(nxt) 30 | temp_cnt[j] += counters[n_idx] 31 | if n[1]+1 <= y_max: 32 | nxt = [n[0], n[1]+1] 33 | if not nxt in temp: 34 | temp.append(nxt) 35 | temp_cnt.append(counters[n_idx]) 36 | else: 37 | j = temp.index(nxt) 38 | temp_cnt[j] += counters[n_idx] 39 | nodes_at_dist = temp 40 | counters = temp_cnt 41 | d += 1 42 | 43 | def main(): 44 | sol = Solution() 45 | print('Output:', sol.uniquePaths(3,7)) 46 | print('Expected:', 28) 47 | 48 | if __name__ == "__main__": 49 | main() 50 | -------------------------------------------------------------------------------- /solutions/647. Palindromic Substrings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1016 ms, faster than 5.76% of Python3 online submissions for Palindromic Substrings. 3 | Memory Usage: 14.2 MB, less than 67.80% of Python3 online submissions for Palindromic Substrings. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def countSubstrings(self, s: str) -> int: 10 | counter = 0 11 | for i in range(len(s)): 12 | for j in range(i,len(s)): 13 | this = s[i:j+1] 14 | if self.palindromeCheck(this): 15 | counter += 1 16 | return counter 17 | 18 | def palindromeCheck(self, s: str) -> bool: 19 | if len(s) == 1: 20 | return True 21 | else: 22 | if len(s)%2 == 0: 23 | first_half = s[:int(len(s)//2)] 24 | second_half = s[int(len(s)//2):] 25 | else: 26 | first_half = s[:int(len(s)//2)] 27 | second_half = s[int(len(s)//2)+1:] 28 | if first_half == second_half[::-1]: 29 | return True 30 | else: 31 | return False 32 | 33 | def main(): 34 | sol = Solution() 35 | print('Output:', sol.countSubstrings("abc")) 36 | print('Expected:', 3) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /solutions/70. Climbing Stairs.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 62.49% of Python3 online submissions for Climbing Stairs. 3 | Memory Usage: 14.3 MB, less than 44.55% of Python3 online submissions for Climbing Stairs. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | cache = {} 10 | def climbStairs(self, n: int) -> int: 11 | if n == 1: 12 | return 1 13 | elif n == 2: 14 | return 2 15 | else: 16 | if str(n-2) not in self.cache: 17 | self.cache[str(n-2)] = self.climbStairs(n-2) 18 | if str(n-1) not in self.cache: 19 | self.cache[str(n-1)] = self.climbStairs(n-1) 20 | return self.cache[str(n-2)] + self.cache[str(n-1)] 21 | 22 | def main(): 23 | sol = Solution() 24 | print('Output:', sol.climbStairs(2)) 25 | print('Expected:', 2) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /solutions/72. Edit Distance.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 4308 ms, faster than 16.57% of Python3 online submissions for Two Sum. 3 | Memory Usage: 14.9 MB, less than 65.12% of Python3 online submissions for Two Sum. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def __init__(self): 10 | self.cache = {} 11 | 12 | def minDistance(self, word1: str, word2: str) -> int: 13 | if (word1, word2) in self.cache.keys(): 14 | return self.cache[(word1, word2)] 15 | ans = -1 16 | if word1 == '' and word2 == '': 17 | ans = 0 18 | elif word1 == '': 19 | ans = len(word2) 20 | elif word2 == '': 21 | ans = len(word1) 22 | elif word1[0] == word2[0]: 23 | ans = self.minDistance(word1[1:], word2[1:]) 24 | else: 25 | insert = self.minDistance(word1, word2[1:]) 26 | delete = self.minDistance(word1[1:], word2) 27 | replace = self.minDistance(word1[1:], word2[1:]) 28 | ans = min([insert, replace, delete]) + 1 29 | self.cache[(word1, word2)] = ans 30 | return ans 31 | 32 | def main(): 33 | sol = Solution() 34 | print('Output:', sol.minDistance("horse", "ros")) 35 | print('Expected:', 3) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/739. Daily Temperatures.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1368 ms, faster than 23.12% of Python3 online submissions for Daily Temperatures. 3 | Memory Usage: 25.8 MB, less than 23.67% of Python3 online submissions for Daily Temperatures. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def dailyTemperatures(self, temperatures: List[int]) -> List[int]: 10 | ret = [0] * len(temperatures) 11 | stack = [] 12 | for idx, t in enumerate(temperatures): 13 | if idx == 0: stack.append([idx, t]) 14 | elif len(stack) == 0 or t <= stack[-1][1]: 15 | stack.append([idx, t]) 16 | else: 17 | popped = 0 18 | while len(stack) > 0 and t > stack[-1][1]: 19 | p = stack.pop() 20 | popped += 1 21 | ret[p[0]] = idx - p[0] 22 | stack.append([idx, t]) 23 | return ret 24 | 25 | def main(): 26 | sol = Solution() 27 | print('Output:', sol.dailyTemperatures([73,74,75,71,69,72,76,73])) 28 | print('Expected:', [1,1,4,2,1,1,0,0]) 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /solutions/74. Search a 2D Matrix.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 56 ms, faster than 64.54% of Python3 online submissions for Search a 2D Matrix. 3 | Memory Usage: 14.4 MB, less than 69.06% of Python3 online submissions for Search a 2D Matrix. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: 10 | row, column = 0, 0 11 | while True: 12 | val = matrix[row][column] 13 | if val == target: 14 | return True 15 | if row < len(matrix)-1 or column < len(matrix[0])-1: 16 | if row < len(matrix)-1 and target >= matrix[row+1][0]: 17 | row += 1 18 | elif column < len(matrix[0])-1: 19 | column += 1 20 | else: 21 | break 22 | else: 23 | break 24 | return False 25 | 26 | def main(): 27 | sol = Solution() 28 | print('Output:', sol.searchMatrix([[1,3,5,7],[10,11,16,20],[23,30,34,60]], 3)) 29 | print('Expected:', True) 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /solutions/75. Sort Colors.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 32 ms, faster than 76.36% of Python3 online submissions for Sort Colors. 3 | Memory Usage: 14.1 MB, less than 92.21% of Python3 online submissions for Sort Colors. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def sortColors(self, nums: List[int]) -> None: 10 | """ 11 | Do not return anything, modify nums in-place instead. 12 | """ 13 | zeros = nums.count(0) 14 | ones = nums.count(1) 15 | twos = nums.count(2) 16 | nums[:zeros] = [0] * zeros 17 | nums[zeros:ones] = [1] * ones 18 | nums[zeros+ones:] = [2] * twos 19 | 20 | def main(): 21 | sol = Solution() 22 | inp = [2,0,2,1,1,0] 23 | sol.sortColors(inp) 24 | print('Output:', inp) 25 | print('Expected:', [0,0,1,1,2,2]) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /solutions/76. Minimum Window Substring.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 104 ms, faster than 89.46% of Python3 online submissions for Minimum Window Substring. 3 | Memory Usage: 14.8 MB, less than 45.43% of Python3 online submissions for Minimum Window Substring. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def minWindow(self, s: str, t: str) -> str: 10 | t_counters = {} 11 | for c in t: 12 | if c not in t_counters.keys(): 13 | t_counters[c] = 1 14 | else: 15 | t_counters[c] += 1 16 | start = 0 17 | end = 0 18 | min_window = '' 19 | target_len = len(t) 20 | for end in range(len(s)): 21 | if s[end] in t_counters.keys() and t_counters[s[end]] > 0: 22 | target_len -= 1 23 | if s[end] in t_counters.keys(): 24 | t_counters[s[end]] -= 1 25 | while target_len == 0: 26 | window_len = end - start + 1 27 | if not min_window or window_len < len(min_window): 28 | min_window = s[start:end+1] 29 | if s[start] in t_counters.keys(): 30 | t_counters[s[start]] += 1 31 | if s[start] in t_counters.keys() and t_counters[s[start]] > 0: 32 | target_len += 1 33 | start+=1 34 | return min_window 35 | 36 | def main(): 37 | sol = Solution() 38 | print('Output:', sol.minWindow("ADOBECODEBANC", "ABC")) 39 | print('Expected:', "BANC") 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /solutions/763. Partition Labels.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 332 ms, faster than 5.13% of Python3 online submissions for Partition Labels. 3 | Memory Usage: 14.4 MB, less than 26.01% of Python3 online submissions for Partition Labels. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def partitionLabels(self, s: str) -> List[int]: 10 | ret = [] 11 | part_idx = 1 12 | counter = part_idx 13 | while part_idx < len(s): 14 | looked = s[:part_idx] 15 | looking = s[part_idx:] 16 | if self.contains(looked, looking): 17 | pass 18 | else: 19 | ret.append(counter) 20 | counter = 0 21 | part_idx += 1 22 | counter += 1 23 | ret.append(counter) 24 | return ret 25 | 26 | def contains(self, looked: List[int], looking: List[int]) -> bool: 27 | for i in looked: 28 | if i in looking: 29 | return True 30 | return False 31 | 32 | def main(): 33 | sol = Solution() 34 | print('Output:', sol.partitionLabels("ababcbacadefegdehijhklij")) 35 | print('Expected:', [9,7,8]) 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /solutions/78. Subsets.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 28 ms, faster than 94.84% of Python3 online submissions for Subsets. 3 | Memory Usage: 14.5 MB, less than 19.72% of Python3 online submissions for Subsets. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def subsets(self, nums: List[int]) -> List[List[int]]: 10 | ret = [] 11 | for i in range(2**len(nums)): 12 | val = i 13 | binary = [] 14 | while val > 0: 15 | binary.append(val%2) 16 | val = val // 2 17 | temp = [] 18 | for idx, d in enumerate(binary): 19 | if d == 1: 20 | temp.append(nums[idx]) 21 | ret.append(temp) 22 | return ret 23 | 24 | def main(): 25 | sol = Solution() 26 | print('Output:', sol.subsets([1,2,3])) 27 | print('Expected:', [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/79. Word Search.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 8509 ms, faster than 25.13% of Python3 online submissions for Word Search. 3 | Memory Usage: 14 MB, less than 68.71% of Python3 online submissions for Word Search. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | import math 8 | 9 | class Solution: 10 | def exist(self, board: List[List[str]], word: str) -> bool: 11 | for i in range(len(board)): 12 | for j in range(len(board[0])): 13 | if self.searchFrom(board, i, j, word): 14 | return True 15 | return False 16 | 17 | def searchFrom(self, board: List[List[str]], row: int, col: int, word: str) -> bool: 18 | if len(word) == 0: 19 | return True 20 | if (row >= len(board)) or (row < 0) or (col >= len(board[0])) or (col < 0) or board[row][col] != word[0]: 21 | return False 22 | temp = board[row][col] 23 | board[row][col] = -1 24 | ans = self.searchFrom(board, row+1, col, word[1:]) or \ 25 | self.searchFrom(board, row-1, col, word[1:]) or \ 26 | self.searchFrom(board, row, col+1, word[1:]) or \ 27 | self.searchFrom(board, row, col-1, word[1:]) 28 | board[row][col] = temp 29 | return ans 30 | 31 | def main(): 32 | sol = Solution() 33 | print('Output:', sol.exist([["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], "ABCB")) 34 | print('Expected:', False) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /solutions/84. Largest Rectangle in Histogram.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 1750 ms, faster than 13.66% of Python3 online submissions for Largest Rectangle in Histogram. 3 | Memory Usage: 28.9 MB, less than 24.95% of Python3 online submissions for Largest Rectangle in Histogram. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def largestRectangleArea(self, heights: List[int], start: int=0) -> int: 10 | heights.append(0) 11 | stack = [-1] 12 | ans = 0 13 | for i in range(len(heights)): 14 | while heights[stack[-1]] > heights[i]: 15 | h = heights[stack.pop()] 16 | w = i - stack[-1] - 1 17 | ans = max(ans, h * w) 18 | stack.append(i) 19 | heights.pop() 20 | return ans 21 | 22 | def main(): 23 | sol = Solution() 24 | print('Output:', sol.largestRectangleArea([2,1,5,6,2,3])) 25 | print('Expected:', 10) 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /solutions/85. Maximal Rectangle.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 500 ms, faster than 29.13% of Python3 online submissions for Maximal Rectangle. 3 | Memory Usage: 15.1 MB, less than 92.44% of Python3 online submissions for Maximal Rectangle. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def maximalRectangle(self, matrix: List[List[str]]) -> int: 10 | if len(matrix) == 0: 11 | return 0 12 | rows = len(matrix) 13 | cols = len(matrix[0]) 14 | ones_in_col_up_to_row = [0] * cols 15 | max_area = 0 16 | for r in range(rows): 17 | for c in range(cols): 18 | if matrix[r][c] == '1': 19 | ones_in_col_up_to_row[c] += 1 20 | else: 21 | ones_in_col_up_to_row[c] = 0 22 | max_area = max(max_area, self.maxRectangleUpToRow(ones_in_col_up_to_row)) 23 | return max_area 24 | 25 | def maxRectangleUpToRow(self, heights) -> int: 26 | n = len(heights) 27 | stack = [-1] 28 | max_area = 0 29 | for i in range(n): 30 | while stack[-1] != -1 and heights[stack[-1]] >= heights[i]: 31 | h = heights[stack.pop()] 32 | w = i - stack[-1] - 1 33 | max_area = max(max_area, h*w) 34 | stack.append(i) 35 | while stack[-1] != -1: 36 | h = heights[stack.pop()] 37 | w = n - stack[-1] - 1 38 | max_area = max(max_area, h*w) 39 | return max_area 40 | 41 | def main(): 42 | sol = Solution() 43 | print('Output:', sol.maximalRectangle([["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]])) 44 | print('Expected:', 6) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /solutions/94. Binary Tree Inorder Traversal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 28 ms, faster than 86.44% of Python3 online submissions for Binary Tree Inorder Traversal. 3 | Memory Usage: 14.4 MB, less than 13.97% of Python3 online submissions for Binary Tree Inorder Traversal. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class TreeNode: 9 | def __init__(self, val=0, left=None, right=None): 10 | self.val = val 11 | self.left = left 12 | self.right = right 13 | 14 | class Solution: 15 | def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 16 | if root is None: 17 | return [] 18 | else: 19 | ret = [] 20 | if root.left is not None: 21 | ret.append(self.inorderTraversal(root.left)) 22 | ret.append([root.val]) 23 | if root.right is not None: 24 | ret.append(self.inorderTraversal(root.right)) 25 | ret = [item for sublist in ret for item in sublist] 26 | return ret 27 | 28 | def main(): 29 | sol = Solution() 30 | t = TreeNode(1,None,TreeNode(2,TreeNode(3,None,None),None)) 31 | print('Output:', sol.inorderTraversal(t)) 32 | print('Expected:', [1,3,2]) 33 | 34 | if __name__ == "__main__": 35 | main() 36 | -------------------------------------------------------------------------------- /solutions/96. Unique Binary Search Trees.py: -------------------------------------------------------------------------------- 1 | """ 2 | Runtime: 27 ms, faster than 81.37% of Python3 online submissions for Unique Binary Search Trees. 3 | Memory Usage: 14.3 MB, less than 50.41% of Python3 online submissions for Unique Binary Search Trees. 4 | """ 5 | from typing import List 6 | from typing import Optional 7 | 8 | class Solution: 9 | def numTrees(self, n: int) -> int: 10 | return self.catalanNumber(n) 11 | 12 | def catalanNumber(self, n: int) -> int: 13 | prod = 1 14 | for i in range(2,n+1): 15 | prod *= ((n + i) / i) 16 | return int(round(prod)) 17 | 18 | def main(): 19 | sol = Solution() 20 | print('Output:', sol.numTrees(7)) 21 | print('Expected:', 429) 22 | 23 | if __name__ == "__main__": 24 | main() 25 | --------------------------------------------------------------------------------