├── .DS_Store ├── .gitignore ├── README.md └── python ├── Array ├── 1-bit and 2-bit Characters │ └── 1-bit and 2-bit Characters.py ├── Array Partition I │ └── Array Partition I.py ├── Array Transformation │ └── Array Transformation.py ├── Before and After Puzzle │ └── Before and After Puzzle.py ├── Best Time to Buy and Sell Stock II │ └── Best Time to Buy and Sell Stock II.py ├── Best Time to Buy and Sell Stock │ └── Best Time to Buy and Sell Stock.py ├── Can Make Palindrome from Substring │ └── Can Make Palindrome from Substring.py ├── Cells with Odd Values in a Matrix │ └── Cells with Odd Values in a Matrix.py ├── Check If It Is a Good Array │ └── Check If It Is a Good Array.py ├── Check If It Is a Straight Line │ └── Check If It Is a Straight Line.py ├── Circular Array Loop │ └── Circular Array Loop.py ├── Contains Duplicate │ └── Contains Duplicate.py ├── Count Square Submatrices with All Ones │ └── Count Square Submatrices with All Ones.py ├── Count Substrings with Only One Distinct Letter │ └── Count Substrings with Only One Distinct Letter.py ├── Decrease Elements To Make Array Zigzag │ └── Decrease Elements To Make Array Zigzag.py ├── Degree of an Array │ └── Degree of an Array.py ├── Diet Plan Performance │ └── Diet Plan Performance.py ├── Distance Between Bus Stops │ └── Distance Between Bus Stops.py ├── Duplicate Zeros │ └── Duplicate Zeros.py ├── Fair Candy Swap │ └── Fair Candy Swap.py ├── Fibonacci Number │ └── Fibonacci Number.py ├── Find All Numbers Disappeared in an Array │ └── Find All Numbers Disappeared in an Array.py ├── Find Common Characters │ └── Find Common Characters.py ├── Find Pivot Index │ └── Find Pivot Index.py ├── Get Equal Substrings Within Budget │ └── Get Equal Substrings Within Budget.py ├── Height Checker │ └── Height Checker.py ├── How Many Apples Can You Put into the Basket │ └── How Many Apples Can You Put into the Basket.py ├── Image Smoother │ └── Image Smoother.py ├── Insert Delete GetRandom O(1) - Duplicates allowed │ └── Insert Delete GetRandom O(1) - Duplicates allowed.py ├── Insert Delete GetRandom O(1) │ └── Insert Delete GetRandom O(1).py ├── Interval List Intersections │ └── Interval List Intersections.py ├── Invalid Transactions │ └── Invalid Transactions.py ├── K-Concatenation Maximum Sum │ └── K-Concatenation Maximum Sum.py ├── Largest 1-Bordered Square │ └── Largest 1-Bordered Square.py ├── Last Substring in Lexicographical Order │ └── Last Substring in Lexicographical Order.py ├── Majority Element │ └── Majority Element.py ├── Max Chunks To Make Sorted II │ └── Max Chunks To Make Sorted II.py ├── Max Chunks To Make Sorted │ └── Max Chunks To Make Sorted.py ├── Max Consecutive Ones │ └── Max Consecutive Ones.py ├── Maximum Number of Ones │ └── Maximum Number of Ones.py ├── Maximum Product of Three Numbers │ └── Maximum Product of Three Numbers.py ├── Maximum Subarray Sum with One Deletion │ └── Maximum Subarray Sum with One Deletion.py ├── Maximum Subarray │ └── Maximum Subarray.py ├── Maximum Sum of 3 Non-Overlapping Subarrays │ └── Maximum Sum of 3 Non-Overlapping Subarrays.py ├── Maximum of Absolute Value Expression │ └── Maximum of Absolute Value Expression.py ├── Meeting Scheduler │ └── Meeting Scheduler.py ├── Min Cost Climbing Stairs │ └── Min Cost Climbing Stairs.py ├── Minimum Absolute Difference │ └── Minimum Absolute Difference.py ├── Missing Number In Arithmetic Progression │ └── Missing Number In Arithmetic Progression.py ├── Missing Number │ └── Missing Number.py ├── Monotonic Array │ └── Monotonic Array.py ├── Move Zeroes │ └── Move Zeroes.py ├── N-th Tribonacci Number │ └── N-th Tribonacci Number.py ├── Numbers At Most N Given Digit Set │ └── Numbers At Most N Given Digit Set.py ├── Numbers With Repeated Digits │ └── Numbers With Repeated Digits.py ├── Pairs of Songs With Total Durations Divisible by 60 │ └── Pairs of Songs With Total Durations Divisible by 60.py ├── Partition Array Into Three Parts With Equal Sum │ └── Partition Array Into Three Parts With Equal Sum.py ├── Plus One │ └── Plus One.py ├── Positions of Large Groups │ └── Positions of Large Groups.py ├── Prime Arrangements │ └── Prime Arrangements.py ├── Queens That Can Attack the King │ └── Queens That Can Attack the King.py ├── Remove Element │ └── Remove Element.py ├── Search Insert Position │ └── Search Insert Position.py ├── Sort Array By Parity II │ └── Sort Array By Parity II.py ├── Sort Array By Parity │ └── Sort Array By Parity.py ├── Squares of a Sorted Array │ └── Squares of a Sorted Array.py ├── Sum of Even Numbers After Queries │ └── Sum of Even Numbers After Queries.py ├── Swap For Longest Repeated Character Substring │ └── Swap For Longest Repeated Character Substring.py ├── Transform to Chessboard │ └── Transform to Chessboard.py ├── Two Sum II - Input array is sorted │ └── Two Sum II - Input array is sorted.py ├── Unique Number of Occurrences │ └── Unique Number of Occurrences.py └── __init__.py ├── BFS ├── As Far from Land as Possible │ └── As Far from Land as Possible.py ├── Minimum Knight Moves │ └── Minimum Knight Moves.py ├── Minimum Moves to Reach Target with Rotations │ └── Minimum Moves to Reach Target with Rotations.py ├── Shortest Path Visiting All Nodes │ └── Shortest Path Visiting All Nodes.py ├── Shortest Path with Alternating Colors │ └── Shortest Path with Alternating Colors.py └── Stepping Numbers │ └── Stepping Numbers.py ├── Backtrack ├── Combination Sum II │ └── Combination Sum II.py ├── Combination Sum III │ └── Combination Sum III.py ├── Combination Sum │ └── Combination Sum.py ├── Permutations II │ └── Permutations II.py ├── Permutations │ └── Permutations.py ├── Subsets II │ └── Subsets II.py └── Subsets │ └── Subsets.py ├── Binary Search ├── Compare Strings by Frequency of the Smallest Character │ └── Compare Strings by Frequency of the Smallest Character.py ├── Design A Leaderboard │ └── Design A Leaderboard.py ├── Divide Chocolate │ └── Divide Chocolate.py ├── Find K-th Smallest Pair Distance │ └── Find K-th Smallest Pair Distance.py ├── Find Minimum in Rotated Sorted Array II │ └── Find Minimum in Rotated Sorted Array II.py ├── Find Positive Integer Solution for a Given Equation │ └── Find Positive Integer Solution for a Given Equation.py ├── Kth Smallest Number in Multiplication Table │ └── Kth Smallest Number in Multiplication Table.py ├── Number of Ships in a Rectangle │ └── Number of Ships in a Rectangle.py ├── Online Majority Element In Subarray │ └── Online Majority Element In Subarray.py ├── Search in Rotated Sorted Array II │ └── Search in Rotated Sorted Array II.py ├── Shortest Distance to Target Color │ └── Shortest Distance to Target Color.py ├── Snapshot Array │ └── Snapshot Array.py └── Ugly Number III │ └── Ugly Number III.py ├── Bitwise ├── Circular Permutation in Binary Representation │ └── Circular Permutation in Binary Representation.py └── Number of Valid Words for Each Puzzle │ └── Number of Valid Words for Each Puzzle.py ├── DFS ├── Number of Closed Islands │ └── Number of Closed Islands.py ├── Path with Maximum Gold │ └── Path with Maximum Gold.py └── Unique Paths III │ └── Unique Paths III.py ├── Dynamic Programming ├── Best Time to Buy and Sell Stock IV │ └── Best Time to Buy and Sell Stock IV.py ├── Can I Win │ └── Can I Win.py ├── Count Vowels Permutation │ └── Count Vowels Permutation.py ├── Dice Roll Simulation │ └── Dice Roll Simulation.py ├── Distinct Subsequences II │ └── Distinct Subsequences II.py ├── Distinct Subsequences │ └── Distinct Subsequences.py ├── Dungeon Game │ └── Dungeon Game.py ├── Frog Jump │ └── Frog Jump.py ├── Guess Number Higher or Lower II │ └── Guess Number Higher or Lower II.py ├── Knight Dialer │ └── Knight Dialer.py ├── Largest Divisible Subset │ └── Largest Divisible Subset.py ├── Longest Arithmetic Subsequence of Given Difference │ └── Longest Arithmetic Subsequence of Given Difference.py ├── Longest Common Subsequence │ └── Longest Common Subsequence.py ├── Longest Increasing Subsequence │ └── Longest Increasing Subsequence.py ├── Make Array Strictly Increasing │ └── Make Array Strictly Increasing.py ├── Maximum Length of a Concatenated String with Unique Characters │ └── Maximum Length of a Concatenated String with Unique Characters.py ├── Maximum Profit in Job Scheduling │ └── Maximum Profit in Job Scheduling.py ├── Maximum Score Words Formed by Letters │ └── Maximum Score Words Formed by Letters.py ├── Minimum Cost For Tickets │ └── Minimum Cost For Tickets.py ├── Minimum Cost to Merge Stones │ └── Minimum Cost to Merge Stones.py ├── Minimum Falling Path Sum │ └── Minimum Falling Path Sum.py ├── Minimum Number of Refueling Stops │ └── Minimum Number of Refueling Stops.py ├── Number of Dice Rolls With Target Sum │ └── Number of Dice Rolls With Target Sum.py ├── Number of Subarrays with Bounded Maximum │ └── Number of Subarrays with Bounded Maximum.py ├── Numbers With Same Consecutive Differences │ └── Numbers With Same Consecutive Differences.py ├── Palindrome Partitioning III │ └── Palindrome Partitioning III.py ├── Palindrome Removal │ └── Palindrome Removal.py ├── Russian Doll Envelopes │ └── Russian Doll Envelopes.py ├── Smallest Sufficient Team │ └── Smallest Sufficient Team.py ├── Stone Game II │ └── Stone Game II.py ├── Tallest Billboard │ └── Tallest Billboard.py ├── Tiling a Rectangle with the Fewest Squares │ └── Tiling a Rectangle with the Fewest Squares.py ├── Toss Strange Coins │ └── Toss Strange Coins.py └── Valid Palindrome III │ └── Valid Palindrome III.py ├── Graph ├── Cheapest Flights Within K Stops │ └── Cheapest Flights Within K Stops.py ├── Critical Connections in a Network │ └── Critical Connections in a Network.py ├── Parallel Courses │ └── Parallel Courses.py └── Sort Items by Groups Respecting Dependencies │ └── Sort Items by Groups Respecting Dependencies.py ├── Greedy ├── Broken Calculator │ └── Broken Calculator.py ├── Longest Chunked Palindrome Decomposition │ └── Longest Chunked Palindrome Decomposition.py └── Reconstruct a 2-Row Binary Matrix │ └── Reconstruct a 2-Row Binary Matrix.py ├── Hash ├── Longest Duplicate Substring │ └── Longest Duplicate Substring.py ├── Repeated String Match │ └── Repeated String Match.py └── Rotate String │ └── Rotate String.py ├── HashMap ├── Alphabet Board Path │ └── Alphabet Board Path.py ├── Analyze User Website Visit Pattern │ └── Analyze User Website Visit Pattern.py ├── Binary Subarrays With Sum │ └── Binary Subarrays With Sum.py ├── Day of the Week │ └── Day of the Week.py ├── Design File System │ └── Design File System.py ├── Longest Well-Performing Interval │ └── Longest Well-Performing Interval.py ├── Maximum Equal Frequency │ └── Maximum Equal Frequency.py ├── Maximum Number of Balloons │ └── Maximum Number of Balloons.py ├── Minimum Area Rectangle │ └── Minimum Area Rectangle.py ├── Minimum Swaps to Make Strings Equal │ └── Minimum Swaps to Make Strings Equal.py ├── Number of Equivalent Domino Pairs │ └── Number of Equivalent Domino Pairs.py ├── Play with Chips │ └── Play with Chips.py ├── Single-Row Keyboard │ └── Single-Row Keyboard.py ├── String Transforms Into Another String │ └── String Transforms Into Another String.py └── Triples with Bitwise AND Equal To Zero │ └── Triples with Bitwise AND Equal To Zero.py ├── HashSet └── Intersection of Three Sorted Arrays │ └── Intersection of Three Sorted Arrays.py ├── Heap ├── Dinner Plate Stacks │ └── Dinner Plate Stacks.py ├── Find Smallest Common Element in All Rows │ └── Find Smallest Common Element in All Rows.py ├── K-th Smallest Prime Fraction │ └── K-th Smallest Prime Fraction.py ├── Minimum Cost to Connect Sticks │ └── Minimum Cost to Connect Sticks.py ├── Minimum Cost to Hire K Workers │ └── Minimum Cost to Hire K Workers.py ├── Minimum Number of Refueling Stops │ └── Minimum Number of Refueling Stops.py └── Minimum Time to Build Blocks │ └── Minimum Time to Build Blocks.py ├── LinkedList ├── Convert Sorted List to Binary Search Tree │ └── Convert Sorted List to Binary Search Tree.py ├── Design Linked List │ └── Design Linked List.py ├── Insertion Sort List │ └── Insertion Sort List.py ├── LRU Cache │ └── LRU Cache.py ├── Linked List Cycle II │ └── Linked List Cycle II.py ├── Linked List Cycle │ └── Linked List Cycle.py ├── Linked List Random Node │ └── Linked List Random Node.py ├── LinkedList Structure │ └── LinkedList Structure.py ├── Merge Two Sorted Lists │ └── Merge Two Sorted Lists.py ├── Merge k Sorted Lists │ └── Merge k Sorted Lists.py ├── Middle of the Linked List │ └── Middle of the Linked List.py ├── Odd Even Linked List │ └── Odd Even Linked List.py ├── Palindrome Linked List │ └── Palindrome Linked List.py ├── Partition List │ └── Partition List.py ├── Remove Duplicates from Sorted List II │ └── Remove Duplicates from Sorted List II.py ├── Remove Duplicates from Sorted List │ └── Remove Duplicates from Sorted List.py ├── Remove Linked List Elements │ └── Remove Linked List Elements.py ├── Remove Nth Node From End of List │ └── Remove Nth Node From End of List.py ├── Remove Zero Sum Consecutive Nodes from Linked List │ └── Remove Zero Sum Consecutive Nodes from Linked List.py ├── Reorder List │ └── Reorder List.py ├── Reverse Linked List II │ └── Reverse Linked List II.py ├── Reverse Linked List │ └── Reverse Linked List.py ├── Reverse Nodes in k-Group │ └── Reverse Nodes in k-Group.py ├── Rotate List │ └── Rotate List.py ├── Sort List │ └── Sort List.py └── Swap Nodes in Pairs │ └── Swap Nodes in Pairs.py ├── Math └── Number of Burgers with No Waste of Ingredients │ └── Number of Burgers with No Waste of Ingredients.py ├── Sliding Window ├── Count Number of Nice Subarrays │ └── Count Number of Nice Subarrays.py ├── Replace the Substring for Balanced String │ └── Replace the Substring for Balanced String.py └── Subarrays with K Different Integers │ └── Subarrays with K Different Integers.py ├── Sort ├── K Closest Points to Origin │ └── K Closest Points to Origin.py ├── Relative Sort Array │ └── Relative Sort Array.py └── Remove Interval │ └── Remove Interval.py ├── Stack ├── Backspace String Compare │ └── Backspace String Compare.py ├── Baseball Game │ └── Baseball Game.py ├── Implement Queue using Stacks │ └── Implement Queue using Stacks.py ├── Implement Stack using Queues │ └── Implement Stack using Queues.py ├── Min Stack │ └── Min Stack.py ├── Minimum Cost Tree From Leaf Values │ └── Minimum Cost Tree From Leaf Values.py ├── Minimum Remove to Make Valid Parentheses │ └── Minimum Remove to Make Valid Parentheses.py ├── Next Greater Element I │ └── Next Greater Element I.py ├── Remove All Adjacent Duplicates In String │ └── Remove All Adjacent Duplicates In String.py ├── Remove All Adjacent Duplicates in String II │ └── Remove All Adjacent Duplicates in String II.py ├── Remove Outermost Parentheses │ └── Remove Outermost Parentheses.py ├── Reverse Substrings Between Each Pair of Parentheses │ └── Reverse Substrings Between Each Pair of Parentheses.py ├── Simplify Path │ └── Simplify Path.py └── Valid Parentheses │ └── Valid Parentheses.py ├── String ├── Equal Rational Numbers │ └── Equal Rational Numbers.py ├── Find Winner on a Tic Tac Toe Game │ └── Find Winner on a Tic Tac Toe Game.py ├── Hexspeak │ └── Hexspeak.py └── Split a String in Balanced Strings │ └── Split a String in Balanced Strings.py ├── Tree ├── Binary Tree Coloring Game │ └── Binary Tree Coloring Game.py ├── Delete Tree Nodes │ └── Delete Tree Nodes.py ├── Lowest Common Ancestor of Deepest Leaves │ └── Lowest Common Ancestor of Deepest Leaves.py ├── Scramble String │ └── Scramble String.py ├── Tree Diameter │ └── Tree Diameter.py └── Two Sum BSTs │ └── Two Sum BSTs.py ├── Trie └── Remove Sub-Folders from the Filesystem │ └── Remove Sub-Folders from the Filesystem.py ├── Union Find ├── Accounts Merge │ └── Accounts Merge.py ├── Connecting Cities With Minimum Cost │ └── Connecting Cities With Minimum Cost.py ├── DSU Structure │ └── DSU Structure.py ├── Minimize Malware Spread │ └── Minimize Malware Spread.py ├── Most Stones Removed with Same Row or Column │ └── Most Stones Removed with Same Row or Column.py ├── Optimize Water Distribution in a Village │ └── Optimize Water Distribution in a Village.py └── Smallest String With Swaps │ └── Smallest String With Swaps.py └── __init__.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baldFemale/LeetCode-Solution/d89ebad5305e4d1a185b0c6f101a88691602b523/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # idea 2 | .idea 3 | idea/ 4 | -------------------------------------------------------------------------------- /python/Array/1-bit and 2-bit Characters/1-bit and 2-bit Characters.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isOneBitCharacter(self, bits): 3 | """ 4 | :type bits: List[int] 5 | :rtype: bool 6 | """ 7 | i = 0 8 | 9 | while i < len(bits): 10 | if i == len(bits) - 1 and bits[i] == 0: 11 | return True 12 | if bits[i] == 1: 13 | i += 2 14 | else: 15 | i += 1 16 | return False 17 | -------------------------------------------------------------------------------- /python/Array/Array Partition I/Array Partition I.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def arrayPairSum(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | nums.sort() 8 | return sum([nums[i] for i in range(0,len(nums),2)]) -------------------------------------------------------------------------------- /python/Array/Array Transformation/Array Transformation.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def transformArray(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: List[int] 6 | """ 7 | pre = None 8 | 9 | while pre != arr: 10 | pre = list(arr) 11 | temp = list(arr) 12 | for i in range(1, len(arr) - 1): 13 | if arr[i] < arr[i + 1] and arr[i] < arr[i - 1]: 14 | temp[i] += 1 15 | elif arr[i] > arr[i + 1] and arr[i] > arr[i - 1]: 16 | temp[i] -= 1 17 | arr = temp 18 | return arr 19 | 20 | -------------------------------------------------------------------------------- /python/Array/Before and After Puzzle/Before and After Puzzle.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def beforeAndAfterPuzzles(self, phrases): 3 | """ 4 | :type phrases: List[str] 5 | :rtype: List[str] 6 | """ 7 | n = len(phrases) 8 | res = [] 9 | for i in range(n): 10 | for j in range(n): 11 | if i==j: 12 | continue 13 | items_i = phrases[i].split(" ") 14 | items_j = phrases[j].split(" ") 15 | if items_i[-1]==items_j[0]: 16 | res.append(" ".join(items_i+items_j[1:])) 17 | return sorted(list(set(res))) -------------------------------------------------------------------------------- /python/Array/Best Time to Buy and Sell Stock II/Best Time to Buy and Sell Stock II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxProfit(self, prices): 3 | """ 4 | :type prices: List[int] 5 | :rtype: int 6 | """ 7 | pre = float("inf") 8 | res = 0 9 | 10 | for p in prices: 11 | if p > pre: 12 | res += p - pre 13 | pre = p 14 | 15 | return res 16 | -------------------------------------------------------------------------------- /python/Array/Best Time to Buy and Sell Stock/Best Time to Buy and Sell Stock.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxProfit(self, prices): 3 | """ 4 | :type prices: List[int] 5 | :rtype: int 6 | """ 7 | if not prices: 8 | return 0 9 | res = 0 10 | pre = prices[0] 11 | 12 | for p in prices: 13 | if p <= pre: 14 | pre = p 15 | else: 16 | if p > pre: 17 | res = max(res, p - pre) 18 | return res 19 | -------------------------------------------------------------------------------- /python/Array/Can Make Palindrome from Substring/Can Make Palindrome from Substring.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canMakePaliQueries(self, s, queries): 3 | """ 4 | :type s: str 5 | :type queries: List[List[int]] 6 | :rtype: List[bool] 7 | """ 8 | counters = [] 9 | temp = [0 for i in range(26)] 10 | counters.append(list(temp)) 11 | for i in range(len(s)): 12 | temp[ord(s[i]) - ord("a")] += 1 13 | counters.append(list(temp)) 14 | res = [] 15 | for q in queries: 16 | t = [counters[q[1] + 1][i] - counters[q[0]][i] for i in range(26)] 17 | t = [i % 2 for i in t] 18 | if (q[1] - q[0] + 1) % 2 == 0: 19 | res.append(sum(t) // 2 <= q[2]) 20 | else: 21 | res.append((sum(t) - 1) // 2 <= q[2]) 22 | return res 23 | -------------------------------------------------------------------------------- /python/Array/Cells with Odd Values in a Matrix/Cells with Odd Values in a Matrix.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def oddCells(self, n, m, indices): 3 | """ 4 | :type n: int 5 | :type m: int 6 | :type indices: List[List[int]] 7 | :rtype: int 8 | """ 9 | matrix = [[0 for i in range(m)] for j in range(n)] 10 | 11 | for i, j in indices: 12 | for k in range(m): 13 | matrix[i][k] += 1 14 | for k in range(n): 15 | matrix[k][j] += 1 16 | 17 | res = 0 18 | for i in range(n): 19 | for j in range(m): 20 | if matrix[i][j] % 2 == 1: 21 | res += 1 22 | return res -------------------------------------------------------------------------------- /python/Array/Check If It Is a Good Array/Check If It Is a Good Array.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isGoodArray(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: bool 6 | """ 7 | nums = list(set(nums)) 8 | 9 | def gcd(a, b): 10 | if a < b: 11 | a, b = b, a 12 | while b: 13 | a, b = b, a % b 14 | 15 | return a 16 | 17 | nums.sort() 18 | t = nums[0] 19 | 20 | if t == 1: 21 | return True 22 | if len(nums) == 1: 23 | return False 24 | 25 | tt = gcd(nums[0], nums[1]) 26 | for i in range(2, len(nums)): 27 | tt = gcd(nums[i], tt) 28 | if tt == 1: 29 | return True 30 | return False if tt != 1 else True 31 | -------------------------------------------------------------------------------- /python/Array/Check If It Is a Straight Line/Check If It Is a Straight Line.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def checkStraightLine(self, coordinates): 3 | """ 4 | :type coordinates: List[List[int]] 5 | :rtype: bool 6 | """ 7 | coordinates.sort(key=lambda x: x[0]) 8 | 9 | dif_x, dif_y = coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1] 10 | 11 | for i in range(2, len(coordinates)): 12 | if (coordinates[i][0] - coordinates[i - 1][0]) * dif_y != ( 13 | coordinates[i][1] - coordinates[i - 1][1]) * dif_x: 14 | return False 15 | return True 16 | -------------------------------------------------------------------------------- /python/Array/Circular Array Loop/Circular Array Loop.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def circularArrayLoop(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: bool 6 | """ 7 | for i in range(len(nums)): 8 | if nums[i] == 0: 9 | continue 10 | cur = i 11 | seen = set([i]) 12 | tag = nums[i] 13 | while tag * nums[(cur + nums[cur]) % len(nums)] > 0 and (cur + nums[cur]) % len(nums) not in seen: 14 | seen.add((cur + nums[cur]) % len(nums)) 15 | cur = (cur + nums[cur]) % len(nums) 16 | if tag * nums[(cur + nums[cur]) % len(nums)] > 0 and cur != (cur + nums[cur]) % len(nums): 17 | return True 18 | else: 19 | for i in seen: 20 | nums[i] = 0 21 | 22 | return False 23 | -------------------------------------------------------------------------------- /python/Array/Contains Duplicate/Contains Duplicate.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def containsDuplicate(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: bool 6 | """ 7 | return not len(set(nums))==len(nums) 8 | -------------------------------------------------------------------------------- /python/Array/Count Square Submatrices with All Ones/Count Square Submatrices with All Ones.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countSquares(self, matrix: List[List[int]]) -> int: 3 | 4 | m = len(matrix) 5 | n = len(matrix[0]) 6 | 7 | va = set([i ** 2 for i in range(1, 300)]) 8 | 9 | for j in range(m): 10 | for i in range(1, n): 11 | matrix[j][i] += matrix[j][i - 1] 12 | 13 | for i in range(1, m): 14 | for j in range(n): 15 | matrix[i][j] += matrix[i - 1][j] 16 | 17 | res = 0 18 | for i in range(m): 19 | for j in range(n): 20 | k = 0 21 | while i - k >= 0 and j - k >= 0: 22 | if i - k > 0 and j - k > 0: 23 | t = matrix[i][j] + matrix[i - k - 1][j - k - 1] - matrix[i - k - 1][j] - matrix[i][j - k - 1] 24 | elif i - k == 0 and j - k == 0: 25 | t = matrix[i][j] 26 | elif i - k == 0: 27 | t = matrix[i][j] - matrix[i][j - k - 1] 28 | else: 29 | t = matrix[i][j] - matrix[i - k - 1][j] 30 | if t == (k + 1) ** 2: 31 | res += 1 32 | k += 1 33 | else: 34 | break 35 | return res 36 | 37 | -------------------------------------------------------------------------------- /python/Array/Count Substrings with Only One Distinct Letter/Count Substrings with Only One Distinct Letter.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def countLetters(self, S): 3 | """ 4 | :type S: str 5 | :rtype: int 6 | """ 7 | res = 0 8 | count = 0 9 | temp = "" 10 | for i in S: 11 | if count==0 or temp[-1]==i: 12 | count+=1 13 | temp = temp+i 14 | else: 15 | temp = i 16 | res+=(count*(count+1))//2 17 | count = 1 18 | if count: 19 | res+=(count*(count+1))//2 20 | return res 21 | -------------------------------------------------------------------------------- /python/Array/Decrease Elements To Make Array Zigzag/Decrease Elements To Make Array Zigzag.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def movesToMakeZigzag(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | 8 | nums = [float("inf")] + nums + [float("inf")] 9 | res = [0, 0] 10 | 11 | for i in range(1, len(nums) - 1): 12 | res[i % 2] += max(0, nums[i] + 1 - min(nums[i - 1], nums[i + 1])) 13 | return min(res) 14 | -------------------------------------------------------------------------------- /python/Array/Degree of an Array/Degree of an Array.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def findShortestSubArray(self, nums): 6 | """ 7 | :type nums: List[int] 8 | :rtype: int 9 | """ 10 | dic = defaultdict(list) 11 | 12 | for i, j in enumerate(nums): 13 | dic[j].append(i) 14 | 15 | degree = 0 16 | length = float("inf") 17 | print(dic) 18 | 19 | for k, v in dic.items(): 20 | print(k, v) 21 | print(degree, length) 22 | if len(v) > degree: 23 | degree = len(v) 24 | if degree == 1: 25 | length = 1 26 | else: 27 | length = v[-1] - v[0] + 1 28 | elif len(v) == degree and len(v) > 1 and v[-1] - v[0] + 1 <= length: 29 | length = v[-1] - v[0] + 1 30 | 31 | return length 32 | -------------------------------------------------------------------------------- /python/Array/Diet Plan Performance/Diet Plan Performance.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def dietPlanPerformance(self, calories, k, lower, upper): 3 | """ 4 | :type calories: List[int] 5 | :type k: int 6 | :type lower: int 7 | :type upper: int 8 | :rtype: int 9 | """ 10 | n = len(calories) 11 | temp = [] 12 | cur = sum(calories[0:k-1]) 13 | for i in range(0,n-k+1): 14 | cur+=calories[i+k-1] 15 | temp.append(cur) 16 | cur-=calories[i] 17 | res = 0 18 | for i in temp: 19 | if i>upper: 20 | res+=1 21 | elif i destination: 12 | return min(sum(distance[destination:start]), sum(distance[start:]) + sum(distance[:destination])) 13 | else: 14 | return min(sum(distance[start:destination]), sum(distance[destination:]) + sum(distance[:start])) 15 | -------------------------------------------------------------------------------- /python/Array/Duplicate Zeros/Duplicate Zeros.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def duplicateZeros(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: None Do not return anything, modify arr in-place instead. 6 | """ 7 | 8 | count = 0 9 | for i in arr: 10 | if i == 0: 11 | count += 1 12 | 13 | for j in range(len(arr) - 1, -1, -1): 14 | if j + count < len(arr): 15 | arr[j + count] = arr[j] 16 | if arr[j] == 0: 17 | count -= 1 18 | if j + count < len(arr): 19 | arr[j + count] = 0 20 | -------------------------------------------------------------------------------- /python/Array/Fair Candy Swap/Fair Candy Swap.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def fairCandySwap(self, A, B): 3 | """ 4 | :type A: List[int] 5 | :type B: List[int] 6 | :rtype: List[int] 7 | """ 8 | sum_A = sum(A) 9 | sum_B = sum(B) 10 | A = set(A) 11 | B = set(B) 12 | 13 | for i in A: 14 | if ((sum_A + sum_B) // 2 - sum_A) + i in B: 15 | return [i, ((sum_A + sum_B) // 2 - sum_A) + i] 16 | -------------------------------------------------------------------------------- /python/Array/Fibonacci Number/Fibonacci Number.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def fib(self, N): 3 | """ 4 | :type N: int 5 | :rtype: int 6 | """ 7 | cache = {0: 0, 1: 1} 8 | 9 | def helper(n): 10 | return cache[n] if n in cache else helper(n - 1) + helper(n - 2) 11 | 12 | return helper(N) 13 | -------------------------------------------------------------------------------- /python/Array/Find All Numbers Disappeared in an Array/Find All Numbers Disappeared in an Array.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findDisappearedNumbers(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[int] 6 | """ 7 | for i in nums: 8 | i = abs(i) 9 | if nums[i - 1] > 0: 10 | nums[i - 1] *= -1 11 | print(nums) 12 | 13 | res = [] 14 | for i in range(len(nums)): 15 | if nums[i] > 0: 16 | res.append(i + 1) 17 | return res 18 | -------------------------------------------------------------------------------- /python/Array/Find Common Characters/Find Common Characters.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | class Solution(object): 4 | def commonChars(self, A): 5 | """ 6 | :type A: List[str] 7 | :rtype: List[str] 8 | """ 9 | c = Counter(A[0]) 10 | for word in A[1:]: 11 | temp = Counter(word) 12 | c = c & temp 13 | 14 | res = [] 15 | for k in c: 16 | res += [k] * c[k] 17 | return res 18 | -------------------------------------------------------------------------------- /python/Array/Find Pivot Index/Find Pivot Index.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def pivotIndex(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | s = sum(nums) 8 | left = 0 9 | 10 | for i in range(len(nums)): 11 | if left == s - left - nums[i]: 12 | return i 13 | left += nums[i] 14 | return -1 15 | -------------------------------------------------------------------------------- /python/Array/Get Equal Substrings Within Budget/Get Equal Substrings Within Budget.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def equalSubstring(self, s, t, maxCost): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :type maxCost: int 7 | :rtype: int 8 | """ 9 | A = [abs(ord(i) - ord(j)) for i, j in zip(s, t)] 10 | 11 | cost = maxCost 12 | 13 | res = 0 14 | i = 0 15 | 16 | for j in range(len(s)): 17 | cost -= A[j] 18 | 19 | while i < len(s) and cost < 0: 20 | cost += A[i] 21 | i += 1 22 | 23 | res = max(res, j - i + 1) 24 | 25 | return res 26 | -------------------------------------------------------------------------------- /python/Array/Height Checker/Height Checker.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def heightChecker(self, heights): 3 | """ 4 | :type heights: List[int] 5 | :rtype: int 6 | """ 7 | return sum([1 for h1,h2 in zip(heights,sorted(heights)) if h1!=h2]) 8 | -------------------------------------------------------------------------------- /python/Array/How Many Apples Can You Put into the Basket/How Many Apples Can You Put into the Basket.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxNumberOfApples(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: int 6 | """ 7 | arr.sort() 8 | 9 | weight = 5000 10 | count = 0 11 | 12 | while len(arr) > 0 and weight - arr[0] > 0: 13 | count += 1 14 | weight -= arr[0] 15 | arr.pop(0) 16 | return count 17 | -------------------------------------------------------------------------------- /python/Array/Image Smoother/Image Smoother.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def imageSmoother(self, M): 3 | """ 4 | :type M: List[List[int]] 5 | :rtype: List[List[int]] 6 | """ 7 | res = [[0 for i in range(len(M[0]))] for j in range(len(M))] 8 | 9 | for i in range(len(M)): 10 | for j in range(len(M[0])): 11 | count = 0 12 | temp = 0 13 | for x in [1, 0, -1]: 14 | for y in [1, 0, -1]: 15 | if 0 <= i + x < len(M) and 0 <= j + y < len(M[0]): 16 | temp += M[i + x][j + y] 17 | count += 1 18 | res[i][j] = temp // count 19 | return res 20 | -------------------------------------------------------------------------------- /python/Array/Insert Delete GetRandom O(1) - Duplicates allowed/Insert Delete GetRandom O(1) - Duplicates allowed.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | from collections import defaultdict 3 | 4 | 5 | class RandomizedCollection(object): 6 | 7 | def __init__(self): 8 | """ 9 | Initialize your data structure here. 10 | """ 11 | self.dic = defaultdict(set) 12 | self.arr = [] 13 | self.length = 0 14 | 15 | def insert(self, val): 16 | """ 17 | Inserts a value to the collection. Returns true if the collection did not already contain the specified element. 18 | :type val: int 19 | :rtype: bool 20 | """ 21 | self.dic[val].add(self.length) 22 | self.length += 1 23 | self.arr.append(val) 24 | return len(self.dic[val]) == 1 25 | 26 | def remove(self, val): 27 | """ 28 | Removes a value from the collection. Returns true if the collection contained the specified element. 29 | :type val: int 30 | :rtype: bool 31 | """ 32 | if len(self.dic[val]) >= 1: 33 | index = self.dic[val].pop() 34 | last = self.arr[-1] 35 | self.arr[index] = last 36 | self.arr.pop() 37 | self.dic[last].add(index) 38 | self.dic[last].remove(self.length - 1) 39 | self.length -= 1 40 | return True 41 | else: 42 | return False 43 | 44 | def getRandom(self): 45 | """ 46 | Get a random element from the collection. 47 | :rtype: int 48 | """ 49 | index = randint(0, self.length - 1) 50 | return self.arr[index] 51 | 52 | # Your RandomizedCollection object will be instantiated and called as such: 53 | # obj = RandomizedCollection() 54 | # param_1 = obj.insert(val) 55 | # param_2 = obj.remove(val) 56 | # param_3 = obj.getRandom() 57 | -------------------------------------------------------------------------------- /python/Array/Interval List Intersections/Interval List Intersections.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def intervalIntersection(self, A, B): 3 | """ 4 | :type A: List[List[int]] 5 | :type B: List[List[int]] 6 | :rtype: List[List[int]] 7 | """ 8 | i = 0 9 | j = 0 10 | res = [] 11 | while i < len(A) and j < len(B): 12 | if A[i][-1] < B[j][-1]: 13 | if A[i][-1] >= max(A[i][0], B[j][0]): 14 | res.append([max(A[i][0], B[j][0]), A[i][-1]]) 15 | i += 1 16 | else: 17 | if B[j][-1] >= max(A[i][0], B[j][0]): 18 | res.append([max(A[i][0], B[j][0]), B[j][-1]]) 19 | j += 1 20 | return res 21 | -------------------------------------------------------------------------------- /python/Array/Invalid Transactions/Invalid Transactions.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def invalidTransactions(self, transactions): 3 | """ 4 | :type transactions: List[str] 5 | :rtype: List[str] 6 | """ 7 | res = [] 8 | for i in range(len(transactions)): 9 | tran = transactions[i].split(",") 10 | if int(tran[2]) > 1000: 11 | res.append(transactions[i]) 12 | continue 13 | for j in range(len(transactions)): 14 | if i == j: 15 | continue 16 | tran2 = transactions[j].split(",") 17 | if tran2[0] == tran[0] and (int(tran2[1]) - 60 <= int(tran[1]) <= int(tran2[1]) + 60) and tran[3] != \ 18 | tran2[3]: 19 | res.append(transactions[i]) 20 | print(transactions[i]) 21 | break 22 | return res 23 | -------------------------------------------------------------------------------- /python/Array/K-Concatenation Maximum Sum/K-Concatenation Maximum Sum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def kConcatenationMaxSum(self, arr, k): 3 | """ 4 | :type arr: List[int] 5 | :type k: int 6 | :rtype: int 7 | """ 8 | v = -float("inf") 9 | m = 0 10 | res = v 11 | cur = 0 12 | temp = [0] 13 | for j, i in enumerate(arr): 14 | temp.append(temp[-1] + i) 15 | cur = max(cur + i, i) 16 | m = max(cur, m) 17 | res = max(res, m) 18 | print(res) 19 | cross_m = v 20 | 21 | for i in temp: 22 | if i <= temp[-1]: 23 | cross_m = max(cross_m, temp[-1] - i) 24 | print(cross_m) 25 | 26 | if temp[-1] > 0: 27 | res = max(res, cross_m + (k - 1) * temp[-1]) 28 | print(res) 29 | res = max(res, cross_m + max(temp[1:])) 30 | print(res) 31 | res = max(res, cross_m + (k - 2) * temp[-1] + max(temp[1:])) 32 | return res % (10 ** 9 + 7) 33 | -------------------------------------------------------------------------------- /python/Array/Largest 1-Bordered Square/Largest 1-Bordered Square.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def largest1BorderedSquare(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | top = [i for i in grid] 8 | left = [[i[j] for j in range(len(grid[0]))] for i in grid] 9 | 10 | for i in range(len(grid)): 11 | for j in range(len(grid[0])): 12 | if grid[i][j]: 13 | if i: 14 | top[i][j] = top[i - 1][j] + 1 15 | if j: 16 | left[i][j] = left[i][j - 1] + 1 17 | 18 | for r in range(min(len(grid), len(grid[0])), 0, -1): 19 | for i in range(len(grid) + 1 - r): 20 | for j in range(len(grid[0]) + 1 - r): 21 | if min(top[i + r - 1][j], top[i + r - 1][j + r - 1], left[i][j + r - 1], 22 | left[i + r - 1][j + r - 1]) >= r: 23 | return r ** 2 24 | return 0 25 | -------------------------------------------------------------------------------- /python/Array/Last Substring in Lexicographical Order/Last Substring in Lexicographical Order.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def lastSubstring(self, s): 6 | """ 7 | :type s: str 8 | :rtype: str 9 | """ 10 | n = len(s) 11 | d = defaultdict(list) 12 | for i, j in enumerate(s): 13 | d[j].append(i) 14 | if len(d) == 1: 15 | return s 16 | m = max(d.keys()) 17 | start = d[m] 18 | 19 | c = 0 20 | while len(start) > 1: 21 | c += 1 22 | start = [i + 1 for i in start if i + 1 <= n - 1] 23 | m = max([s[i] for i in start]) 24 | start = [i for i in start if s[i] == m] 25 | return s[start[0] - c:] 26 | -------------------------------------------------------------------------------- /python/Array/Majority Element/Majority Element.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def majorityElement(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | count = 0 8 | candinate = None 9 | 10 | for i in nums: 11 | if count == 0: 12 | candinate = i 13 | if i == candinate: 14 | count += 1 15 | else: 16 | count -= 1 17 | return candinate 18 | -------------------------------------------------------------------------------- /python/Array/Max Chunks To Make Sorted II/Max Chunks To Make Sorted II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxChunksToSorted(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: int 6 | """ 7 | mi_value = float("inf") 8 | ma_value = -mi_value 9 | mi = [] 10 | ma = [] 11 | 12 | for i in range(len(arr)): 13 | ma_value = max(ma_value, arr[i]) 14 | ma.append(ma_value) 15 | for i in range(len(arr) - 1, -1, -1): 16 | mi_value = min(mi_value, arr[i]) 17 | mi.append(mi_value) 18 | mi = mi[::-1] 19 | print(mi) 20 | print(ma) 21 | res = 0 22 | for i in range(len(arr) - 1): 23 | if mi[i + 1] >= ma[i]: 24 | res += 1 25 | return res + 1 26 | -------------------------------------------------------------------------------- /python/Array/Max Chunks To Make Sorted/Max Chunks To Make Sorted.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxChunksToSorted(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: int 6 | """ 7 | ma = -float("inf") 8 | res = 0 9 | for i in range(len(arr)): 10 | ma = max(ma,arr[i]) 11 | if ma==i: 12 | res+=1 13 | return res 14 | -------------------------------------------------------------------------------- /python/Array/Max Consecutive Ones/Max Consecutive Ones.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findMaxConsecutiveOnes(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | res = 0 8 | count = 0 9 | for i in nums: 10 | if i==1: 11 | count+=1 12 | else: 13 | res = max(count,res) 14 | count = 0 15 | return max(res,count) 16 | -------------------------------------------------------------------------------- /python/Array/Maximum Number of Ones/Maximum Number of Ones.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maximumNumberOfOnes(self, width, height, sideLength, maxOnes): 3 | """ 4 | :type width: int 5 | :type height: int 6 | :type sideLength: int 7 | :type maxOnes: int 8 | :rtype: int 9 | """ 10 | count = [0] * sideLength ** 2 11 | 12 | for i in range(height): 13 | for j in range(width): 14 | count[i % sideLength * sideLength + j % sideLength] += 1 15 | 16 | res = 0 17 | count.sort() 18 | for i in range(maxOnes): 19 | res += count.pop() 20 | return res 21 | -------------------------------------------------------------------------------- /python/Array/Maximum Product of Three Numbers/Maximum Product of Three Numbers.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maximumProduct(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | m = float("inf") 8 | min1 = m 9 | min2 = m 10 | max1 = -m 11 | max2 = -m 12 | max3 = -m 13 | 14 | for i in nums: 15 | if i < min1: 16 | min2 = min1 17 | min1 = i 18 | elif i < min2: 19 | min2 = i 20 | 21 | if i > max1: 22 | max3 = max2 23 | max2 = max1 24 | max1 = i 25 | elif i > max2: 26 | max3 = max2 27 | max2 = i 28 | elif i > max3: 29 | max3 = i 30 | 31 | return max(min1 * min2, max2 * max3) * max1 32 | -------------------------------------------------------------------------------- /python/Array/Maximum Subarray Sum with One Deletion/Maximum Subarray Sum with One Deletion.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maximumSum(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: int 6 | """ 7 | n = len(arr) 8 | fw = [0] * n 9 | bw = [0] * n 10 | 11 | cur_max = -2 ** 32 12 | max_sofar = -2 * 32 13 | fans = -2 ** 32 14 | for i in range(n): 15 | cur_max = max(cur_max + arr[i], arr[i]) 16 | fw[i] = cur_max 17 | max_sofar = max(max_sofar, cur_max) 18 | fans = max(fans, max_sofar) 19 | cur_max = arr[-1] 20 | max_sofar = arr[-1] 21 | bw[-1] = arr[-1] 22 | i = n - 2 23 | while i >= 0: 24 | cur_max = max(arr[i], cur_max + arr[i]) 25 | max_sofar = max(max_sofar, cur_max) 26 | bw[i] = cur_max 27 | i -= 1 28 | fans = max(fans, max_sofar) 29 | for i in range(1, n - 1): 30 | fans = max(fans, fw[i - 1] + bw[i + 1]) 31 | return fans 32 | -------------------------------------------------------------------------------- /python/Array/Maximum Subarray/Maximum Subarray.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxSubArray(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | pre = 0 8 | res = -float("inf") 9 | 10 | for i in nums: 11 | pre = max(i, pre + i) 12 | res = max(res, pre) 13 | return res 14 | -------------------------------------------------------------------------------- /python/Array/Maximum Sum of 3 Non-Overlapping Subarrays/Maximum Sum of 3 Non-Overlapping Subarrays.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxSumOfThreeSubarrays(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: List[int] 7 | """ 8 | 9 | w = [] 10 | temp = 0 11 | for i in range(len(nums)): 12 | temp += nums[i] 13 | if i >= k: 14 | temp -= nums[i - k] 15 | if i >= k - 1: 16 | w.append(temp) 17 | 18 | left = [] 19 | best = 0 20 | for i in range(len(w)): 21 | if w[i] > w[best]: 22 | best = i 23 | left.append(best) 24 | 25 | right = [0] * len(w) 26 | best = len(w) - 1 27 | 28 | for i in range(len(w) - 1, -1, -1): 29 | if w[i] >= w[best]: 30 | best = i 31 | right[i] = best 32 | 33 | ans = None 34 | res = -float("inf") 35 | for i in range(k, len(w) - k): 36 | if w[left[i - k]] + w[right[i + k]] + w[i] > res: 37 | res = w[left[i - k]] + w[right[i + k]] + w[i] 38 | ans = [left[i - k], i, right[i + k]] 39 | return ans 40 | -------------------------------------------------------------------------------- /python/Array/Maximum of Absolute Value Expression/Maximum of Absolute Value Expression.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxAbsValExpr(self, arr1, arr2): 3 | """ 4 | :type arr1: List[int] 5 | :type arr2: List[int] 6 | :rtype: int 7 | """ 8 | res = -float("inf") 9 | for j in [1, -1]: 10 | for k in [1, -1]: 11 | temp = [] 12 | for i in range(len(arr1)): 13 | temp.append(arr1[i] * j + arr2[i] * k + i) 14 | res = max(res, max(temp) - min(temp)) 15 | return res 16 | 17 | -------------------------------------------------------------------------------- /python/Array/Meeting Scheduler/Meeting Scheduler.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minAvailableDuration(self, slots1, slots2, duration): 3 | """ 4 | :type slots1: List[List[int]] 5 | :type slots2: List[List[int]] 6 | :type duration: int 7 | :rtype: List[int] 8 | """ 9 | slots1.sort(key=lambda x: x[0]) 10 | slots2.sort(key=lambda x: x[0]) 11 | i = 0 12 | j = 0 13 | 14 | while i < len(slots1) and j < len(slots2): 15 | 16 | if slots1[i][0] + duration > slots1[i][1] and i + 1 < len(slots1): 17 | i += 1 18 | if slots2[j][0] + duration > slots2[j][1] and j + 1 < len(slots2): 19 | j += 1 20 | 21 | if i < len(slots1) and j < len(slots2): 22 | if slots1[i][0] < slots2[j][0]: 23 | if slots2[j][0] + duration <= min(slots1[i][1], slots2[j][1]): 24 | return [slots2[j][0], slots2[j][0] + duration] 25 | else: 26 | i += 1 27 | else: 28 | if slots1[i][0] + duration <= min(slots1[i][1], slots2[j][1]): 29 | return [slots1[i][0], slots1[i][0] + duration] 30 | else: 31 | j += 1 32 | return [] 33 | -------------------------------------------------------------------------------- /python/Array/Min Cost Climbing Stairs/Min Cost Climbing Stairs.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minCostClimbingStairs(self, cost): 3 | """ 4 | :type cost: List[int] 5 | :rtype: int 6 | """ 7 | 8 | m = float("inf") 9 | dp = [m] * (len(cost) + 1) 10 | 11 | dp[0] = 0 12 | dp[1] = 0 13 | 14 | for i in range(2, len(dp)): 15 | dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]) 16 | return dp[-1] 17 | -------------------------------------------------------------------------------- /python/Array/Minimum Absolute Difference/Minimum Absolute Difference.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minimumAbsDifference(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: List[List[int]] 6 | """ 7 | arr.sort() 8 | 9 | dis = float("inf") 10 | 11 | for i in range(1, len(arr)): 12 | dis = min(dis, arr[i] - arr[i - 1]) 13 | 14 | res = [] 15 | 16 | s = set(arr) 17 | for i in arr: 18 | if i + dis in s: 19 | res.append([i, i + dis]) 20 | return res 21 | -------------------------------------------------------------------------------- /python/Array/Missing Number In Arithmetic Progression/Missing Number In Arithmetic Progression.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def missingNumber(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: int 6 | """ 7 | interval = (arr[-1] - arr[0]) / len(arr) 8 | if interval == 0: 9 | return arr[0] 10 | 11 | for i in range(len(arr)): 12 | if arr[i] + interval != arr[i + 1]: 13 | return arr[i] + interval 14 | -------------------------------------------------------------------------------- /python/Array/Missing Number/Missing Number.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def missingNumber(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | temp = 0 8 | for i in nums: 9 | temp ^= i 10 | 11 | for i in range(1, len(nums) + 1): 12 | temp ^= i 13 | 14 | return temp 15 | -------------------------------------------------------------------------------- /python/Array/Monotonic Array/Monotonic Array.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isMonotonic(self, A): 3 | """ 4 | :type A: List[int] 5 | :rtype: bool 6 | """ 7 | increase = True 8 | decrease = True 9 | 10 | for i in range(1, len(A)): 11 | if A[i] - A[i - 1] > 0: 12 | decrease = False 13 | if A[i] - A[i - 1] < 0: 14 | increase = False 15 | return increase or decrease 16 | -------------------------------------------------------------------------------- /python/Array/Move Zeroes/Move Zeroes.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def moveZeroes(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: None Do not return anything, modify nums in-place instead. 6 | """ 7 | j = 0 8 | for i in range(len(nums)): 9 | while j < len(nums) and nums[j] == 0: 10 | j += 1 11 | if j < len(nums): 12 | nums[i], nums[j] = nums[j], nums[i] 13 | j += 1 14 | -------------------------------------------------------------------------------- /python/Array/N-th Tribonacci Number/N-th Tribonacci Number.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def tribonacci(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | cache = { 8 | 0:0, 9 | 1:1, 10 | 2:1 11 | } 12 | 13 | def helper(n): 14 | if n in cache: 15 | return cache[n] 16 | else: 17 | cache[n-1] = helper(n-1) 18 | cache[n-2] = helper(n-2) 19 | cache[n-3] = helper(n-3) 20 | cache[n] = cache[n-1]+cache[n-2]+cache[n-3] 21 | return cache[n] 22 | return helper(n) 23 | -------------------------------------------------------------------------------- /python/Array/Numbers At Most N Given Digit Set/Numbers At Most N Given Digit Set.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def atMostNGivenDigitSet(self, D, N): 3 | """ 4 | :type D: List[str] 5 | :type N: int 6 | :rtype: int 7 | """ 8 | res = 0 9 | 10 | res += sum(len(D) ** i for i in range(1, len(str(N)))) 11 | 12 | i = 0 13 | while i < len(str(N)): 14 | res += sum(D[j] < str(N)[i] for j in range(len(D))) * len(D) ** (len(str(N)) - i - 1) 15 | 16 | if str(N)[i] not in D: 17 | break 18 | i += 1 19 | return res + (i == len(str(N))) 20 | -------------------------------------------------------------------------------- /python/Array/Numbers With Repeated Digits/Numbers With Repeated Digits.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numDupDigitsAtMostN(self, N): 3 | """ 4 | :type N: int 5 | :rtype: int 6 | """ 7 | 8 | def permutation(m, n): 9 | return 1 if n == 0 else permutation(m, n - 1) * (m - n + 1) 10 | 11 | res = 0 12 | 13 | n = str(N) 14 | res += sum(9 * permutation(9, i - 1) for i in range(1, len(n))) 15 | 16 | i = 0 17 | s = set() 18 | while i < len(n): 19 | for j in range(0 if i != 0 else 1, int(n[i])): 20 | if str(j) not in s: 21 | res += permutation(9 - i, len(n) - i - 1) 22 | if n[i] in s: 23 | break 24 | s.add(n[i]) 25 | i += 1 26 | 27 | return N - res - (i == len(n)) 28 | -------------------------------------------------------------------------------- /python/Array/Pairs of Songs With Total Durations Divisible by 60/Pairs of Songs With Total Durations Divisible by 60.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numPairsDivisibleBy60(self, time): 3 | """ 4 | :type time: List[int] 5 | :rtype: int 6 | """ 7 | dic = {} 8 | 9 | for t in time: 10 | dic[t % 60] = dic.get(t % 60, 0) + 1 11 | 12 | res = 0 13 | for k, v in dic.items(): 14 | if k == 0 or k == 30: 15 | res += v * (v - 1) 16 | else: 17 | if 60 - k in dic: 18 | res += v * dic[60 - k] 19 | return res // 2 20 | -------------------------------------------------------------------------------- /python/Array/Partition Array Into Three Parts With Equal Sum/Partition Array Into Three Parts With Equal Sum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canThreePartsEqualSum(self, A): 3 | """ 4 | :type A: List[int] 5 | :rtype: bool 6 | """ 7 | s = sum(A) 8 | if s % 3 != 0: 9 | return False 10 | target = s // 3 11 | 12 | cur = 0 13 | count = 0 14 | for i in A: 15 | cur += i 16 | if cur == target: 17 | cur = 0 18 | count += 1 19 | return count == 3 20 | -------------------------------------------------------------------------------- /python/Array/Plus One/Plus One.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def plusOne(self, digits): 3 | """ 4 | :type digits: List[int] 5 | :rtype: List[int] 6 | """ 7 | res = [] 8 | cur = 1 9 | for d in digits[::-1]: 10 | res.append((d+cur)%10) 11 | cur = (d+cur)//10 12 | if cur: 13 | res.append(cur) 14 | return res[::-1] 15 | -------------------------------------------------------------------------------- /python/Array/Positions of Large Groups/Positions of Large Groups.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def largeGroupPositions(self, S): 3 | """ 4 | :type S: str 5 | :rtype: List[List[int]] 6 | """ 7 | i = 0 8 | j = 0 9 | res = [] 10 | while j < len(S) and i < len(S): 11 | while j + 1 < len(S) and S[j + 1] == S[j]: 12 | j += 1 13 | if j - i + 1 >= 3: 14 | res.append([i, j]) 15 | i = j + 1 16 | j = j + 1 17 | return res 18 | -------------------------------------------------------------------------------- /python/Array/Prime Arrangements/Prime Arrangements.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numPrimeArrangements(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | 8 | def helper(x): 9 | if x == 1: 10 | return 1 11 | else: 12 | return x * helper(x - 1) 13 | 14 | prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 15 | count = 0 16 | for i in prime: 17 | if i <= n: 18 | count += 1 19 | if count == 0: 20 | return helper(n) % (10 ** 9 + 7) 21 | elif count == n: 22 | return helper(count) % (10 ** 9 + 7) 23 | return (helper(count) * helper(n - count)) % (10 ** 9 + 7) 24 | -------------------------------------------------------------------------------- /python/Array/Queens That Can Attack the King/Queens That Can Attack the King.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def queensAttacktheKing(self, queens, king): 3 | """ 4 | :type queens: List[List[int]] 5 | :type king: List[int] 6 | :rtype: List[List[int]] 7 | """ 8 | queens = set([tuple(x) for x in queens]) 9 | res = [] 10 | 11 | for i in range(king[1] + 1, 8): 12 | if (king[0], i) in queens: 13 | res.append([king[0], i]) 14 | break 15 | 16 | for i in range(king[1] - 1, -1, -1): 17 | if (king[0], i) in queens: 18 | res.append([king[0], i]) 19 | break 20 | 21 | for i in range(king[0] + 1, 8): 22 | if (i, king[1]) in queens: 23 | res.append([i, king[1]]) 24 | break 25 | for i in range(king[0] - 1, -1, -1): 26 | if (i, king[1]) in queens: 27 | res.append([i, king[1]]) 28 | break 29 | 30 | for i in range(1, min(8 - king[1], 8 - king[0])): 31 | if (king[0] + i, king[1] + i) in queens: 32 | res.append([king[0] + i, king[1] + i]) 33 | break 34 | for i in range(1, min(8 - king[1], king[0] + 1)): 35 | if (king[0] - i, king[1] + i) in queens: 36 | res.append([king[0] - i, king[1] + i]) 37 | break 38 | 39 | for i in range(1, min(king[1] + 1, 8 - king[0])): 40 | if (king[0] + i, king[1] - i) in queens: 41 | res.append([king[0] + i, king[1] - i]) 42 | break 43 | 44 | for i in range(1, min(king[1] + 1, king[0] + 1)): 45 | if (king[0] - i, king[1] - i) in queens: 46 | res.append([king[0] - i, king[1] - i]) 47 | break 48 | 49 | return res 50 | -------------------------------------------------------------------------------- /python/Array/Remove Element/Remove Element.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeElement(self, nums, val): 3 | """ 4 | :type nums: List[int] 5 | :type val: int 6 | :rtype: int 7 | """ 8 | i = 0 9 | 10 | for j in range(len(nums)): 11 | if nums[j] != val: 12 | nums[i] = nums[j] 13 | i += 1 14 | return i 15 | -------------------------------------------------------------------------------- /python/Array/Search Insert Position/Search Insert Position.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def searchInsert(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: int 7 | """ 8 | left = 0 9 | right = len(nums) - 1 10 | 11 | while left <= right: 12 | mid = (left + right) // 2 13 | if nums[mid] == target: 14 | return mid 15 | elif nums[mid] > target: 16 | right = mid - 1 17 | else: 18 | left = mid + 1 19 | return left 20 | -------------------------------------------------------------------------------- /python/Array/Sort Array By Parity II/Sort Array By Parity II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def sortArrayByParityII(self, A): 3 | """ 4 | :type A: List[int] 5 | :rtype: List[int] 6 | """ 7 | i = 0 8 | 9 | for j in range(1, len(A), 2): 10 | if A[j] % 2 == 1: 11 | continue 12 | else: 13 | while i + 2 < len(A) and A[i] % 2 == 0: 14 | i += 2 15 | A[i], A[j] = A[j], A[i] 16 | i += 2 17 | return A 18 | -------------------------------------------------------------------------------- /python/Array/Sort Array By Parity/Sort Array By Parity.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def sortArrayByParity(self, A): 3 | """ 4 | :type A: List[int] 5 | :rtype: List[int] 6 | """ 7 | i = 0 8 | j = len(A)-1 9 | while i0 and A[j]%2==1: 13 | j-=1 14 | if 0<=i abs(A[j]): 14 | res.append(A[i] ** 2) 15 | i += 1 16 | else: 17 | res.append(A[j] ** 2) 18 | j -= 1 19 | return res[::-1] -------------------------------------------------------------------------------- /python/Array/Sum of Even Numbers After Queries/Sum of Even Numbers After Queries.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def sumEvenAfterQueries(self, A, queries): 3 | """ 4 | :type A: List[int] 5 | :type queries: List[List[int]] 6 | :rtype: List[int] 7 | """ 8 | ans = sum([i for i in A if i%2==0]) 9 | res = [] 10 | for v,i in queries: 11 | if A[i]%2==0: 12 | ans-=A[i] 13 | A[i]+=v 14 | if A[i]%2==0: 15 | ans+=A[i] 16 | res.append(ans) 17 | return res 18 | -------------------------------------------------------------------------------- /python/Array/Swap For Longest Repeated Character Substring/Swap For Longest Repeated Character Substring.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | class Solution: 4 | def maxRepOpt1(self, text): 5 | c = Counter(text) 6 | res = 0 7 | for i in range(len(text)): 8 | j = i 9 | current = text[i] 10 | diff = 0 11 | count = 0 12 | while j target: 15 | j -= 1 16 | else: 17 | i += 1 18 | -------------------------------------------------------------------------------- /python/Array/Unique Number of Occurrences/Unique Number of Occurrences.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution(object): 5 | def uniqueOccurrences(self, arr): 6 | """ 7 | :type arr: List[int] 8 | :rtype: bool 9 | """ 10 | c = Counter(arr) 11 | 12 | return len(c.values()) == len(set(c.values())) 13 | -------------------------------------------------------------------------------- /python/Array/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baldFemale/LeetCode-Solution/d89ebad5305e4d1a185b0c6f101a88691602b523/python/Array/__init__.py -------------------------------------------------------------------------------- /python/BFS/As Far from Land as Possible/As Far from Land as Possible.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class Solution(object): 5 | def maxDistance(self, grid): 6 | """ 7 | :type grid: List[List[int]] 8 | :rtype: int 9 | """ 10 | N = len(grid) 11 | queue = deque() 12 | for i in range(N): 13 | for j in range(N): 14 | if grid[i][j] == 1: 15 | queue.append((i, j)) 16 | if len(queue) == 0 or len(queue) == N * N: 17 | return -1 18 | level = 0 19 | while queue: 20 | size = len(queue) 21 | while size: 22 | size -= 1 23 | x, y = queue.popleft() 24 | for dx, dy in [[-1, 0], [1, 0], [0, 1], [0, -1]]: 25 | if 0 <= x + dx < N and 0 <= y + dy < N and grid[x + dx][y + dy] == 0: 26 | queue.append((x + dx, y + dy)) 27 | grid[x + dx][y + dy] = 1 28 | level += 1 29 | return level - 1 30 | -------------------------------------------------------------------------------- /python/BFS/Minimum Knight Moves/Minimum Knight Moves.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class Solution(object): 5 | def minKnightMoves(self, x, y): 6 | """ 7 | :type x: int 8 | :type y: int 9 | :rtype: int 10 | """ 11 | x = abs(x) 12 | y = abs(y) 13 | 14 | q = deque() 15 | seen = set() 16 | 17 | q.append((0, 0, 0)) 18 | 19 | while q: 20 | for i in range(len(q)): 21 | xx, yy, c = q.popleft() 22 | if xx == x and yy == y: 23 | return c 24 | if (xx, yy) in seen: 25 | continue 26 | seen.add((xx, yy)) 27 | 28 | for dx, dy in [[1, 2], [1, -2], [2, 1], [2, -1], [-1, 2], [-1, -2], [-2, 1], [-2, -1]]: 29 | if -2 < dx + xx <= x and -2 < dy + yy <= y: 30 | q.append((dx + xx, dy + yy, c + 1)) 31 | -------------------------------------------------------------------------------- /python/BFS/Minimum Moves to Reach Target with Rotations/Minimum Moves to Reach Target with Rotations.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minimumMoves(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | cur,cnt, n, seen = [(0,0,0)], 0 , len(grid),set([(0,0,0)]) 8 | while cur and (n-1,n-2,0) not in cur: 9 | cnt,tmp = cnt+1, [] 10 | for x,y,dx in cur: 11 | if dx==0: 12 | if y+2 < n and grid[x][y+2] == 0: tmp += [(x,y+1,dx)] 13 | if x+1 < n and (grid[x+1][y] + grid[x+1][y+1]) == 0: tmp += [(x,y,1),(x+1,y,0)] 14 | else: 15 | if x+2 < n and grid[x+2][y] == 0: tmp += [(x+1,y,dx)] 16 | if y+1 < n and (grid[x][y+1] + grid[x+1][y+1]) == 0: tmp += [(x,y,0),(x,y+1,1)] 17 | cur = set(tmp) - seen 18 | seen |= cur 19 | return cnt if cur else -1 -------------------------------------------------------------------------------- /python/BFS/Shortest Path Visiting All Nodes/Shortest Path Visiting All Nodes.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def shortestPathLength(self, graph): 6 | """ 7 | :type graph: List[List[int]] 8 | :rtype: int 9 | """ 10 | N = len(graph) 11 | queue = [(i, 1 << i) for i in range(N)] 12 | dist = defaultdict(lambda: N * N) 13 | for i in range(N): 14 | dist[(i, 1 << i)] = 0 15 | 16 | while queue: 17 | node, path = queue.pop(0) 18 | d = dist[(node, path)] 19 | if path == 2 ** N - 1: 20 | return d 21 | for nex in graph[node]: 22 | temp = (1 << nex) | path 23 | if dist[(nex, temp)] > d + 1: 24 | dist[(nex, temp)] = d + 1 25 | queue.append((nex, temp)) 26 | -------------------------------------------------------------------------------- /python/BFS/Shortest Path with Alternating Colors/Shortest Path with Alternating Colors.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def shortestAlternatingPaths(self, n, red_edges, blue_edges): 6 | """ 7 | :type n: int 8 | :type red_edges: List[List[int]] 9 | :type blue_edges: List[List[int]] 10 | :rtype: List[int] 11 | """ 12 | redGraph = defaultdict(list) 13 | blueGraph = defaultdict(list) 14 | 15 | for i, j in red_edges: 16 | redGraph[i].append(j) 17 | print(redGraph) 18 | for i, j in blue_edges: 19 | blueGraph[i].append(j) 20 | 21 | red_seen = set() 22 | blue_seen = set() 23 | queue = [] 24 | queue.append((0, 0)) 25 | queue.append((0, 1)) 26 | red_seen.add(0) 27 | blue_seen.add(0) 28 | 29 | step = 0 30 | res = [float("inf") for i in range(n)] 31 | 32 | while queue: 33 | size = len(queue) 34 | while size > 0: 35 | node, color = queue.pop(0) 36 | if color == 0: 37 | for nex in blueGraph[node]: 38 | if nex not in blue_seen: 39 | queue.append((nex, 1)) 40 | blue_seen.add(nex) 41 | res[nex] = min(res[nex], step + 1) 42 | else: 43 | for nex in redGraph[node]: 44 | if nex not in red_seen: 45 | queue.append((nex, 0)) 46 | red_seen.add(nex) 47 | res[nex] = min(res[nex], step + 1) 48 | size -= 1 49 | step += 1 50 | res[0] = 0 51 | return [i if i != float("inf") else -1 for i in res] 52 | 53 | -------------------------------------------------------------------------------- /python/BFS/Stepping Numbers/Stepping Numbers.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Solution(object): 5 | def countSteppingNumbers(self, low, high): 6 | """ 7 | :type low: int 8 | :type high: int 9 | :rtype: List[int] 10 | """ 11 | s = set([i for i in range(10)]) 12 | 13 | dic = {} 14 | dic[0] = s 15 | 16 | # print(s) 17 | 18 | for i in range(10): 19 | temp = set() 20 | for j in dic[i]: 21 | if j == 0: 22 | continue 23 | last = j % 10 24 | if last > 0: 25 | temp.add(j * 10 + last - 1) 26 | if last < 9: 27 | temp.add(j * 10 + last + 1) 28 | 29 | first = j // (10 ** (i)) 30 | if first > 1: 31 | temp.add((first - 1) * (10 ** (i + 1)) + j) 32 | if first < 9: 33 | temp.add((first + 1) * (10 ** (i + 1)) + j) 34 | dic[i + 1] = temp 35 | # print(temp) 36 | 37 | temp = [] 38 | for i in dic.values(): 39 | temp += list(i) 40 | temp.sort() 41 | left = bisect.bisect_left(temp, low) 42 | right = bisect.bisect_right(temp, high) 43 | return temp[left:right] 44 | -------------------------------------------------------------------------------- /python/Backtrack/Combination Sum II/Combination Sum II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: 3 | 4 | self.ans = [] 5 | 6 | def backtrack(tmp, cur): 7 | 8 | if sum(tmp) == target: 9 | self.ans.append(list(tmp)) 10 | elif sum(tmp) > target: 11 | pass 12 | else: 13 | for i in range(cur, len(candidates)): 14 | if visited[i] or (i > 0 and candidates[i - 1] == candidates[i] and not visited[i - 1]): 15 | continue 16 | else: 17 | tmp.append(candidates[i]) 18 | visited[i] = True 19 | backtrack(tmp, i + 1) 20 | tmp.pop() 21 | visited[i] = False 22 | 23 | candidates.sort() 24 | visited = [False] * len(candidates) 25 | backtrack([], 0) 26 | 27 | return self.ans 28 | 29 | -------------------------------------------------------------------------------- /python/Backtrack/Combination Sum III/Combination Sum III.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def combinationSum3(self, k: int, n: int) -> List[List[int]]: 3 | 4 | self.ans = [] 5 | 6 | def backtrack(tmp, cur): 7 | if len(tmp) == k and sum(tmp) == n: 8 | self.ans.append(list(tmp)) 9 | elif len(tmp) < k and sum(tmp) < n: 10 | for i in range(cur, 10): 11 | tmp.append(i) 12 | backtrack(tmp, i + 1) 13 | tmp.pop() 14 | 15 | backtrack([], 1) 16 | return self.ans 17 | -------------------------------------------------------------------------------- /python/Backtrack/Combination Sum/Combination Sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: 3 | 4 | self.ans = [] 5 | 6 | def backtrack(cur, tmp): 7 | if sum(tmp) == target: 8 | self.ans.append(list(tmp)) 9 | elif sum(tmp) > target: 10 | pass 11 | else: 12 | for i in range(cur, len(candidates)): 13 | tmp.append(candidates[i]) 14 | backtrack(i, tmp) 15 | tmp.pop() 16 | 17 | backtrack(0, []) 18 | 19 | return self.ans -------------------------------------------------------------------------------- /python/Backtrack/Permutations II/Permutations II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def permuteUnique(self, nums: List[int]) -> List[List[int]]: 3 | 4 | self.length = len(nums) 5 | self.ans = [] 6 | 7 | def backtrack(tmp): 8 | if len(tmp) == self.length: 9 | print(tmp) 10 | self.ans.append(list(tmp)) 11 | 12 | for i in range(self.length): 13 | if visited[i] or (i > 0 and nums[i] == nums[i - 1] and not visited[i - 1]): 14 | continue 15 | else: 16 | tmp.append(nums[i]) 17 | visited[i] = True 18 | backtrack(tmp) 19 | tmp.pop() 20 | visited[i] = False 21 | 22 | visited = [False] * self.length 23 | 24 | nums.sort() 25 | backtrack([]) 26 | 27 | return self.ans -------------------------------------------------------------------------------- /python/Backtrack/Permutations/Permutations.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def permute(self, nums: List[int]) -> List[List[int]]: 3 | 4 | self.length = len(nums) 5 | self.ans = [] 6 | 7 | def backtrack(tmp): 8 | if len(tmp) == self.length: 9 | self.ans.append(list(tmp)) 10 | 11 | for i in range(self.length): 12 | if visited[i]: 13 | continue 14 | else: 15 | tmp.append(nums[i]) 16 | visited[i] = True 17 | backtrack(tmp) 18 | tmp.pop() 19 | visited[i] = False 20 | 21 | visited = [False] * self.length 22 | 23 | backtrack([]) 24 | 25 | return self.ans 26 | -------------------------------------------------------------------------------- /python/Backtrack/Subsets II/Subsets II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: 3 | 4 | self.length = len(nums) 5 | self.ans = [] 6 | 7 | def backtrack(cur, tmp): 8 | 9 | self.ans.append(list(tmp)) 10 | 11 | for i in range(cur, self.length): 12 | if visited[i] or (i > 0 and nums[i - 1] == nums[i] and not visited[i - 1]): 13 | continue 14 | else: 15 | visited[i] = True 16 | tmp.append(nums[i]) 17 | backtrack(i + 1, tmp) 18 | tmp.pop() 19 | visited[i] = False 20 | 21 | visited = [False] * self.length 22 | nums.sort() 23 | backtrack(0, []) 24 | return self.ans 25 | -------------------------------------------------------------------------------- /python/Backtrack/Subsets/Subsets.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subsets(self, nums: List[int]) -> List[List[int]]: 3 | 4 | self.length = len(nums) 5 | self.ans = [] 6 | 7 | def backtrack(cur, tmp): 8 | 9 | self.ans.append(list(tmp)) 10 | 11 | for i in range(cur, self.length): 12 | if visited[i]: 13 | continue 14 | else: 15 | visited[i] = True 16 | tmp.append(nums[i]) 17 | backtrack(i + 1, tmp) 18 | tmp.pop() 19 | visited[i] = False 20 | 21 | visited = [False] * self.length 22 | backtrack(0, []) 23 | return self.ans 24 | 25 | -------------------------------------------------------------------------------- /python/Binary Search/Compare Strings by Frequency of the Smallest Character/Compare Strings by Frequency of the Smallest Character.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | import bisect 3 | 4 | 5 | class Solution(object): 6 | def numSmallerByFrequency(self, queries, words): 7 | """ 8 | :type queries: List[str] 9 | :type words: List[str] 10 | :rtype: List[int] 11 | """ 12 | w = [] 13 | for word in words: 14 | c = Counter(word) 15 | k = sorted(c.keys()) 16 | w.append(c[k[0]]) 17 | w.sort() 18 | 19 | res = [] 20 | for q in queries: 21 | c = Counter(q) 22 | k = sorted(c.keys()) 23 | t = c[k[0]] 24 | index = bisect.bisect(w, t) 25 | res.append(len(w) - index) 26 | return res 27 | -------------------------------------------------------------------------------- /python/Binary Search/Design A Leaderboard/Design A Leaderboard.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Leaderboard(object): 5 | 6 | def __init__(self): 7 | self.dic = {} 8 | self.scores = [] 9 | 10 | def addScore(self, playerId, score): 11 | """ 12 | :type playerId: int 13 | :type score: int 14 | :rtype: None 15 | """ 16 | if playerId not in self.dic: 17 | self.dic[playerId] = score 18 | index = bisect.bisect_left(self.scores, score) 19 | self.scores = self.scores[:index] + [score] + self.scores[index:] 20 | else: 21 | s = self.dic[playerId] 22 | index = bisect.bisect_left(self.scores, s) 23 | self.scores = self.scores[:index] + self.scores[index + 1:] 24 | 25 | self.dic[playerId] = score + s 26 | index = bisect.bisect_left(self.scores, score + s) 27 | self.scores = self.scores[:index] + [score + s] + self.scores[index:] 28 | # print(self.scores) 29 | # print(self.dic) 30 | 31 | def top(self, K): 32 | """ 33 | :type K: int 34 | :rtype: int 35 | """ 36 | # print(self.scores) 37 | # print(self.scores[::-1][:K]) 38 | # print(self.dic) 39 | return sum(self.scores[::-1][:K]) 40 | 41 | def reset(self, playerId): 42 | """ 43 | :type playerId: int 44 | :rtype: None 45 | """ 46 | s = self.dic[playerId] 47 | del (self.dic[playerId]) 48 | 49 | index = bisect.bisect_left(self.scores, s) 50 | self.scores = self.scores[:index] + self.scores[index + 1:] 51 | # print(self.scores) 52 | # print(self.dic) 53 | 54 | # Your Leaderboard object will be instantiated and called as such: 55 | # obj = Leaderboard() 56 | # obj.addScore(playerId,score) 57 | # param_2 = obj.top(K) 58 | # obj.reset(playerId) -------------------------------------------------------------------------------- /python/Binary Search/Divide Chocolate/Divide Chocolate.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maximizeSweetness(self, sweetness, K): 3 | """ 4 | :type sweetness: List[int] 5 | :type K: int 6 | :rtype: int 7 | """ 8 | 9 | def check(chunk): 10 | count = 0 11 | cur = 0 12 | for i in sweetness: 13 | cur += i 14 | if cur >= chunk: 15 | count += 1 16 | cur = 0 17 | return count >= K + 1 18 | 19 | left = 1 20 | right = sum(sweetness) // (K + 1) 21 | 22 | while left < right: 23 | mid = (left + right + 1) // 2 24 | if check(mid): 25 | left = mid 26 | else: 27 | right = mid - 1 28 | return right 29 | 30 | -------------------------------------------------------------------------------- /python/Binary Search/Find K-th Smallest Pair Distance/Find K-th Smallest Pair Distance.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def smallestDistancePair(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: int 7 | """ 8 | nums.sort() 9 | 10 | def count(val): 11 | c = 0 12 | left = 0 13 | 14 | for right in range(len(nums)): 15 | while nums[right] - nums[left] > val: 16 | left += 1 17 | c += right - left 18 | return c >= k 19 | 20 | low = 0 21 | high = nums[-1] - nums[0] 22 | while low < high: 23 | mid = (low + high) // 2 24 | if count(mid): 25 | high = mid 26 | else: 27 | low = mid + 1 28 | return low 29 | -------------------------------------------------------------------------------- /python/Binary Search/Find Minimum in Rotated Sorted Array II/Find Minimum in Rotated Sorted Array II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findMin(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | left = 0 8 | right = len(nums) - 1 9 | 10 | while left < right: 11 | mid = (left + right) // 2 12 | if nums[left] > nums[mid]: 13 | right = mid 14 | left += 1 15 | else: 16 | if nums[mid] > nums[right]: 17 | left = mid + 1 18 | else: 19 | right -= 1 20 | 21 | return nums[left] 22 | -------------------------------------------------------------------------------- /python/Binary Search/Find Positive Integer Solution for a Given Equation/Find Positive Integer Solution for a Given Equation.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findSolution(self, customfunction, z): 3 | """ 4 | :type num: int 5 | :type z: int 6 | :rtype: List[List[int]] 7 | """ 8 | res = [] 9 | for i in range(1,1001): 10 | for j in range(1,1001): 11 | if customfunction.f(i,j)==z: 12 | res.append([i,j]) 13 | elif customfunction.f(i,j)>z: 14 | break 15 | if customfunction.f(i,1)>z: 16 | break 17 | return res -------------------------------------------------------------------------------- /python/Binary Search/Kth Smallest Number in Multiplication Table/Kth Smallest Number in Multiplication Table.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findKthNumber(self, m, n, k): 3 | """ 4 | :type m: int 5 | :type n: int 6 | :type k: int 7 | :rtype: int 8 | """ 9 | 10 | def count(val): 11 | count = 0 12 | j = n 13 | 14 | for i in range(1, m + 1): 15 | while i * j > val: 16 | j -= 1 17 | count += j 18 | return count >= k 19 | 20 | lo = 0 21 | high = m * n 22 | while lo < high: 23 | mid = (lo + high) // 2 24 | if count(mid): 25 | high = mid 26 | else: 27 | lo = mid + 1 28 | return lo 29 | -------------------------------------------------------------------------------- /python/Binary Search/Number of Ships in a Rectangle/Number of Ships in a Rectangle.py: -------------------------------------------------------------------------------- 1 | # """ 2 | # This is Sea's API interface. 3 | # You should not implement it, or speculate about its implementation 4 | # """ 5 | class Sea(object): 6 | def hasShips(self, topRight: 'Point', bottomLeft: 'Point') -> bool: 7 | 8 | class Point(object): 9 | def __init__(self, x: int, y: int): 10 | self.x = x 11 | self.y = y 12 | 13 | class Solution(object): 14 | def countShips(self, sea: 'Sea', topRight: 'Point', bottomLeft: 'Point') -> int: 15 | # print(topRight.x,topRight.y,bottomLeft.x,bottomLeft.y) 16 | if topRight.x < bottomLeft.x or topRight.y < bottomLeft.y or (not sea.hasShips(topRight, bottomLeft)): 17 | return 0 18 | elif topRight.x == bottomLeft.x and topRight.y == bottomLeft.y: 19 | return 1 20 | else: 21 | mid_x = (topRight.x + bottomLeft.x) // 2 22 | mid_y = (topRight.y + bottomLeft.y) // 2 23 | return self.countShips(sea, Point(mid_x, mid_y), bottomLeft) + self.countShips(sea, 24 | Point(topRight.x, mid_y), 25 | Point(mid_x + 1, 26 | bottomLeft.y)) + self.countShips( 27 | sea, topRight, Point(mid_x + 1, mid_y + 1)) + self.countShips(sea, Point(mid_x, topRight.y), 28 | Point(bottomLeft.x, mid_y + 1)) 29 | 30 | 31 | -------------------------------------------------------------------------------- /python/Binary Search/Online Majority Element In Subarray/Online Majority Element In Subarray.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | from collections import defaultdict 3 | 4 | 5 | class MajorityChecker(object): 6 | 7 | def __init__(self, arr): 8 | """ 9 | :type arr: List[int] 10 | """ 11 | self.d = defaultdict(list) 12 | for i, j in enumerate(arr): 13 | self.d[j].append(i) 14 | 15 | def query(self, left, right, threshold): 16 | """ 17 | :type left: int 18 | :type right: int 19 | :type threshold: int 20 | :rtype: int 21 | """ 22 | for k, v in self.d.items(): 23 | if len(v) < threshold: 24 | continue 25 | left_index = bisect.bisect_left(v, left) 26 | right_index = bisect.bisect_right(v, right) 27 | if right_index - left_index >= threshold: 28 | return k 29 | return -1 30 | 31 | # Your MajorityChecker object will be instantiated and called as such: 32 | # obj = MajorityChecker(arr) 33 | # param_1 = obj.query(left,right,threshold) 34 | -------------------------------------------------------------------------------- /python/Binary Search/Search in Rotated Sorted Array II/Search in Rotated Sorted Array II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def search(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: bool 7 | """ 8 | if not nums: 9 | return False 10 | left = 0 11 | right = len(nums) - 1 12 | 13 | while left < right: 14 | mid = (left + right) // 2 15 | if target == nums[mid]: 16 | return True 17 | if nums[left] == nums[right] == nums[mid]: 18 | left += 1 19 | right -= 1 20 | else: 21 | 22 | if nums[mid] >= nums[left]: 23 | if nums[left] <= target < nums[mid]: 24 | right = mid - 1 25 | else: 26 | left = mid + 1 27 | else: 28 | if nums[mid] < target <= nums[right]: 29 | left = mid + 1 30 | else: 31 | right = mid - 1 32 | 33 | print(left, right) 34 | if nums[left] == target: 35 | return True 36 | return False 37 | -------------------------------------------------------------------------------- /python/Binary Search/Shortest Distance to Target Color/Shortest Distance to Target Color.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Solution: 5 | def shortestDistanceColor(self, colors, queries): 6 | """ 7 | :type colors: List[int] 8 | :type queries: List[List[int]] 9 | :rtype: List[int] 10 | """ 11 | dic = { 12 | 1: [], 13 | 2: [], 14 | 3: [] 15 | } 16 | 17 | for i, j in enumerate(colors): 18 | if j == 1: 19 | dic[1].append(i) 20 | elif j == 2: 21 | dic[2].append(i) 22 | else: 23 | dic[3].append(i) 24 | res = [] 25 | for q in queries: 26 | index, color = q[0], q[1] 27 | if len(dic[color]) == 0: 28 | res.append(-1) 29 | elif colors[index] == color: 30 | res.append(0) 31 | else: 32 | i = bisect.bisect(dic[color], index) 33 | if i == 0: 34 | res.append(dic[color][0] - index) 35 | elif i == len(dic[color]): 36 | res.append(index - dic[color][-1]) 37 | else: 38 | res.append(min(index - dic[color][i - 1], dic[color][i] - index)) 39 | return res 40 | 41 | -------------------------------------------------------------------------------- /python/Binary Search/Snapshot Array/Snapshot Array.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class SnapshotArray(object): 5 | 6 | def __init__(self, length): 7 | """ 8 | :type length: int 9 | """ 10 | self.snap_id = 0 11 | self.array = [[[-1, 0]] for i in range(length)] 12 | 13 | def set(self, index, val): 14 | """ 15 | :type index: int 16 | :type val: int 17 | :rtype: None 18 | """ 19 | self.array[index].append([self.snap_id, val]) 20 | 21 | def snap(self): 22 | """ 23 | :rtype: int 24 | """ 25 | self.snap_id += 1 26 | return self.snap_id - 1 27 | 28 | def get(self, index, snap_id): 29 | """ 30 | :type index: int 31 | :type snap_id: int 32 | :rtype: int 33 | """ 34 | i = bisect.bisect(self.array[index], [snap_id + 1, 0]) - 1 35 | return self.array[index][i][1] 36 | 37 | # Your SnapshotArray object will be instantiated and called as such: 38 | # obj = SnapshotArray(length) 39 | # obj.set(index,val) 40 | # param_2 = obj.snap() 41 | # param_3 = obj.get(index,snap_id) 42 | -------------------------------------------------------------------------------- /python/Binary Search/Ugly Number III/Ugly Number III.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def nthUglyNumber(self, n, a, b, c): 3 | """ 4 | :type n: int 5 | :type a: int 6 | :type b: int 7 | :type c: int 8 | :rtype: int 9 | """ 10 | 11 | def gcd(a, b): 12 | if b == 0: 13 | return a 14 | else: 15 | return gcd(b, a % b) 16 | 17 | ab = a * b // gcd(a, b) 18 | ac = a * c // gcd(a, c) 19 | bc = b * c // gcd(b, c) 20 | abc = ab * c // gcd(ab, c) 21 | 22 | low = 1 23 | high = 2 * 10 ** 9 24 | 25 | while low < high: 26 | mid = (low + high) // 2 27 | 28 | count = mid // a + mid // b + mid // c - mid // ab - mid // ac - mid // bc + mid // abc 29 | 30 | if count < n: 31 | low = mid + 1 32 | else: 33 | high = mid 34 | return low 35 | -------------------------------------------------------------------------------- /python/Bitwise/Circular Permutation in Binary Representation/Circular Permutation in Binary Representation.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def circularPermutation(self, n, start): 3 | """ 4 | :type n: int 5 | :type start: int 6 | :rtype: List[int] 7 | """ 8 | 9 | def gray(x): 10 | if x == 1: 11 | return [0, 1] 12 | 13 | else: 14 | temp = gray(x - 1) 15 | return temp + [i + 2 ** (x - 1) for i in temp[::-1]] 16 | 17 | t = gray(n) 18 | 19 | for j, i in enumerate(t): 20 | if i == start: 21 | return t[j:] + t[:j] 22 | -------------------------------------------------------------------------------- /python/Bitwise/Number of Valid Words for Each Puzzle/Number of Valid Words for Each Puzzle.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | from itertools import product 3 | from itertools import compress 4 | 5 | 6 | class Solution(object): 7 | def findNumOfValidWords(self, words, puzzles): 8 | """ 9 | :type words: List[str] 10 | :type puzzles: List[str] 11 | :rtype: List[int] 12 | """ 13 | c = Counter("".join(sorted(set(w))) for w in words) 14 | res = [] 15 | for p in puzzles: 16 | count = 0 17 | for selec in product([1, 0], repeat=len(p) - 1): 18 | s = compress(p, [1] + list(selec)) 19 | count += c["".join(sorted(set(s)))] 20 | res.append(count) 21 | return res 22 | -------------------------------------------------------------------------------- /python/DFS/Number of Closed Islands/Number of Closed Islands.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def closedIsland(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | m = len(grid) 8 | n = len(grid[0]) 9 | self.seen = set() 10 | 11 | def dfs(i, j): 12 | if i == -1 or i == m: 13 | return True 14 | if j == -1 or j == n: 15 | return True 16 | 17 | self.seen.add((i, j)) 18 | 19 | if grid[i][j] == 1: 20 | return False 21 | 22 | tag = False 23 | for x, y in [[1, 0], [0, -1], [-1, 0], [0, 1]]: 24 | if (i + x, j + y) not in self.seen: 25 | t = dfs(i + x, j + y) 26 | tag = tag or t 27 | return tag 28 | 29 | res = 0 30 | for i in range(m): 31 | for j in range(n): 32 | if grid[i][j] == 0 and (i, j) not in self.seen: 33 | t = dfs(i, j) 34 | if not t: 35 | res += 1 36 | 37 | return res -------------------------------------------------------------------------------- /python/DFS/Path with Maximum Gold/Path with Maximum Gold.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def getMaximumGold(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | m = len(grid) 8 | n = len(grid[0]) 9 | self.res = -float("inf") 10 | 11 | def dfs(i, j, seen, s): 12 | seen.add((i, j)) 13 | self.res = max(self.res, s) 14 | for x, y in [[1, 0], [-1, 0], [0, 1], [0, -1]]: 15 | if 0 <= i + x < m and 0 <= j + y < n: 16 | if grid[x + i][j + y] != 0 and (x + i, j + y) not in seen: 17 | temp = set(seen) 18 | dfs(i + x, j + y, temp, s + grid[x + i][j + y]) 19 | 20 | for i in range(m): 21 | for j in range(n): 22 | if grid[i][j] != 0: 23 | dfs(i, j, set(), grid[i][j]) 24 | return self.res 25 | -------------------------------------------------------------------------------- /python/DFS/Unique Paths III/Unique Paths III.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def uniquePathsIII(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | m = len(grid) 8 | n = len(grid[0]) 9 | empty = 1 10 | self.res = 0 11 | 12 | for i in range(m): 13 | for j in range(n): 14 | if grid[i][j] == 0: 15 | empty += 1 16 | elif grid[i][j] == 1: 17 | start_x, start_y = i, j 18 | elif grid[i][j] == 2: 19 | end_x, end_y = i, j 20 | 21 | def dfs(x, y, empty): 22 | if not (0 <= x < m and 0 <= y < n): 23 | return 24 | if grid[x][y] < 0: 25 | return 26 | if (x, y) == (end_x, end_y): 27 | if empty == 0: 28 | self.res += 1 29 | return 30 | grid[x][y] = -2 31 | dfs(x + 1, y, empty - 1) 32 | dfs(x - 1, y, empty - 1) 33 | dfs(x, y + 1, empty - 1) 34 | dfs(x, y - 1, empty - 1) 35 | grid[x][y] = 0 36 | 37 | dfs(start_x, start_y, empty) 38 | return self.res 39 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Best Time to Buy and Sell Stock IV/Best Time to Buy and Sell Stock IV.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxProfit(self, k, prices): 3 | """ 4 | :type k: int 5 | :type prices: List[int] 6 | :rtype: int 7 | """ 8 | if not prices: 9 | return 0 10 | n = len(prices) 11 | 12 | if k >= n // 2: 13 | pre = prices[0] 14 | res = 0 15 | for p in prices[1:]: 16 | if p >= pre: 17 | res += p - pre 18 | pre = p 19 | return res 20 | 21 | else: 22 | dp = [[0 for i in range(n)] for j in range(k + 1)] 23 | for i in range(1, k + 1): 24 | temp = dp[i - 1][0] - prices[0] 25 | for j in range(1, n): 26 | dp[i][j] = max(dp[i][j - 1], prices[j] + temp) 27 | temp = max(temp, dp[i - 1][j] - prices[j]) 28 | return dp[-1][-1] 29 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Can I Win/Can I Win.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canIWin(self, maxChoosableInteger, desiredTotal): 3 | """ 4 | :type maxChoosableInteger: int 5 | :type desiredTotal: int 6 | :rtype: bool 7 | """ 8 | cache = {} 9 | allow = [i + 1 for i in range(maxChoosableInteger)] 10 | 11 | def dfs(allow, value): 12 | state = tuple(allow) 13 | if len(allow) == 0: 14 | cache[state] = False 15 | return False 16 | if state in cache: 17 | return cache[state] 18 | if value + max(allow) >= desiredTotal: 19 | cache[state] = True 20 | return True 21 | cache[state] = False 22 | for i in allow: 23 | temp_allow = [j for j in allow if j != i] 24 | if dfs(temp_allow, value + i) == False: 25 | cache[state] = True 26 | break 27 | return cache[state] 28 | 29 | return dfs(allow, 0) if maxChoosableInteger * (maxChoosableInteger + 1) >= desiredTotal else False 30 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Count Vowels Permutation/Count Vowels Permutation.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def countVowelPermutation(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | 8 | dp = [[0] * 5 for i in range(n)] 9 | 10 | dp[0] = [1] * 5 11 | 12 | for i in range(1, n): 13 | dp[i][0] = dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][4] 14 | dp[i][1] = dp[i - 1][0] + dp[i - 1][2] 15 | dp[i][2] = dp[i - 1][1] + dp[i - 1][3] 16 | dp[i][3] = dp[i - 1][2] 17 | dp[i][4] = dp[i - 1][2] + dp[i - 1][3] 18 | 19 | return sum(dp[-1]) % (10 ** 9 + 7) 20 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Dice Roll Simulation/Dice Roll Simulation.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def dieSimulator(self, n, rollMax): 6 | """ 7 | :type n: int 8 | :type rollMax: List[int] 9 | :rtype: int 10 | """ 11 | dd = defaultdict(dict) 12 | mod = 10 ** 9 + 7 13 | 14 | for i in range(1, 7): 15 | dd[i] = {1: 1} 16 | 17 | for i in range(1, n): 18 | temp = defaultdict(dict) 19 | for j in range(1, 7): 20 | s = 0 21 | for k in range(1, 7): 22 | if k != j: 23 | s += sum(dd[k].values()) % mod 24 | else: 25 | for kk in dd[j].keys(): 26 | if kk + 1 <= rollMax[k - 1]: 27 | temp[j][kk + 1] = dd[j][kk] % mod 28 | temp[j][1] = s 29 | dd = temp 30 | res = sum([sum(dd[k].values()) for k in range(1, 7)]) 31 | return res % mod 32 | 33 | 34 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Distinct Subsequences II/Distinct Subsequences II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def distinctSubseqII(self, S): 3 | """ 4 | :type S: str 5 | :rtype: int 6 | """ 7 | dp = [0 for i in range(len(S))] 8 | dp = [1]+dp 9 | last = {} 10 | for i in range(1,len(S)+1): 11 | dp[i] = dp[i-1]*2 12 | if S[i-1] in last: 13 | dp[i]-=dp[last[S[i-1]]-1] 14 | last[S[i-1]] = i 15 | return (dp[-1]-1)%(10**9+7) 16 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Distinct Subsequences/Distinct Subsequences.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numDistinct(self, s, t): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :rtype: int 7 | """ 8 | dp = [[0 for i in range(len(s) + 1)] for j in range(len(t) + 1)] 9 | 10 | for i in range(len(dp[0])): 11 | dp[0][i] = 1 12 | 13 | for i in range(len(dp) - 1): 14 | for j in range(len(dp[0]) - 1): 15 | if s[j] == t[i]: 16 | dp[i + 1][j + 1] = dp[i][j] + dp[i + 1][j] 17 | else: 18 | dp[i + 1][j + 1] = dp[i + 1][j] 19 | return dp[-1][-1] 20 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Dungeon Game/Dungeon Game.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def calculateMinimumHP(self, dungeon): 3 | """ 4 | :type dungeon: List[List[int]] 5 | :rtype: int 6 | """ 7 | M = len(dungeon) 8 | N = len(dungeon[0]) 9 | ma = float("inf") 10 | 11 | dp = [[ma for i in range(N)] for j in range(M)] 12 | dp[-1][-1] = 1 if dungeon[-1][-1] >= 0 else -dungeon[-1][-1] + 1 13 | 14 | for i in range(N - 2, -1, -1): 15 | if dungeon[-1][i] >= 0: 16 | if dp[-1][i + 1] > dungeon[-1][i]: 17 | dp[-1][i] = dp[-1][i + 1] - dungeon[-1][i] 18 | else: 19 | dp[-1][i] = 1 20 | else: 21 | dp[-1][i] = dp[-1][i + 1] - dungeon[-1][i] 22 | 23 | for i in range(M - 2, -1, -1): 24 | if dungeon[i][-1] >= 0: 25 | if dp[i + 1][-1] > dungeon[i][-1]: 26 | dp[i][-1] = dp[i + 1][-1] - dungeon[i][-1] 27 | else: 28 | dp[i][-1] = 1 29 | else: 30 | dp[i][-1] = dp[i + 1][-1] - dungeon[i][-1] 31 | 32 | for i in range(M - 2, -1, -1): 33 | for j in range(N - 2, -1, -1): 34 | if dungeon[i][j] < 0: 35 | dp[i][j] = -dungeon[i][j] + min(dp[i + 1][j], dp[i][j + 1]) 36 | else: 37 | if dp[i + 1][j] <= dungeon[i][j] or dp[i][j + 1] <= dungeon[i][j]: 38 | dp[i][j] = 1 39 | else: 40 | dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j] 41 | return dp[0][0] 42 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Frog Jump/Frog Jump.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canCross(self, stones): 3 | """ 4 | :type stones: List[int] 5 | :rtype: bool 6 | """ 7 | dic = {stones[i]: i for i in range(len(stones))} 8 | cache = {} 9 | 10 | def dp(i, k): 11 | if i == len(stones) - 1: 12 | cache[(i, k)] = True 13 | return True 14 | if (i, k) in cache: 15 | return cache[(i, k)] 16 | temp = False 17 | if stones[i] + k in dic and (stones[i] + k, k) not in cache: 18 | temp |= dp(dic[stones[i] + k], k) 19 | if stones[i] + k - 1 in dic and (stones[i] + k - 1, k - 1) not in cache and k - 1 != 0: 20 | temp |= dp(dic[stones[i] + k - 1], k - 1) 21 | if stones[i] + k + 1 in dic and (stones[i] + k + 1, k + 1) not in cache: 22 | temp |= dp(dic[stones[i] + k + 1], k + 1) 23 | cache[(i, k)] = temp 24 | return temp 25 | 26 | return dp(1, 1) if stones[0] + 1 == stones[1] else False 27 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Guess Number Higher or Lower II/Guess Number Higher or Lower II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def getMoneyAmount(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | 8 | cache = {} 9 | 10 | def dp(i, j): 11 | if (i, j) in cache: 12 | return cache[(i, j)] 13 | else: 14 | if i >= j: 15 | return 0 16 | res = float("inf") 17 | for cur in range(i, j + 1): 18 | res = min(res, cur + max(dp(i, cur - 1), dp(cur + 1, j))) 19 | cache[(i, j)] = res 20 | return res 21 | 22 | return dp(1, n) 23 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Knight Dialer/Knight Dialer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def knightDialer(self, N): 3 | """ 4 | :type N: int 5 | :rtype: int 6 | """ 7 | 8 | dp = [1] * 10 9 | mod = 10 ** 9 + 7 10 | 11 | for i in range(1, N): 12 | temp = list(dp) 13 | dp[0] = (temp[4] + temp[6]) % mod 14 | dp[1] = (temp[6] + temp[8]) % mod 15 | dp[2] = (temp[7] + temp[9]) % mod 16 | dp[3] = (temp[4] + temp[8]) % mod 17 | dp[4] = (temp[3] + temp[9] + temp[0]) % mod 18 | dp[6] = (temp[1] + temp[7] + temp[0]) % mod 19 | dp[7] = (temp[2] + temp[6]) % mod 20 | dp[8] = (temp[1] + temp[3]) % mod 21 | dp[9] = (temp[2] + temp[4]) % mod 22 | return (sum(dp) - dp[5]) % mod if N > 1 else 10 -------------------------------------------------------------------------------- /python/Dynamic Programming/Largest Divisible Subset/Largest Divisible Subset.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def largestDivisibleSubset(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[int] 6 | """ 7 | if len(nums) <= 1: 8 | return nums 9 | nums.sort() 10 | 11 | dp = [1 for i in range(len(nums))] 12 | parent = {} 13 | count = 0 14 | maxindex = None 15 | 16 | for i in range(len(nums)): 17 | for j in range(i): 18 | if nums[i] % nums[j] == 0: 19 | if dp[j] + 1 > dp[i]: 20 | dp[i] = dp[j] + 1 21 | parent[i] = j 22 | if dp[i] > count: 23 | count = dp[i] 24 | maxindex = i 25 | 26 | if not maxindex: 27 | return [nums[0]] 28 | 29 | res = [] 30 | while maxindex in parent: 31 | res.append(nums[maxindex]) 32 | maxindex = parent[maxindex] 33 | res.append(nums[maxindex]) 34 | return res[::-1] 35 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Longest Arithmetic Subsequence of Given Difference/Longest Arithmetic Subsequence of Given Difference.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def longestSubsequence(self, arr, difference): 6 | """ 7 | :type arr: List[int] 8 | :type difference: int 9 | :rtype: int 10 | """ 11 | index = defaultdict(list) 12 | for i, j in enumerate(arr): 13 | index[j].append(i) 14 | 15 | s = set(arr) 16 | 17 | dp = {i: 1 for i in range(len(arr))} 18 | 19 | for i in range(len(arr)): 20 | if arr[i] + difference in s: 21 | for j in index[arr[i] + difference]: 22 | if j > i: 23 | dp[j] = max(dp[j], dp[i] + 1) 24 | # print(dp) 25 | 26 | return max(dp.values()) 27 | 28 | 29 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Longest Common Subsequence/Longest Common Subsequence.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def longestCommonSubsequence(self, text1, text2): 3 | """ 4 | :type text1: str 5 | :type text2: str 6 | :rtype: int 7 | """ 8 | n = len(text1) 9 | m = len(text2) 10 | dp = [[0 for i in range(n + 1)] for j in range(m + 1)] 11 | 12 | for i in range(m): 13 | for j in range(n): 14 | if text2[i] == text1[j]: 15 | dp[i + 1][j + 1] = max(dp[i][j] + 1, dp[i][j + 1], dp[i][j + 1]) 16 | else: 17 | dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]) 18 | print(dp) 19 | return dp[-1][-1] 20 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Longest Increasing Subsequence/Longest Increasing Subsequence.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Solution(object): 5 | def lengthOfLIS(self, nums): 6 | """ 7 | :type nums: List[int] 8 | :rtype: int 9 | """ 10 | dp = [] 11 | res = 0 12 | for i in nums: 13 | index = bisect.bisect_left(dp,i) 14 | if index==len(dp): 15 | dp.append(i) 16 | res = max(res,len(dp)) 17 | else: 18 | dp[index] = i 19 | return res 20 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Make Array Strictly Increasing/Make Array Strictly Increasing.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | from collections import defaultdict 3 | 4 | 5 | class Solution: 6 | def makeArrayIncreasing(self, arr1, arr2): 7 | """ 8 | :type arr1: List[int] 9 | :type arr2: List[int] 10 | :rtype: int 11 | """ 12 | 13 | dp = {-1: 0} 14 | 15 | arr2.sort() 16 | 17 | for i in arr1: 18 | tmp = defaultdict(lambda: float("inf")) 19 | 20 | for k in dp.keys(): 21 | if i > k: 22 | tmp[i] = min(tmp[i], dp[k]) 23 | 24 | index = bisect.bisect(arr2, k) 25 | if index < len(arr2): 26 | tmp[arr2[index]] = min(tmp[arr2[index]], dp[k] + 1) 27 | dp = tmp 28 | if dp: 29 | return min(dp.values()) 30 | return -1 31 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Maximum Length of a Concatenated String with Unique Characters/Maximum Length of a Concatenated String with Unique Characters.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxLength(self, arr): 3 | """ 4 | :type arr: List[str] 5 | :rtype: int 6 | """ 7 | 8 | dp = [set()] 9 | 10 | for i in arr: 11 | if len(set(i)) != len(i): 12 | continue 13 | 14 | for c in dp: 15 | if set(i) & c: 16 | continue 17 | else: 18 | dp.append(set(i) | c) 19 | return max(len(i) for i in dp) 20 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Maximum Profit in Job Scheduling/Maximum Profit in Job Scheduling.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Solution(object): 5 | def jobScheduling(self, startTime, endTime, profit): 6 | """ 7 | :type startTime: List[int] 8 | :type endTime: List[int] 9 | :type profit: List[int] 10 | :rtype: int 11 | """ 12 | 13 | jobs = [(startTime[i], endTime[i], profit[i]) for i in range(len(profit))] 14 | jobs.sort(key=lambda x: x[0]) 15 | starts = [i[0] for i in jobs] 16 | print(jobs) 17 | cache = {} 18 | 19 | def dp(x): 20 | if x in cache: 21 | return cache[x] 22 | 23 | else: 24 | if x >= len(profit): 25 | cache[x] = 0 26 | return 0 27 | 28 | else: 29 | s, e, p = jobs[x] 30 | index = bisect.bisect_left(starts, e) 31 | p += dp(index) 32 | cache[x] = max(p, dp(x + 1)) 33 | 34 | return cache[x] 35 | 36 | return dp(0) 37 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Maximum Score Words Formed by Letters/Maximum Score Words Formed by Letters.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxScoreWords(self, words, letters, score): 3 | """ 4 | :type words: List[str] 5 | :type letters: List[str] 6 | :type score: List[int] 7 | :rtype: int 8 | """ 9 | 10 | def check(word, state): 11 | for j in word: 12 | state[ord(j) - ord("a")] -= 1 13 | if state[ord(j) - ord("a")] < 0: 14 | return False, None 15 | return True, state 16 | 17 | def get_score(word): 18 | res = 0 19 | for j in word: 20 | res += score[ord(j) - ord("a")] 21 | return res 22 | 23 | state = [0 for i in range(26)] 24 | for i in letters: 25 | state[ord(i) - ord("a")] += 1 26 | 27 | word_index = [1 for i in range(len(words))] 28 | cache = {} 29 | 30 | def dp(state, word_index): 31 | if tuple(state + word_index) in cache: 32 | return cache[tuple(state + word_index)] 33 | res = 0 34 | for i, w in enumerate(word_index): 35 | if w == 1: 36 | tag, temp_state = check(words[i], list(state)) 37 | if tag == True: 38 | res = max(res, get_score(words[i]) + dp(temp_state, word_index[:i] + [0] + word_index[i + 1:])) 39 | cache[tuple(state + word_index)] = res 40 | return res 41 | 42 | return dp(state, word_index) 43 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Minimum Cost For Tickets/Minimum Cost For Tickets.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def mincostTickets(self, days, costs): 3 | """ 4 | :type days: List[int] 5 | :type costs: List[int] 6 | :rtype: int 7 | """ 8 | dp = [float("inf") for day in range(366)] 9 | dp[0] = 0 10 | 11 | days = set(days) 12 | 13 | for day in range(1, 366): 14 | if day not in days: 15 | dp[day] = dp[day - 1] 16 | else: 17 | dp[day] = min(dp[day], dp[day - 1] + costs[0]) 18 | dp[day] = min(dp[day], dp[max(0, day - 7)] + costs[1]) 19 | dp[day] = min(dp[day], dp[max(0, day - 30)] + costs[2]) 20 | return dp[-1] -------------------------------------------------------------------------------- /python/Dynamic Programming/Minimum Cost to Merge Stones/Minimum Cost to Merge Stones.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def mergeStones(self, stones, K): 3 | """ 4 | :type stones: List[int] 5 | :type K: int 6 | :rtype: int 7 | """ 8 | N = len(stones) 9 | prefix = [0 for i in range(N + 1)] 10 | for i in range(N): 11 | prefix[i + 1] += (prefix[i] + stones[i]) 12 | 13 | inf = float("inf") 14 | 15 | import functools 16 | 17 | @functools.lru_cache(None) 18 | def dp(i, j, m): 19 | if (j - i + 1 - m) % (K - 1) != 0: 20 | return inf 21 | if i == j: 22 | return inf if m != 1 else 0 23 | if m == 1: 24 | return dp(i, j, K) + prefix[j + 1] - prefix[i] 25 | 26 | return min(dp(i, mid, 1) + dp(mid + 1, j, m - 1) for mid in range(i, j)) 27 | 28 | res = dp(0, N - 1, 1) 29 | return res if res != inf else -1 30 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Minimum Falling Path Sum/Minimum Falling Path Sum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minFallingPathSum(self, A): 3 | """ 4 | :type A: List[List[int]] 5 | :rtype: int 6 | """ 7 | dp = A[0] 8 | 9 | for row in A[1:]: 10 | temp = [float("inf")] + dp + [float("inf")] 11 | for i in range(1, len(A) + 1): 12 | dp[i - 1] = row[i - 1] + min(temp[i - 1:i + 2]) 13 | return min(dp) -------------------------------------------------------------------------------- /python/Dynamic Programming/Minimum Number of Refueling Stops/Minimum Number of Refueling Stops.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minRefuelStops(self, target, startFuel, stations): 3 | """ 4 | :type target: int 5 | :type startFuel: int 6 | :type stations: List[List[int]] 7 | :rtype: int 8 | """ 9 | dp = [0 for i in range(len(stations))] 10 | 11 | dp = [startFuel] + dp 12 | 13 | for i in range(len(stations)): 14 | for j in range(i, -1, -1): 15 | if stations[i][0] <= dp[j]: 16 | dp[j + 1] = max(dp[j + 1], dp[j] + stations[i][1]) 17 | for i in range(len(dp)): 18 | if dp[i] >= target: 19 | return i 20 | return -1 21 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Number of Dice Rolls With Target Sum/Number of Dice Rolls With Target Sum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numRollsToTarget(self, d, f, target): 3 | """ 4 | :type d: int 5 | :type f: int 6 | :type target: int 7 | :rtype: int 8 | """ 9 | self.cache = {} 10 | def dp(d,target): 11 | if (d,target) in self.cache: 12 | return self.cache[(d,target)] 13 | if target>d*f or target=target: 17 | self.cache[(d,target)] = 1 18 | return 1 19 | else: 20 | s = 0 21 | for i in range(1,f+1): 22 | s+=dp(d-1,target-i) 23 | self.cache[(d,target)] = s 24 | return s 25 | return dp(d,target)%(10**9+7) 26 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Number of Subarrays with Bounded Maximum/Number of Subarrays with Bounded Maximum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numSubarrayBoundedMax(self, A, L, R): 3 | """ 4 | :type A: List[int] 5 | :type L: int 6 | :type R: int 7 | :rtype: int 8 | """ 9 | 10 | dp = [0 for i in range(len(A) + 1)] 11 | pre = -1 12 | 13 | for i in range(len(A)): 14 | if A[i] < L: 15 | dp[i + 1] = dp[i] 16 | elif A[i] > R: 17 | pre = i 18 | else: 19 | dp[i + 1] = i - pre 20 | return sum(dp) 21 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Numbers With Same Consecutive Differences/Numbers With Same Consecutive Differences.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numsSameConsecDiff(self, N, K): 3 | """ 4 | :type N: int 5 | :type K: int 6 | :rtype: List[int] 7 | """ 8 | cur = [i for i in range(1,10)] 9 | if N==1: 10 | return [0]+cur 11 | while N>1: 12 | temp = [] 13 | N-=1 14 | for i in cur: 15 | last = i%10 16 | if last+K<10: 17 | temp.append(i*10+K+last) 18 | if last-K>=0: 19 | temp.append(i*10-K+last) 20 | cur = list(set(temp)) 21 | return cur 22 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Palindrome Partitioning III/Palindrome Partitioning III.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def palindromePartition(self, s: str, k: int) -> int: 3 | 4 | def count(s): 5 | temp_s = s[::-1] 6 | c = 0 7 | for i in range(len(s) // 2): 8 | if s[i] != temp_s[i]: 9 | c += 1 10 | return c 11 | 12 | cache = {} 13 | 14 | def dp(i, j): 15 | if (i, j) in cache: 16 | return cache[(i, j)] 17 | 18 | if i + 1 == j: 19 | cache[(i, j)] = 0 20 | return 0 21 | 22 | if j == 1: 23 | cache[(i, j)] = count(s[:i + 1]) 24 | return cache[(i, j)] 25 | 26 | temp = 1000 27 | for cur in range(j - 1, i + 1): 28 | temp = min(temp, dp(cur - 1, j - 1) + count(s[cur:i + 1])) 29 | cache[(i, j)] = temp 30 | return temp 31 | 32 | return dp(len(s) - 1, k) 33 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Palindrome Removal/Palindrome Removal.py: -------------------------------------------------------------------------------- 1 | from functools import lru_cache 2 | 3 | 4 | class Solution(object): 5 | def minimumMoves(self, arr): 6 | """ 7 | :type arr: List[int] 8 | :rtype: int 9 | """ 10 | 11 | @lru_cache(None) 12 | def dp(i, j): 13 | if i > j: 14 | return 0 15 | 16 | res = 1 + dp(i, j - 1) 17 | if arr[j] == arr[j - 1]: 18 | res = 1 + dp(i, j - 2) 19 | 20 | for k in range(i, j - 1): 21 | if arr[j] == arr[k]: 22 | res = min(res, dp(i, k - 1) + dp(k + 1, j - 1)) 23 | return res 24 | 25 | return dp(0, len(arr) - 1) 26 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Russian Doll Envelopes/Russian Doll Envelopes.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Solution(object): 5 | def maxEnvelopes(self, envelopes): 6 | """ 7 | :type envelopes: List[List[int]] 8 | :rtype: int 9 | """ 10 | if not envelopes: 11 | return 0 12 | 13 | envelopes.sort(key=lambda x: (x[0], -x[1])) 14 | 15 | temp = [i[1] for i in envelopes] 16 | 17 | dp = [] 18 | res = 0 19 | for i in temp: 20 | index = bisect.bisect_left(dp, i) 21 | if index == len(dp): 22 | dp.append(i) 23 | res = max(res, len(dp)) 24 | else: 25 | dp[index] = i 26 | return res 27 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Smallest Sufficient Team/Smallest Sufficient Team.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Solution(object): 4 | def smallestSufficientTeam(self, req_skills, people): 5 | """ 6 | :type req_skills: List[str] 7 | :type people: List[List[str]] 8 | :rtype: List[int] 9 | """ 10 | n, m = len(req_skills), len(people) 11 | 12 | key = {i: j for j, i in enumerate(req_skills)} 13 | dp = {0: []} 14 | 15 | for i, p in enumerate(people): 16 | his_skill = 0 17 | for sk in p: 18 | if sk in key: 19 | his_skill |= 1 << key[sk] 20 | 21 | for skill_set, need in dp.items(): 22 | with_him = skill_set | his_skill 23 | if with_him == skill_set: 24 | continue 25 | if with_him not in dp or len(dp[with_him]) > len(need) + 1: 26 | dp[with_him] = need + [i] 27 | return dp[(1 << n) - 1] 28 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Stone Game II/Stone Game II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def stoneGameII(self, piles): 3 | """ 4 | :type piles: List[int] 5 | :rtype: int 6 | """ 7 | 8 | a = [] 9 | for p in piles[::-1]: 10 | if not a: 11 | a.append(p) 12 | else: 13 | a.append(p + a[-1]) 14 | a = a[::-1] 15 | 16 | from functools import lru_cache 17 | @lru_cache(None) 18 | def dp(i, m): 19 | if i + 2 * m >= len(piles): 20 | return a[i] 21 | else: 22 | return a[i] - min(dp(i + x, max(m, x)) for x in range(1, 2 * m + 1)) 23 | 24 | return dp(0, 1) 25 | tt56 -------------------------------------------------------------------------------- /python/Dynamic Programming/Tallest Billboard/Tallest Billboard.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def tallestBillboard(self, rods): 3 | """ 4 | :type rods: List[int] 5 | :rtype: int 6 | """ 7 | dp = {0: 0} 8 | 9 | for r in rods: 10 | for d, s in dp.items(): 11 | dp[d + r] = max(dp.get(d + r, 0), s) 12 | if d >= r: 13 | dp[d - r] = max(dp.get(d - r, 0), s + r) 14 | else: 15 | dp[r - d] = max(dp.get(r - d, 0), s + d) 16 | return dp[0] 17 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Tiling a Rectangle with the Fewest Squares/Tiling a Rectangle with the Fewest Squares.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def tilingRectangle(self, n, m): 3 | """ 4 | :type n: int 5 | :type m: int 6 | :rtype: int 7 | """ 8 | 9 | MAX = 14 10 | self.dp = [[0 for i in range(MAX)] for i in range(MAX)] 11 | 12 | def minimumSquare(m, n): 13 | 14 | vertical_min = 10000000000 15 | horizontal_min = 10000000000 16 | 17 | if m == n: 18 | return 1 19 | 20 | if self.dp[m][n] != 0: 21 | return self.dp[m][n] 22 | 23 | for i in range(1, m // 2 + 1): 24 | horizontal_min = min(minimumSquare(i, n) + 25 | minimumSquare(m - i, n), horizontal_min) 26 | for j in range(1, n // 2 + 1): 27 | vertical_min = min(minimumSquare(m, j) + 28 | minimumSquare(m, n - j), vertical_min) 29 | self.dp[m][n] = min(vertical_min, horizontal_min) 30 | return self.dp[m][n] 31 | 32 | if (n == 11 and m == 13) or (n == 13 and m == 11): 33 | return 6 34 | return minimumSquare(n, m) 35 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Toss Strange Coins/Toss Strange Coins.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def probabilityOfHeads(self, prob, target): 3 | """ 4 | :type prob: List[float] 5 | :type target: int 6 | :rtype: float 7 | """ 8 | cache = {} 9 | 10 | def dp(l, n): 11 | if (l, n) in cache: 12 | return cache[(l, n)] 13 | if n > l: 14 | cache[(l, n)] = 0 15 | return 0 16 | else: 17 | if l == 1: 18 | if n == 0: 19 | cache[(l, n)] = 1 - prob[0] 20 | return 1 - prob[0] 21 | else: 22 | cache[(l, n)] = prob[0] 23 | return prob[0] 24 | else: 25 | if n == 0: 26 | cache[(l, n)] = (1 - prob[l - 1]) * dp(l - 1, 0) 27 | return cache[(l, n)] 28 | 29 | else: 30 | cache[(l, n)] = (1 - prob[l - 1]) * dp(l - 1, n) + (prob[l - 1]) * dp(l - 1, n - 1) 31 | return cache[(l, n)] 32 | 33 | return dp(len(prob), target) 34 | -------------------------------------------------------------------------------- /python/Dynamic Programming/Valid Palindrome III/Valid Palindrome III.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isValidPalindrome(self, s, k): 3 | """ 4 | :type s: str 5 | :type k: int 6 | :rtype: bool 7 | """ 8 | 9 | def isKPalDP(str1, str2, m, n): 10 | dp = [[0] * (n + 1) for _ in range(m + 1)] 11 | 12 | for i in range(m + 1): 13 | for j in range(n + 1): 14 | if not i: 15 | dp[i][j] = j 16 | elif not j: 17 | dp[i][j] = i 18 | elif str1[i - 1] == str2[j - 1]: 19 | dp[i][j] = dp[i - 1][j - 1] 20 | else: 21 | dp[i][j] = 1 + min(dp[i - 1][j], 22 | (dp[i][j - 1])) 23 | print(dp) 24 | return dp[m][n] 25 | 26 | return isKPalDP(s, s[::-1], len(s), len(s)) <= k * 2 27 | -------------------------------------------------------------------------------- /python/Graph/Cheapest Flights Within K Stops/Cheapest Flights Within K Stops.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from collections import defaultdict 3 | 4 | 5 | class Solution(object): 6 | def findCheapestPrice(self, n, flights, src, dst, K): 7 | """ 8 | :type n: int 9 | :type flights: List[List[int]] 10 | :type src: int 11 | :type dst: int 12 | :type K: int 13 | :rtype: int 14 | """ 15 | 16 | graph = defaultdict(dict) 17 | for f in flights: 18 | graph[f[0]][f[1]] = f[2] 19 | 20 | heap = [(0, src, K + 1)] 21 | while heap: 22 | dis, cur, k = heapq.heappop(heap) 23 | if cur == dst: 24 | return dis 25 | if k > 0: 26 | for i in graph[cur]: 27 | heapq.heappush(heap, (dis + graph[cur][i], i, k - 1)) 28 | return -1 -------------------------------------------------------------------------------- /python/Graph/Critical Connections in a Network/Critical Connections in a Network.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def criticalConnections(self, n, connections): 6 | """ 7 | :type n: int 8 | :type connections: List[List[int]] 9 | :rtype: List[List[int]] 10 | """ 11 | graph = defaultdict(list) 12 | for v in connections: 13 | graph[v[0]].append(v[1]) 14 | graph[v[1]].append(v[0]) 15 | 16 | dfn = [None for i in range(n)] 17 | low = [None for i in range(n)] 18 | 19 | cur = 0 20 | start = 0 21 | res = [] 22 | self.cur = 0 23 | 24 | def dfs(node, parent): 25 | if dfn[node] is None: 26 | dfn[node] = self.cur 27 | low[node] = self.cur 28 | self.cur += 1 29 | for n in graph[node]: 30 | if dfn[n] is None: 31 | dfs(n, node) 32 | 33 | if parent is not None: 34 | l = min([low[i] for i in graph[node] if i != parent] + [low[node]]) 35 | else: 36 | l = min(low[i] for i in graph[node] + [low[node]]) 37 | low[node] = l 38 | 39 | dfs(0, None) 40 | 41 | for v in connections: 42 | if low[v[0]] > dfn[v[1]] or low[v[1]] > dfn[v[0]]: 43 | res.append(v) 44 | return res 45 | -------------------------------------------------------------------------------- /python/Graph/Parallel Courses/Parallel Courses.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def minimumSemesters(self, N, relations): 6 | """ 7 | :type N: int 8 | :type relations: List[List[int]] 9 | :rtype: int 10 | """ 11 | 12 | graph = defaultdict(dict) 13 | temp = defaultdict(dict) 14 | 15 | for i, j in relations: 16 | graph[i][j] = 1 17 | temp[j][i] = 1 18 | indegree = {j: len(temp[j]) for j in temp} 19 | for i in range(1, N + 1): 20 | if i not in indegree: 21 | indegree[i] = 0 22 | 23 | count = 0 24 | 25 | while len(indegree) > 0: 26 | temp = dict(indegree) 27 | pop_node = [i for i in temp if temp[i] == 0] 28 | for i in pop_node: 29 | for j in graph[i]: 30 | temp[j] -= 1 31 | del (temp[i]) 32 | if len(temp) > 0 and temp == indegree: 33 | return -1 34 | else: 35 | indegree = temp 36 | count += 1 37 | return count 38 | -------------------------------------------------------------------------------- /python/Greedy/Broken Calculator/Broken Calculator.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def brokenCalc(self, X, Y): 3 | """ 4 | :type X: int 5 | :type Y: int 6 | :rtype: int 7 | """ 8 | if Y>X: 9 | return Y%2+1+self.brokenCalc(X,(Y+1)//2) 10 | else: 11 | return X-Y 12 | -------------------------------------------------------------------------------- /python/Greedy/Longest Chunked Palindrome Decomposition/Longest Chunked Palindrome Decomposition.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def longestDecomposition(self, text): 3 | """ 4 | :type text: str 5 | :rtype: int 6 | """ 7 | left_pre = 0 8 | right_pre = len(text) 9 | left = 1 10 | right = len(text) - 1 11 | count = 0 12 | 13 | while left <= right: 14 | if left > left_pre and right < right_pre and text[left_pre:left] == text[right:right_pre]: 15 | count += 2 16 | left_pre = left 17 | right_pre = right 18 | left += 1 19 | right -= 1 20 | if left_pre < right_pre: 21 | count += 1 22 | return count 23 | -------------------------------------------------------------------------------- /python/Greedy/Reconstruct a 2-Row Binary Matrix/Reconstruct a 2-Row Binary Matrix.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reconstructMatrix(self, upper, lower, colsum): 3 | """ 4 | :type upper: int 5 | :type lower: int 6 | :type colsum: List[int] 7 | :rtype: List[List[int]] 8 | """ 9 | 10 | if upper + lower != sum(colsum): 11 | return [] 12 | 13 | if max(upper, lower) > sum([1 if i > 0 else 0 for i in colsum]): 14 | return [] 15 | 16 | if max(colsum) > sum([1 if i > 0 else 0 for i in [upper, lower]]): 17 | return [] 18 | 19 | u = [] 20 | l = [] 21 | u_count = sum([1 if i == 2 else 0 for i in colsum]) 22 | l_count = int(u_count) 23 | 24 | for i in range(len(colsum)): 25 | if colsum[i] == 2: 26 | u.append(1) 27 | l.append(1) 28 | elif colsum[i] == 0: 29 | u.append(0) 30 | l.append(0) 31 | 32 | else: 33 | if u_count < upper: 34 | u.append(1) 35 | l.append(0) 36 | u_count += 1 37 | else: 38 | l.append(1) 39 | u.append(0) 40 | l_count += 1 41 | return [u, l] -------------------------------------------------------------------------------- /python/Hash/Longest Duplicate Substring/Longest Duplicate Substring.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | prime = 10 ** 9 + 7 4 | base = 26 5 | 6 | 7 | class Solution(object): 8 | def longestDupSubstring(self, S): 9 | """ 10 | :type S: str 11 | :rtype: str 12 | """ 13 | 14 | def helper(s, n): 15 | max_base = pow(base, n - 1, prime) 16 | cur = 0 17 | for i in s[:n]: 18 | cur = (cur * base + ord(i)) % prime 19 | dic = defaultdict(list) 20 | dic[cur].append(n - 1) 21 | 22 | for j, i in enumerate(s[n:]): 23 | cur -= ord(s[j]) * max_base 24 | cur = (cur * base + ord(i)) % prime 25 | if cur in dic: 26 | st = s[j + 1:j + n + 1] 27 | for v in dic[cur]: 28 | if st == s[v - n + 1:v + 1]: 29 | return st 30 | dic[cur].append(j + n) 31 | return "" 32 | 33 | low = 0 34 | high = len(S) 35 | 36 | res = "" 37 | while low + 1 < high: 38 | mid = (low + high) // 2 39 | v = helper(S, mid) 40 | if v: 41 | res = v 42 | low = mid 43 | else: 44 | high = mid 45 | return res 46 | -------------------------------------------------------------------------------- /python/Hash/Repeated String Match/Repeated String Match.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def repeatedStringMatch(self, A, B): 3 | """ 4 | :type A: str 5 | :type B: str 6 | :rtype: int 7 | """ 8 | b = len(B) 9 | a = len(A) 10 | A = A * ((b // a + 1) * 2) 11 | 12 | mod = 10001 13 | 14 | p = 113 15 | cur = 0 16 | for i in B: 17 | cur += (ord(i) - ord("a")) * p 18 | p *= 113 19 | hb = cur % mod 20 | 21 | p = 113 22 | cur = 0 23 | for i in A[:b]: 24 | cur += (ord(i) - ord("a")) * p 25 | p *= 113 26 | ha = cur % mod 27 | 28 | if ha == hb and A[:b] == B: 29 | return b // a + 1 if b % a != 0 else b // a 30 | 31 | for j, i in enumerate(A[b:]): 32 | cur -= (ord(A[j % b]) - ord("a")) * 113 33 | cur /= 113 34 | cur += (ord(A[b + j]) - ord("a")) * p / 113 35 | ha = cur % mod 36 | if ha == hb and A[j + 1:j + b + 1] == B: 37 | return (j + b + 1) // a + 1 if (j + b + 1) % a != 0 else (j + b + 1) // a 38 | return -1 39 | -------------------------------------------------------------------------------- /python/Hash/Rotate String/Rotate String.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def rotateString(self, A, B): 3 | """ 4 | :type A: str 5 | :type B: str 6 | :rtype: bool 7 | """ 8 | mod = 101 9 | 10 | p = 113 11 | cur = 0 12 | for i in B: 13 | cur += (ord(i) - ord("a")) * p 14 | p *= 113 15 | hb = cur % mod 16 | 17 | p = 113 18 | cur = 0 19 | for i in A: 20 | cur += (ord(i) - ord("a")) * p 21 | p *= 113 22 | ha = cur % mod 23 | 24 | if ha == hb and A == B: 25 | return True 26 | 27 | for j, i in enumerate(A): 28 | cur -= (ord(i) - ord("a")) * 113 29 | cur /= 113 30 | cur += (ord(i) - ord("a")) * p / 113 31 | ha = cur % mod 32 | if ha == hb and A[j + 1:] + A[:j + 1] == B: 33 | return True 34 | return False 35 | -------------------------------------------------------------------------------- /python/HashMap/Alphabet Board Path/Alphabet Board Path.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def alphabetBoardPath(self, target): 3 | """ 4 | :type target: str 5 | :rtype: str 6 | """ 7 | board = {chr(ord("a") + i * 5 + j): (i, j) for i in range(5) for j in range(5)} 8 | board["z"] = (5, 0) 9 | res = "" 10 | current = (0, 0) 11 | for i in target: 12 | cur_x, cur_y = current 13 | next_x, next_y = board[i] 14 | if i != "z": 15 | if next_x >= cur_x: 16 | for j in range(next_x - cur_x): 17 | res += "D" 18 | else: 19 | for j in range(cur_x - next_x): 20 | res += "U" 21 | if next_y >= cur_y: 22 | for j in range(next_y - cur_y): 23 | res += "R" 24 | else: 25 | for j in range(cur_y - next_y): 26 | res += "L" 27 | else: 28 | for j in range(cur_y - next_y): 29 | res += "L" 30 | for j in range(next_x - cur_x): 31 | res += "D" 32 | 33 | res += "!" 34 | current = (next_x, next_y) 35 | return res 36 | -------------------------------------------------------------------------------- /python/HashMap/Analyze User Website Visit Pattern/Analyze User Website Visit Pattern.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | from collections import Counter 3 | from itertools import combinations 4 | 5 | 6 | class Solution(object): 7 | def mostVisitedPattern(self, username, timestamp, website): 8 | """ 9 | :type username: List[str] 10 | :type timestamp: List[int] 11 | :type website: List[str] 12 | :rtype: List[str] 13 | """ 14 | d = defaultdict(list) 15 | 16 | for t, u, w in sorted(zip(timestamp, username, website)): 17 | d[u].append(w) 18 | 19 | c = Counter() 20 | for u in d: 21 | c += Counter(set(seq for seq in combinations(d[u], 3))) 22 | target = max(c.values()) 23 | 24 | return min(list(k) for k in c if c[k] == target) 25 | -------------------------------------------------------------------------------- /python/HashMap/Binary Subarrays With Sum/Binary Subarrays With Sum.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numSubarraysWithSum(self, A, S): 3 | """ 4 | :type A: List[int] 5 | :type S: int 6 | :rtype: int 7 | """ 8 | dic = {0: 1} 9 | temp = 0 10 | res = 0 11 | for i in range(len(A)): 12 | temp += A[i] 13 | if temp - S in dic: 14 | res += dic[temp - S] 15 | dic[temp] = dic.get(temp, 0) + 1 16 | return res 17 | -------------------------------------------------------------------------------- /python/HashMap/Day of the Week/Day of the Week.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def dayOfTheWeek(self, day, month, year): 3 | """ 4 | :type day: int 5 | :type month: int 6 | :type year: int 7 | :rtype: str 8 | """ 9 | # 1997/1/1 Friday 10 | 11 | s = set([i for i in range(1971, 2101) if i % 4 == 0]) 12 | s.remove(2100) 13 | 14 | months = { 15 | 1: 31, 16 | 2: 28, 17 | 3: 31, 18 | 4: 30, 19 | 5: 31, 20 | 6: 30, 21 | 7: 31, 22 | 8: 31, 23 | 9: 30, 24 | 10: 31, 25 | 11: 30, 26 | 12: 31 27 | } 28 | 29 | days = -1 30 | 31 | for i in range(1, month): 32 | days += months[i] 33 | y = year - 1971 34 | days += y * 365 35 | 36 | days += day 37 | 38 | for i in s: 39 | if i < year: 40 | days += 1 41 | if i == year and month > 2: 42 | days += 1 43 | 44 | days = days % 7 45 | 46 | res = { 47 | 6: "Thursday", 48 | 0: "Friday", 49 | 1: "Saturday", 50 | 2: "Sunday", 51 | 3: "Monday", 52 | 4: "Tuesday", 53 | 5: "Wednesday" 54 | } 55 | return res[days] 56 | -------------------------------------------------------------------------------- /python/HashMap/Design File System/Design File System.py: -------------------------------------------------------------------------------- 1 | class FileSystem(object): 2 | 3 | def __init__(self): 4 | self.dic = {} 5 | 6 | def create(self, path, value): 7 | """ 8 | :type path: str 9 | :type value: int 10 | :rtype: bool 11 | """ 12 | path = path.split("/") 13 | path = [p for p in path if p != ""] 14 | if len(path) == 0: 15 | return False 16 | cur = self.dic 17 | for i, p in enumerate(path): 18 | print(i, p) 19 | if i == len(path) - 1: 20 | cur[p] = {"zhou_value": value} 21 | return True 22 | else: 23 | if p not in cur: 24 | return False 25 | cur = cur[p] 26 | return True 27 | 28 | def get(self, path): 29 | """ 30 | :type path: str 31 | :rtype: int 32 | """ 33 | path = path.split("/") 34 | path = [p for p in path if p != ""] 35 | if len(path) == 0: 36 | return -1 37 | cur = self.dic 38 | for i, p in enumerate(path): 39 | if i == len(path) - 1 and p in cur: 40 | return cur[p]["zhou_value"] 41 | else: 42 | if p not in cur: 43 | return -1 44 | else: 45 | cur = cur[p] 46 | return -1 47 | 48 | # Your FileSystem object will be instantiated and called as such: 49 | # obj = FileSystem() 50 | # param_1 = obj.create(path,value) 51 | # param_2 = obj.get(path) 52 | -------------------------------------------------------------------------------- /python/HashMap/Longest Well-Performing Interval/Longest Well-Performing Interval.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def longestWPI(self, hours): 3 | """ 4 | :type hours: List[int] 5 | :rtype: int 6 | """ 7 | res = 0 8 | dic = {} 9 | score = 0 10 | 11 | for i in range(len(hours)): 12 | if hours[i] > 8: 13 | score += 1 14 | else: 15 | score -= 1 16 | if score > 0: 17 | res = max(res, i + 1) 18 | 19 | if score not in dic: 20 | dic[score] = i 21 | 22 | if score - 1 in dic: 23 | res = max(res, i - dic[score - 1]) 24 | return res 25 | -------------------------------------------------------------------------------- /python/HashMap/Maximum Equal Frequency/Maximum Equal Frequency.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def maxEqualFreq(self, nums): 6 | """ 7 | :type nums: List[int] 8 | :rtype: int 9 | """ 10 | 11 | cnt = defaultdict(int) 12 | freq = defaultdict(int) 13 | res = 0 14 | maxF = 0 15 | 16 | for i, j in enumerate(nums): 17 | cnt[j] += 1 18 | freq[cnt[j] - 1] -= 1 19 | freq[cnt[j]] += 1 20 | 21 | maxF = max(maxF, cnt[j]) 22 | 23 | if maxF == 1 or maxF * freq[maxF] == i or (maxF - 1) * (freq[maxF - 1] + 1) == i: 24 | res = max(res, i + 1) 25 | return res 26 | -------------------------------------------------------------------------------- /python/HashMap/Maximum Number of Balloons/Maximum Number of Balloons.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution(object): 5 | def maxNumberOfBalloons(self, text): 6 | """ 7 | :type text: str 8 | :rtype: int 9 | """ 10 | c = Counter(text) 11 | return min(c["b"], c["a"], c["l"] // 2, c["o"] // 2, c["n"]) 12 | -------------------------------------------------------------------------------- /python/HashMap/Minimum Area Rectangle/Minimum Area Rectangle.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def minAreaRect(self, points): 6 | """ 7 | :type points: List[List[int]] 8 | :rtype: int 9 | """ 10 | p = defaultdict(list) 11 | for x, y in points: 12 | p[x].append(y) 13 | res = float("inf") 14 | 15 | latex = {} 16 | for x in sorted(p): 17 | p[x].sort() 18 | for i in range(len(p[x])): 19 | for j in range(i): 20 | y1, y2 = p[x][j], p[x][i] 21 | if (y1, y2) in latex: 22 | res = min(res, (y2 - y1) * (x - latex[(y1, y2)])) 23 | latex[(y1, y2)] = x 24 | return res if res != float("inf") else 0 25 | -------------------------------------------------------------------------------- /python/HashMap/Minimum Swaps to Make Strings Equal/Minimum Swaps to Make Strings Equal.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution(object): 5 | def minimumSwap(self, s1, s2): 6 | """ 7 | :type s1: str 8 | :type s2: str 9 | :rtype: int 10 | """ 11 | 12 | c1 = Counter(s1) 13 | c2 = Counter(s2) 14 | dic = { 15 | "xy": 0, 16 | "yx": 0, 17 | } 18 | 19 | if (c1["x"] + c2["x"]) % 2 == 1: 20 | return -1 21 | 22 | for i in range(len(s1)): 23 | if s1[i] == s2[i]: 24 | continue 25 | else: 26 | if s1[i] == "x": 27 | dic["xy"] += 1 28 | else: 29 | dic["yx"] += 1 30 | 31 | res = 0 32 | if dic["xy"] % 2 == 0: 33 | res += dic["xy"] // 2 34 | res += dic["yx"] // 2 35 | 36 | return res 37 | 38 | else: 39 | res += dic["xy"] // 2 40 | res += dic["yx"] // 2 41 | res += 2 42 | return res -------------------------------------------------------------------------------- /python/HashMap/Number of Equivalent Domino Pairs/Number of Equivalent Domino Pairs.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numEquivDominoPairs(self, dominoes): 3 | """ 4 | :type dominoes: List[List[int]] 5 | :rtype: int 6 | """ 7 | dic = {} 8 | res = 0 9 | for domin in dominoes: 10 | domin = (min(domin[0], domin[1]), max(domin[0], domin[1])) 11 | 12 | if domin in dic: 13 | res += dic[domin] 14 | dic[domin] += 1 15 | else: 16 | dic[domin] = 1 17 | return res 18 | -------------------------------------------------------------------------------- /python/HashMap/Play with Chips/Play with Chips.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution(object): 5 | def minCostToMoveChips(self, chips): 6 | """ 7 | :type chips: List[int] 8 | :rtype: int 9 | """ 10 | c = Counter(chips) 11 | 12 | res = float("inf") 13 | for k in c.keys(): 14 | temp = 0 15 | for j in c.keys(): 16 | dis = abs(j - k) % 2 17 | temp += dis * c[j] * 1 18 | res = min(res, temp) 19 | return res 20 | -------------------------------------------------------------------------------- /python/HashMap/Single-Row Keyboard/Single-Row Keyboard.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def calculateTime(self, keyboard, word): 3 | """ 4 | :type keyboard: str 5 | :type word: str 6 | :rtype: int 7 | """ 8 | dic = {keyboard[i]: i for i in range(26)} 9 | 10 | cur = 0 11 | res = 0 12 | for c in word: 13 | res += abs(dic[c] - cur) 14 | cur = dic[c] 15 | return res 16 | -------------------------------------------------------------------------------- /python/HashMap/String Transforms Into Another String/String Transforms Into Another String.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canConvert(self, str1, str2): 3 | """ 4 | :type str1: str 5 | :type str2: str 6 | :rtype: bool 7 | """ 8 | if str1 == str2: 9 | return True 10 | dic = {} 11 | 12 | for i, j in zip(str1, str2): 13 | if dic.setdefault(i, j) != j: 14 | return False 15 | return len(set(dic.values())) < 26 16 | -------------------------------------------------------------------------------- /python/HashMap/Triples with Bitwise AND Equal To Zero/Triples with Bitwise AND Equal To Zero.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def countTriplets(self, A): 3 | """ 4 | :type A: List[int] 5 | :rtype: int 6 | """ 7 | dic = {} 8 | 9 | for i in A: 10 | for j in A: 11 | dic[i & j] = dic.get(i & j, 0) + 1 12 | 13 | res = 0 14 | for i in A: 15 | for k in dic: 16 | if i & k == 0: 17 | res += dic[k] 18 | return res 19 | -------------------------------------------------------------------------------- /python/HashSet/Intersection of Three Sorted Arrays/Intersection of Three Sorted Arrays.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def arraysIntersection(self, arr1, arr2, arr3): 3 | """ 4 | :type arr1: List[int] 5 | :type arr2: List[int] 6 | :type arr3: List[int] 7 | :rtype: List[int] 8 | """ 9 | s1 = set(arr1) 10 | s2 = set(arr2) 11 | s3 = set(arr3) 12 | 13 | s = s1 & s2 & s3 14 | return sorted(list(s)) 15 | -------------------------------------------------------------------------------- /python/Heap/Dinner Plate Stacks/Dinner Plate Stacks.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class DinnerPlates(object): 5 | 6 | def __init__(self, capacity): 7 | """ 8 | :type capacity: int 9 | """ 10 | self.stacks = [[]] 11 | self.index = [0] 12 | heapq.heapify(self.index) 13 | self.capacity = capacity 14 | 15 | def push(self, val): 16 | """ 17 | :type val: int 18 | :rtype: None 19 | """ 20 | i = heapq.heappop(self.index) 21 | self.stacks[i].append(val) 22 | if len(self.stacks[i]) < self.capacity: 23 | heapq.heappush(self.index, i) 24 | if len(self.index) == 0: 25 | heapq.heappush(self.index, len(self.stacks)) 26 | self.stacks.append([]) 27 | 28 | def pop(self): 29 | """ 30 | :rtype: int 31 | """ 32 | while len(self.stacks) >= 1 and len(self.stacks[-1]) == 0: 33 | self.stacks.pop() 34 | if len(self.stacks) == 0: 35 | return -1 36 | if len(self.stacks[-1]) == self.capacity: 37 | heapq.heappush(self.index, len(self.stacks) - 1) 38 | val = self.stacks[-1].pop() 39 | return val 40 | 41 | def popAtStack(self, index): 42 | """ 43 | :type index: int 44 | :rtype: int 45 | """ 46 | if len(self.stacks[index]) == 0: 47 | return -1 48 | if len(self.stacks[index]) == self.capacity: 49 | heapq.heappush(self.index, index) 50 | val = self.stacks[index].pop() 51 | return val 52 | 53 | # Your DinnerPlates object will be instantiated and called as such: 54 | # obj = DinnerPlates(capacity) 55 | # obj.push(val) 56 | # param_2 = obj.pop() 57 | # param_3 = obj.popAtStack(index) 58 | -------------------------------------------------------------------------------- /python/Heap/Find Smallest Common Element in All Rows/Find Smallest Common Element in All Rows.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class Solution(object): 5 | def smallestCommonElement(self, mat): 6 | """ 7 | :type mat: List[List[int]] 8 | :rtype: int 9 | """ 10 | 11 | h = [(mat[i][0], 0, i) for i in range(len(mat))] 12 | heapq.heapify(h) 13 | 14 | dic = {} 15 | for i in range(len(mat)): 16 | dic[mat[i][0]] = dic.get(mat[i][0], 0) + 1 17 | if dic[mat[i][0]] == len(mat): 18 | return mat[i][0] 19 | 20 | while h: 21 | v, index, row = heapq.heappop(h) 22 | if index == len(mat[0]) - 1: 23 | return -1 24 | dic[v] -= 1 25 | 26 | heapq.heappush(h, (mat[row][index + 1], index + 1, row)) 27 | 28 | dic[mat[row][index + 1]] = dic.get(mat[row][index + 1], 0) + 1 29 | if dic[mat[row][index + 1]] == len(mat): 30 | return mat[row][index + 1] 31 | -------------------------------------------------------------------------------- /python/Heap/K-th Smallest Prime Fraction/K-th Smallest Prime Fraction.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class Solution(object): 5 | def kthSmallestPrimeFraction(self, A, K): 6 | """ 7 | :type A: List[int] 8 | :type K: int 9 | :rtype: List[int] 10 | """ 11 | A = A 12 | reverse_A = A[::-1] 13 | 14 | heap = [] 15 | for i in range(len(A) - 1): 16 | heap.append((1.0 * A[0] / reverse_A[i], i, 0)) 17 | 18 | heapq.heapify(heap) 19 | 20 | while K > 0: 21 | K -= 1 22 | v, i, j = heapq.heappop(heap) 23 | if j < len(A) - i - 2: 24 | heapq.heappush(heap, (1.0 * A[j + 1] / reverse_A[i], i, j + 1)) 25 | else: 26 | heapq.heappush(heap, (float("inf"), i, j + 1)) 27 | 28 | return [A[j], reverse_A[i]] 29 | -------------------------------------------------------------------------------- /python/Heap/Minimum Cost to Connect Sticks/Minimum Cost to Connect Sticks.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | class Solution(object): 4 | def connectSticks(self, sticks): 5 | """ 6 | :type sticks: List[int] 7 | :rtype: int 8 | """ 9 | heapq.heapify(sticks) 10 | res = 0 11 | while len(sticks)>1: 12 | p1 = heapq.heappop(sticks) 13 | p2 = heapq.heappop(sticks) 14 | res+=p1+p2 15 | heapq.heappush(sticks,p1+p2) 16 | return res 17 | -------------------------------------------------------------------------------- /python/Heap/Minimum Cost to Hire K Workers/Minimum Cost to Hire K Workers.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class Solution(object): 5 | def mincostToHireWorkers(self, quality, wage, K): 6 | """ 7 | :type quality: List[int] 8 | :type wage: List[int] 9 | :type K: int 10 | :rtype: float 11 | """ 12 | ratio = [(1.0 * wage[i] / quality[i], quality[i], wage[i]) for i in range(len(quality))] 13 | ratio.sort() 14 | 15 | res = float("inf") 16 | s = 0 17 | heap = [] 18 | for r, q, w in ratio: 19 | heapq.heappush(heap, -q) 20 | s += q 21 | 22 | if len(heap) > K: 23 | s += heapq.heappop(heap) 24 | if len(heap) == K: 25 | res = min(res, r * s) 26 | 27 | return res 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /python/Heap/Minimum Number of Refueling Stops/Minimum Number of Refueling Stops.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class Solution(object): 5 | def minRefuelStops(self, target, startFuel, stations): 6 | """ 7 | :type target: int 8 | :type startFuel: int 9 | :type stations: List[List[int]] 10 | :rtype: int 11 | """ 12 | stations.append([target, float("inf")]) 13 | heap = [] 14 | heapq.heapify(heap) 15 | 16 | res = 0 17 | pre = 0 18 | tank = startFuel 19 | for location, capacity in stations: 20 | tank -= (location - pre) 21 | while tank < 0 and heap: 22 | v = heapq.heappop(heap) 23 | tank -= v 24 | res += 1 25 | if tank < 0: 26 | return -1 27 | heapq.heappush(heap, -capacity) 28 | pre = location 29 | return res 30 | -------------------------------------------------------------------------------- /python/Heap/Minimum Time to Build Blocks/Minimum Time to Build Blocks.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class Solution(object): 5 | def minBuildTime(self, blocks, split): 6 | """ 7 | :type blocks: List[int] 8 | :type split: int 9 | :rtype: int 10 | """ 11 | 12 | heapq.heapify(blocks) 13 | 14 | while len(blocks) > 1: 15 | node1 = heapq.heappop(blocks) 16 | node2 = heapq.heappop(blocks) 17 | heapq.heappush(blocks, max(node1, node2) + split) 18 | 19 | return blocks[0] 20 | -------------------------------------------------------------------------------- /python/LinkedList/Convert Sorted List to Binary Search Tree/Convert Sorted List to Binary Search Tree.py: -------------------------------------------------------------------------------- 1 | # using recommend order 5 : 876 Middle of the Linked List to find the middle node as current root TreeNode 2 | 3 | # class ListNode(object): 4 | # def __init__(self, x): 5 | # self.val = x 6 | # self.next = None 7 | 8 | # Definition for a binary tree node. 9 | # class TreeNode(object): 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.left = None 13 | # self.right = None 14 | 15 | 16 | class Solution(object): 17 | def findMiddleNode(self, head): 18 | if not head: 19 | return None, None 20 | if not head.next: 21 | return head, None 22 | slow = head 23 | fast = head 24 | pre = slow 25 | while fast and fast.next: 26 | pre = slow 27 | slow = slow.next 28 | fast = fast.next.next 29 | pre.next = None 30 | return head, slow 31 | 32 | def sortedListToBST(self, head): 33 | """ 34 | :type head: ListNode 35 | :rtype: TreeNode 36 | """ 37 | start, middle = self.findMiddleNode(head) 38 | if not middle: 39 | if start: 40 | node = TreeNode(start.val) 41 | return node 42 | else: 43 | return 44 | node = TreeNode(middle.val) 45 | node.left = self.sortedListToBST(start) 46 | node.right = self.sortedListToBST(middle.next) 47 | return node 48 | -------------------------------------------------------------------------------- /python/LinkedList/Insertion Sort List/Insertion Sort List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def insertionSortList(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | 14 | pre = ListNode(0) 15 | pre_cur = pre 16 | 17 | cur = head 18 | 19 | while cur: 20 | temp = cur.next 21 | while pre_cur.next and pre_cur.next.val <= cur.val: 22 | pre_cur = pre_cur.next 23 | cur.next = pre_cur.next 24 | pre_cur.next = cur 25 | pre_cur = pre 26 | cur = temp 27 | return pre.next 28 | 29 | -------------------------------------------------------------------------------- /python/LinkedList/Linked List Cycle II/Linked List Cycle II.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def detectCycle(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | slow = head 14 | fast = head 15 | step = 0 16 | 17 | while slow and fast and fast.next: 18 | slow = slow.next 19 | fast = fast.next.next 20 | step += 1 21 | if slow == fast: 22 | break 23 | if not fast or not fast.next: 24 | return None 25 | slow2 = head 26 | index = 0 27 | while slow != slow2: 28 | slow = slow.next 29 | slow2 = slow2.next 30 | index += 1 31 | return slow -------------------------------------------------------------------------------- /python/LinkedList/Linked List Cycle/Linked List Cycle.py: -------------------------------------------------------------------------------- 1 | # similar solution as 876 "Middle of the Linked List" 2 | 3 | # class ListNode(object): 4 | # def __init__(self, x): 5 | # self.val = x 6 | # self.next = None 7 | 8 | 9 | class Solution(object): 10 | def hasCycle(self, head): 11 | """ 12 | :type head: ListNode 13 | :rtype: bool 14 | """ 15 | slow = head 16 | fast = head 17 | 18 | while fast and fast.next and slow: 19 | slow = slow.next 20 | fast = fast.next.next 21 | if fast == slow: 22 | return True 23 | return False 24 | -------------------------------------------------------------------------------- /python/LinkedList/Linked List Random Node/Linked List Random Node.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | import random 7 | 8 | 9 | class Solution(object): 10 | 11 | def __init__(self, head): 12 | """ 13 | @param head The linked list's head. 14 | Note that the head is guaranteed to be not null, so it contains at least one node. 15 | :type head: ListNode 16 | """ 17 | self.head = head 18 | 19 | def getRandom(self): 20 | """ 21 | Returns a random node's value. 22 | :rtype: int 23 | """ 24 | cur = self.head 25 | c = 1 26 | res = cur.val 27 | while cur.next: 28 | cur = cur.next 29 | c += 1 30 | r = random.randint(1, c) 31 | if r == c: 32 | res = cur.val 33 | return res 34 | 35 | # Your Solution object will be instantiated and called as such: 36 | # obj = Solution(head) 37 | # param_1 = obj.getRandom() -------------------------------------------------------------------------------- /python/LinkedList/LinkedList Structure/LinkedList Structure.py: -------------------------------------------------------------------------------- 1 | # single-linked list 2 | class ListNode(object): 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | # double_linked list 8 | class DoubleListNode(object): 9 | """ 10 | A more specific implement for double-linked list is shown in recommend order-9: 707 Design Linked List 11 | """ 12 | def __init__(self, x): 13 | self.val = x 14 | self.pre = None 15 | self.next = None 16 | -------------------------------------------------------------------------------- /python/LinkedList/Merge Two Sorted Lists/Merge Two Sorted Lists.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def mergeTwoLists(self, l1, l2): 9 | """ 10 | :type l1: ListNode 11 | :type l2: ListNode 12 | :rtype: ListNode 13 | """ 14 | if not l1: 15 | return l2 16 | if not l2: 17 | return l1 18 | if l1.val<=l2.val: 19 | l1.next = self.mergeTwoLists(l1.next, l2) 20 | return l1 21 | else: 22 | l2.next = self.mergeTwoLists(l1, l2.next) 23 | return l2 -------------------------------------------------------------------------------- /python/LinkedList/Merge k Sorted Lists/Merge k Sorted Lists.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | class Solution(object): 7 | def mergeKLists(self, lists): 8 | """ 9 | :type lists: List[ListNode] 10 | :rtype: ListNode 11 | """ 12 | 13 | # best solution-> divide&conquer->no extra space 14 | 15 | if not lists: 16 | return 17 | 18 | def mergeTwoLists(head1, head2): 19 | dummy = ListNode(0) 20 | cur = dummy 21 | while head1 and head2: 22 | if head1.val <= head2.val: 23 | cur.next = head1 24 | head1 = head1.next 25 | else: 26 | cur.next = head2 27 | head2 = head2.next 28 | cur = cur.next 29 | if head1: 30 | cur.next = head1 31 | if head2: 32 | cur.next = head2 33 | return dummy.next 34 | 35 | interval = 1 36 | 37 | while interval < len(lists): 38 | for i in range(0, len(lists) - interval, interval * 2): 39 | lists[i] = mergeTwoLists(lists[i], lists[i + interval]) 40 | interval *= 2 41 | return lists[0] 42 | -------------------------------------------------------------------------------- /python/LinkedList/Middle of the Linked List/Middle of the Linked List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def middleNode(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | slow = head 14 | fast = head 15 | 16 | while fast and fast.next: 17 | slow = slow.next 18 | fast = fast.next.next 19 | return slow 20 | -------------------------------------------------------------------------------- /python/LinkedList/Odd Even Linked List/Odd Even Linked List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def oddEvenList(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | if not head: 14 | return 15 | 16 | odd = head 17 | even = head.next 18 | even_start = head.next 19 | 20 | while even and even.next: 21 | temp = even.next 22 | odd.next = temp 23 | odd = odd.next 24 | even.next = odd.next 25 | even = even.next 26 | odd.next = even_start 27 | return head -------------------------------------------------------------------------------- /python/LinkedList/Palindrome Linked List/Palindrome Linked List.py: -------------------------------------------------------------------------------- 1 | # using algorithm in 876 "Middle of the Linked List" and 206 "Reverse Linked List" 2 | 3 | # class ListNode(object): 4 | # def __init__(self, x): 5 | # self.val = x 6 | # self.next = None 7 | 8 | 9 | class Solution(object): 10 | def reverse(self, head): 11 | """ 12 | :type head: ListNode 13 | :rtype: ListNode 14 | """ 15 | pre = None 16 | while head: 17 | temp = head.next 18 | head.next = pre 19 | pre = head 20 | head = temp 21 | return pre 22 | 23 | def isPalindrome(self, head): 24 | """ 25 | :type head: ListNode 26 | :rtype: bool 27 | """ 28 | slow = head 29 | fast = head 30 | while fast and fast.next: 31 | slow = slow.next 32 | fast = fast.next.next 33 | 34 | reverse_head = self.reverse(slow) 35 | 36 | while reverse_head: 37 | if head.val != reverse_head.val: 38 | return False 39 | head = head.next 40 | reverse_head = reverse_head.next 41 | return True 42 | -------------------------------------------------------------------------------- /python/LinkedList/Partition List/Partition List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def partition(self, head, x): 9 | """ 10 | :type head: ListNode 11 | :type x: int 12 | :rtype: ListNode 13 | """ 14 | small_head = ListNode(0) 15 | small_cur = small_head 16 | big_head = ListNode(0) 17 | big_cur = big_head 18 | 19 | while head: 20 | if head.val >= x: 21 | big_cur.next = head 22 | big_cur = big_cur.next 23 | else: 24 | small_cur.next = head 25 | small_cur = small_cur.next 26 | head = head.next 27 | big_cur.next = None 28 | small_cur.next = big_head.next 29 | return small_head.next 30 | 31 | -------------------------------------------------------------------------------- /python/LinkedList/Remove Duplicates from Sorted List II/Remove Duplicates from Sorted List II.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def deleteDuplicates(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | dummy = ListNode(0) 14 | dummy.next = head 15 | pre = dummy 16 | cur = head 17 | 18 | while cur and cur.next: 19 | if cur.val == cur.next.val: 20 | while cur and cur.next and cur.val == cur.next.val: 21 | cur = cur.next 22 | pre.next = cur.next 23 | cur = pre.next 24 | else: 25 | pre = cur 26 | cur = cur.next 27 | return dummy.next -------------------------------------------------------------------------------- /python/LinkedList/Remove Duplicates from Sorted List/Remove Duplicates from Sorted List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def deleteDuplicates(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | 14 | cur = head 15 | while cur and cur.next: 16 | if cur.next.val == cur.val: 17 | cur.next = cur.next.next 18 | else: 19 | cur = cur.next 20 | return head 21 | -------------------------------------------------------------------------------- /python/LinkedList/Remove Linked List Elements/Remove Linked List Elements.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def removeElements(self, head, val): 9 | """ 10 | :type head: ListNode 11 | :type val: int 12 | :rtype: ListNode 13 | """ 14 | pre = ListNode(0) 15 | pre.next = head 16 | 17 | cur = pre 18 | while cur.next: 19 | if cur.next.val == val: 20 | cur.next = cur.next.next 21 | else: 22 | cur = cur.next 23 | return pre.next 24 | -------------------------------------------------------------------------------- /python/LinkedList/Remove Nth Node From End of List/Remove Nth Node From End of List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def removeNthFromEnd(self, head, n): 9 | """ 10 | :type head: ListNode 11 | :type n: int 12 | :rtype: ListNode 13 | """ 14 | slow = head 15 | fast = head 16 | 17 | for i in range(n): 18 | fast = fast.next 19 | if not fast: 20 | return slow.next 21 | 22 | while fast and fast.next: 23 | fast = fast.next 24 | slow = slow.next 25 | slow.next = slow.next.next 26 | return head -------------------------------------------------------------------------------- /python/LinkedList/Remove Zero Sum Consecutive Nodes from Linked List/Remove Zero Sum Consecutive Nodes from Linked List.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def removeZeroSumSublists(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | cur = head 14 | 15 | a = [] 16 | while cur: 17 | a.append(cur.val) 18 | cur = cur.next 19 | res = [] 20 | for i in a: 21 | if i == 0: 22 | continue 23 | else: 24 | tag = True 25 | for j in range(len(res) - 1, -1, -1): 26 | if sum(res[j:]) + i == 0: 27 | res = res[:j] 28 | tag = False 29 | break 30 | if tag: 31 | res.append(i) 32 | 33 | head = ListNode(0) 34 | cur = head 35 | for i in res: 36 | node = ListNode(i) 37 | cur.next = node 38 | cur = cur.next 39 | return head.next -------------------------------------------------------------------------------- /python/LinkedList/Reorder List/Reorder List.py: -------------------------------------------------------------------------------- 1 | # using findMiddle in recommend order 5: 876 Middle of the Linked List and reverseList in recommend 2 | # order 7: 206 Reverse Linked List 3 | 4 | # class ListNode(object): 5 | # def __init__(self, x): 6 | # self.val = x 7 | # self.next = None 8 | 9 | class Solution(object): 10 | def reorderList(self, head): 11 | """ 12 | :type head: ListNode 13 | :rtype: None Do not return anything, modify head in-place instead. 14 | """ 15 | 16 | def findMiddle(head): 17 | pre = None 18 | slow = head 19 | fast = head 20 | while slow and fast and fast.next: 21 | pre = slow 22 | slow = slow.next 23 | fast = fast.next.next 24 | 25 | pre.next = None 26 | return head, slow 27 | 28 | def reverse(head): 29 | pre = None 30 | while head: 31 | temp = head.next 32 | head.next = pre 33 | pre = head 34 | head = temp 35 | return pre 36 | 37 | def merge(head1, head2): 38 | dummy = ListNode(0) 39 | cur = dummy 40 | while head1 and head2: 41 | cur.next = head1 42 | cur = cur.next 43 | head1 = head1.next 44 | cur.next = head2 45 | cur = cur.next 46 | head2 = head2.next 47 | if head2: 48 | cur.next = head2 49 | return dummy.next 50 | 51 | if not head or not head.next: 52 | return head 53 | left, right = findMiddle(head) 54 | head = merge(left, reverse(right)) -------------------------------------------------------------------------------- /python/LinkedList/Reverse Linked List II/Reverse Linked List II.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def reverseBetween(self, head, m, n): 9 | """ 10 | :type head: ListNode 11 | :type m: int 12 | :type n: int 13 | :rtype: ListNode 14 | """ 15 | 16 | if not head or not head.next: 17 | return head 18 | 19 | start = head 20 | pre = None 21 | 22 | while m > 1: 23 | pre = start 24 | start = start.next 25 | m -= 1 26 | n -= 1 27 | 28 | pre_ = None 29 | cur = start 30 | while n: 31 | temp = cur.next 32 | cur.next = pre_ 33 | pre_ = cur 34 | cur = temp 35 | n -= 1 36 | if start: 37 | start.next = temp 38 | if pre: 39 | pre.next = pre_ 40 | return head 41 | else: 42 | return pre_ 43 | 44 | -------------------------------------------------------------------------------- /python/LinkedList/Reverse Linked List/Reverse Linked List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def reverseList(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | pre = None 14 | 15 | while head: 16 | temp = head.next 17 | head.next = pre 18 | pre = head 19 | head = temp 20 | return pre 21 | -------------------------------------------------------------------------------- /python/LinkedList/Reverse Nodes in k-Group/Reverse Nodes in k-Group.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | class Solution(object): 7 | def reverseKGroup(self, head, k): 8 | """ 9 | :type head: ListNode 10 | :type k: int 11 | :rtype: ListNode 12 | """ 13 | if not head or not head.next or k == 0 or k == 1: 14 | return head 15 | 16 | cur = head 17 | pre_cur = None 18 | count = 0 19 | while count < k and cur: 20 | pre_cur = cur 21 | cur = cur.next 22 | count += 1 23 | if count < k: 24 | return head 25 | 26 | pre = self.reverseKGroup(cur, k) 27 | reverse_cur = head 28 | 29 | while count: 30 | temp = reverse_cur.next 31 | reverse_cur.next = pre 32 | pre = reverse_cur 33 | reverse_cur = temp 34 | count -= 1 35 | return pre 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /python/LinkedList/Rotate List/Rotate List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | class Solution(object): 7 | def rotateRight(self, head, k): 8 | """ 9 | :type head: ListNode 10 | :type k: int 11 | :rtype: ListNode 12 | """ 13 | if not head or not head.next: 14 | return head 15 | 16 | c = 1 17 | cur = head 18 | while cur.next: 19 | cur = cur.next 20 | c += 1 21 | cur.next = head 22 | pre = None 23 | cur = head 24 | k = k % c 25 | while c - k > 0: 26 | c -= 1 27 | pre = cur 28 | cur = cur.next 29 | pre.next = None 30 | return cur 31 | -------------------------------------------------------------------------------- /python/LinkedList/Sort List/Sort List.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def mergeList(self, h1, h2): 9 | pre = ListNode(0) 10 | cur = pre 11 | while h1 and h2: 12 | if h1.val <= h2.val: 13 | cur.next = h1 14 | h1 = h1.next 15 | else: 16 | cur.next = h2 17 | h2 = h2.next 18 | cur = cur.next 19 | if h1: 20 | cur.next = h1 21 | if h2: 22 | cur.next = h2 23 | return pre.next 24 | 25 | def sortList(self, head): 26 | """ 27 | :type head: ListNode 28 | :rtype: ListNode 29 | """ 30 | if not head: 31 | return 32 | if not head.next: 33 | return head 34 | 35 | slow = head 36 | pre = slow 37 | fast = head 38 | 39 | while fast and fast.next: 40 | pre = slow 41 | fast = fast.next.next 42 | slow = slow.next 43 | pre.next = None 44 | return self.mergeList(self.sortList(head), self.sortList(slow)) -------------------------------------------------------------------------------- /python/LinkedList/Swap Nodes in Pairs/Swap Nodes in Pairs.py: -------------------------------------------------------------------------------- 1 | # class ListNode(object): 2 | # def __init__(self, x): 3 | # self.val = x 4 | # self.next = None 5 | 6 | 7 | class Solution(object): 8 | def swapPairs(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | pre = ListNode(0) 14 | pre.next = head 15 | cur = pre 16 | 17 | while cur.next and cur.next.next: 18 | first = cur.next 19 | second = cur.next.next 20 | third = cur.next.next.next 21 | cur.next = second 22 | cur.next.next = first 23 | cur.next.next.next = third 24 | cur = cur.next.next 25 | return pre.next 26 | -------------------------------------------------------------------------------- /python/Math/Number of Burgers with No Waste of Ingredients/Number of Burgers with No Waste of Ingredients.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numOfBurgers(self, tomatoSlices: int, cheeseSlices: int) -> List[int]: 3 | x = tomatoSlices - 2 * cheeseSlices 4 | 5 | if x < 0 or x % 2 == 1: 6 | return [] 7 | 8 | else: 9 | x = x // 2 10 | y = cheeseSlices - x 11 | if x >= 0 and y >= 0: 12 | return [x, y] 13 | else: 14 | return [] -------------------------------------------------------------------------------- /python/Sliding Window/Count Number of Nice Subarrays/Count Number of Nice Subarrays.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def numberOfSubarrays(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: int 7 | """ 8 | t = [] 9 | for i, j in enumerate(nums): 10 | if j % 2 == 1: 11 | t.append(i) 12 | 13 | # print(t) 14 | if len(t) < k: 15 | return 0 16 | res = 0 17 | for i in range(len(t) - k + 1): 18 | i1 = t[i] 19 | i2 = t[i + k - 1] 20 | # print(i,i1,i2) 21 | 22 | if i + k < len(t) and i > 0: 23 | res += (t[i + k] - i2) * (i1 - t[i - 1]) 24 | else: 25 | if i + k == len(t) and i == 0: 26 | res += (i1 - 0 + 1) * (len(nums) - i2) 27 | elif i + k == len(t): 28 | res += (i1 - t[i - 1]) * (len(nums) - i2) 29 | else: 30 | res += (t[i + k] - i2) * (i1 - 0 + 1) 31 | return res 32 | -------------------------------------------------------------------------------- /python/Sliding Window/Replace the Substring for Balanced String/Replace the Substring for Balanced String.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def balancedString(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | freq = {ch: 0 for ch in 'QWER'} 8 | for ch in s: 9 | freq[ch] += 1 10 | desired_len = int(len(s) / 4) 11 | fixes = {ch: -desired_len + freq[ch] if desired_len - freq[ch] < 0 else 0 for ch in 'QWER'} 12 | 13 | 14 | i = 0 15 | j = 0 16 | res = len(s) 17 | 18 | dic = {ch: 0 for ch in 'QWER'} 19 | while i < len(s) and j < len(s): 20 | for k in dic.keys(): 21 | while j < len(s) and dic[k] < fixes[k]: 22 | dic[s[j]] += 1 23 | j += 1 24 | if j != len(s) or (j == len(s) and dic[s[j - 1]] == fixes[s[j - 1]]): 25 | while i < len(s) and dic[s[i]] > fixes[s[i]]: 26 | dic[s[i]] -= 1 27 | i += 1 28 | print(i, j) 29 | res = min(res, j - i) 30 | dic[s[i]] -= 1 31 | i += 1 32 | 33 | return res 34 | -------------------------------------------------------------------------------- /python/Sliding Window/Subarrays with K Different Integers/Subarrays with K Different Integers.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def subarraysWithKDistinct(self, A, K): 3 | """ 4 | :type A: List[int] 5 | :type K: int 6 | :rtype: int 7 | """ 8 | 9 | def helper(A, K): 10 | window = {} 11 | i = 0 12 | res = 0 13 | for j in range(len(A)): 14 | if A[j] not in window or window[A[j]] == 0: 15 | K -= 1 16 | window[A[j]] = window.get(A[j], 0) + 1 17 | 18 | while K < 0: 19 | window[A[i]] -= 1 20 | if window[A[i]] == 0: 21 | K += 1 22 | i += 1 23 | res += j - i + 1 24 | return res 25 | 26 | return helper(A, K) - helper(A, K - 1) 27 | -------------------------------------------------------------------------------- /python/Sort/K Closest Points to Origin/K Closest Points to Origin.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def kClosest(self, points, K): 3 | """ 4 | :type points: List[List[int]] 5 | :type K: int 6 | :rtype: List[List[int]] 7 | """ 8 | 9 | # understanding quick-sort,heap & sort 10 | 11 | def compare(x, y): 12 | return x[0] * x[0] + x[1] * x[1] - y[0] * y[0] - y[1] * y[1] 13 | 14 | def partition(l, r): 15 | pivot = points[l] 16 | while l < r: 17 | while l < r and compare(points[r], pivot) >= 0: 18 | r -= 1 19 | points[l] = points[r] 20 | 21 | while l < r and compare(points[l], pivot) < 0: 22 | l += 1 23 | points[r] = points[l] 24 | points[l] = pivot 25 | return l 26 | 27 | l = 0 28 | r = len(points) - 1 29 | 30 | while l < r: 31 | middle = partition(l, r) 32 | if middle == K: 33 | break 34 | else: 35 | if middle > K: 36 | r = middle - 1 37 | else: 38 | l = middle + 1 39 | return points[:K] 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /python/Sort/Relative Sort Array/Relative Sort Array.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def relativeSortArray(self, arr1, arr2): 3 | """ 4 | :type arr1: List[int] 5 | :type arr2: List[int] 6 | :rtype: List[int] 7 | """ 8 | dic = {arr2[i]: i for i in range(len(arr2))} 9 | 10 | return sorted(arr1, key=lambda x: dic.get(x, 1000 + x)) -------------------------------------------------------------------------------- /python/Sort/Remove Interval/Remove Interval.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeInterval(self, intervals: List[List[int]], toBeRemoved: List[int]) -> List[List[int]]: 3 | intervals.sort(key=lambda x: x[1]) 4 | 5 | res = [] 6 | 7 | for i in intervals: 8 | if i[1] <= toBeRemoved[0]: 9 | res.append(i) 10 | else: 11 | if i[1] <= toBeRemoved[1]: 12 | if i[0] < toBeRemoved[0]: 13 | res.append([i[0], toBeRemoved[0]]) 14 | else: 15 | pass 16 | else: 17 | if i[0] < toBeRemoved[0]: 18 | res.append([i[0], toBeRemoved[0]]) 19 | if i[0] <= toBeRemoved[1]: 20 | res.append([toBeRemoved[1], i[1]]) 21 | else: 22 | res.append(i) 23 | return res 24 | 25 | -------------------------------------------------------------------------------- /python/Stack/Backspace String Compare/Backspace String Compare.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def backspaceCompare(self, S, T): 3 | """ 4 | :type S: str 5 | :type T: str 6 | :rtype: bool 7 | """ 8 | 9 | def backspace(s): 10 | stack = [] 11 | for i in s: 12 | if i != "#": 13 | stack.append(i) 14 | else: 15 | if stack: 16 | stack.pop() 17 | return "".join(stack) 18 | 19 | return backspace(S) == backspace(T) -------------------------------------------------------------------------------- /python/Stack/Baseball Game/Baseball Game.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def calPoints(self, ops): 3 | """ 4 | :type ops: List[str] 5 | :rtype: int 6 | """ 7 | stack = [] 8 | 9 | for op in ops: 10 | if op.isdigit() or op[0] == "-": 11 | stack.append(int(op)) 12 | else: 13 | if op == "C": 14 | stack.pop() 15 | if op == "D": 16 | stack.append(stack[-1] * 2) 17 | if op == "+": 18 | stack.append(stack[-1] + stack[-2]) 19 | return sum(stack) -------------------------------------------------------------------------------- /python/Stack/Implement Queue using Stacks/Implement Queue using Stacks.py: -------------------------------------------------------------------------------- 1 | class MyQueue(object): 2 | 3 | def __init__(self): 4 | """ 5 | Initialize your data structure here. 6 | """ 7 | self.stack = [] 8 | self.front = 0 9 | 10 | def push(self, x): 11 | """ 12 | Push element x to the back of queue. 13 | :type x: int 14 | :rtype: None 15 | """ 16 | self.stack.append(x) 17 | 18 | def pop(self): 19 | """ 20 | Removes the element from in front of queue and returns that element. 21 | :rtype: int 22 | """ 23 | res = self.stack[self.front] 24 | self.front += 1 25 | return res 26 | 27 | def peek(self): 28 | """ 29 | Get the front element. 30 | :rtype: int 31 | """ 32 | return self.stack[self.front] 33 | 34 | def empty(self): 35 | """ 36 | Returns whether the queue is empty. 37 | :rtype: bool 38 | """ 39 | return self.front == len(self.stack) 40 | 41 | # Your MyQueue object will be instantiated and called as such: 42 | # obj = MyQueue() 43 | # obj.push(x) 44 | # param_2 = obj.pop() 45 | # param_3 = obj.peek() 46 | # param_4 = obj.empty() 47 | -------------------------------------------------------------------------------- /python/Stack/Implement Stack using Queues/Implement Stack using Queues.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class MyStack(object): 5 | 6 | def __init__(self): 7 | """ 8 | Initialize your data structure here. 9 | """ 10 | self.queue = deque() 11 | 12 | def push(self, x): 13 | """ 14 | Push element x onto stack. 15 | :type x: int 16 | :rtype: None 17 | """ 18 | self.queue.append(x) 19 | for i in range(len(self.queue) - 1): 20 | self.queue.append(self.queue.popleft()) 21 | 22 | def pop(self): 23 | """ 24 | Removes the element on top of the stack and returns that element. 25 | :rtype: int 26 | """ 27 | res = self.queue.popleft() 28 | return res 29 | 30 | def top(self): 31 | """ 32 | Get the top element. 33 | :rtype: int 34 | """ 35 | return self.queue[0] 36 | 37 | def empty(self): 38 | """ 39 | Returns whether the stack is empty. 40 | :rtype: bool 41 | """ 42 | return len(self.queue) == 0 43 | 44 | # Your MyStack object will be instantiated and called as such: 45 | # obj = MyStack() 46 | # obj.push(x) 47 | # param_2 = obj.pop() 48 | # param_3 = obj.top() 49 | # param_4 = obj.empty() 50 | -------------------------------------------------------------------------------- /python/Stack/Min Stack/Min Stack.py: -------------------------------------------------------------------------------- 1 | class MinStack(object): 2 | 3 | def __init__(self): 4 | """ 5 | initialize your data structure here. 6 | """ 7 | self.stack = [] 8 | self.min_stack = [] 9 | 10 | def push(self, x): 11 | """ 12 | :type x: int 13 | :rtype: None 14 | """ 15 | self.stack.append(x) 16 | if not self.min_stack or x < self.min_stack[-1]: 17 | self.min_stack.append(x) 18 | else: 19 | self.min_stack.append(self.min_stack[-1]) 20 | 21 | def pop(self): 22 | """ 23 | :rtype: None 24 | """ 25 | self.stack.pop() 26 | self.min_stack.pop() 27 | 28 | def top(self): 29 | """ 30 | :rtype: int 31 | """ 32 | return self.stack[-1] 33 | 34 | def getMin(self): 35 | """ 36 | :rtype: int 37 | """ 38 | return self.min_stack[-1] 39 | 40 | # Your MinStack object will be instantiated and called as such: 41 | # obj = MinStack() 42 | # obj.push(x) 43 | # obj.pop() 44 | # param_3 = obj.top() 45 | # param_4 = obj.getMin() 46 | -------------------------------------------------------------------------------- /python/Stack/Minimum Cost Tree From Leaf Values/Minimum Cost Tree From Leaf Values.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def mctFromLeafValues(self, arr): 3 | """ 4 | :type arr: List[int] 5 | :rtype: int 6 | """ 7 | stack = [float("inf")] 8 | 9 | res = 0 10 | 11 | for i in arr: 12 | while i > stack[-1]: 13 | node = stack.pop() 14 | res += min(i, stack[-1]) * node 15 | stack.append(i) 16 | 17 | while len(stack) > 2: 18 | res += stack.pop() * stack[-1] 19 | return res 20 | -------------------------------------------------------------------------------- /python/Stack/Minimum Remove to Make Valid Parentheses/Minimum Remove to Make Valid Parentheses.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minRemoveToMakeValid(self, s): 3 | """ 4 | :type s: str 5 | :rtype: str 6 | """ 7 | r = [] 8 | 9 | stack = [] 10 | 11 | for i, j in enumerate(s): 12 | if j not in ["(", ")"]: 13 | continue 14 | 15 | if j == "(": 16 | stack.append(i) 17 | 18 | else: 19 | if len(stack) == 0: 20 | r.append(i) 21 | else: 22 | if s[stack[-1]] == "(": 23 | stack.pop() 24 | 25 | r = r + stack 26 | print(r) 27 | if len(r) == 0: 28 | return s 29 | res = "" 30 | for i, j in enumerate(r): 31 | if i == 0: 32 | res += s[:j] 33 | else: 34 | res += s[r[i - 1] + 1:j] 35 | 36 | if i == len(r) - 1: 37 | res += s[j + 1:] 38 | return res 39 | -------------------------------------------------------------------------------- /python/Stack/Next Greater Element I/Next Greater Element I.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def nextGreaterElement(self, nums1, nums2): 3 | """ 4 | :type nums1: List[int] 5 | :type nums2: List[int] 6 | :rtype: List[int] 7 | """ 8 | dic = {} 9 | stack = [] 10 | 11 | for i in nums2: 12 | if not stack or i < stack[-1]: 13 | stack.append(i) 14 | else: 15 | while stack and stack[-1] < i: 16 | pre = stack.pop() 17 | dic[pre] = i 18 | stack.append(i) 19 | return [dic[i] if i in dic else -1 for i in nums1] -------------------------------------------------------------------------------- /python/Stack/Remove All Adjacent Duplicates In String/Remove All Adjacent Duplicates In String.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeDuplicates(self, S): 3 | """ 4 | :type S: str 5 | :rtype: str 6 | """ 7 | stack = [] 8 | 9 | for i in S: 10 | if not stack or i != stack[-1]: 11 | stack.append(i) 12 | else: 13 | stack.pop() 14 | return "".join(stack) -------------------------------------------------------------------------------- /python/Stack/Remove All Adjacent Duplicates in String II/Remove All Adjacent Duplicates in String II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeDuplicates(self, s, k): 3 | """ 4 | :type s: str 5 | :type k: int 6 | :rtype: str 7 | """ 8 | stack = [] 9 | for i in s: 10 | # print(stack) 11 | if not stack or stack[-1][0] != i: 12 | stack.append((i, 1)) 13 | 14 | else: 15 | count = stack[-1][-1] + 1 16 | if count == k: 17 | stack = stack[:-k + 1] 18 | else: 19 | stack.append((i, count)) 20 | return "".join([i[0] for i in stack]) 21 | -------------------------------------------------------------------------------- /python/Stack/Remove Outermost Parentheses/Remove Outermost Parentheses.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeOuterParentheses(self, S): 3 | """ 4 | :type S: str 5 | :rtype: str 6 | """ 7 | stack = [] 8 | 9 | res = "" 10 | for i in range(len(S)): 11 | char = S[i] 12 | if char == "(": 13 | stack.append(i) 14 | else: 15 | pre = stack.pop() 16 | if not stack: 17 | res += S[pre + 1:i] 18 | return res 19 | -------------------------------------------------------------------------------- /python/Stack/Reverse Substrings Between Each Pair of Parentheses/Reverse Substrings Between Each Pair of Parentheses.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reverseParentheses(self, s): 3 | """ 4 | :type s: str 5 | :rtype: str 6 | """ 7 | stack = [] 8 | 9 | for i, j in enumerate(s): 10 | if j != ")": 11 | stack.append(j) 12 | else: 13 | temp = "" 14 | while stack[-1] != "(": 15 | temp += stack.pop() 16 | stack.pop() 17 | for t in temp: 18 | stack.append(t) 19 | return "".join(stack) 20 | -------------------------------------------------------------------------------- /python/Stack/Simplify Path/Simplify Path.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def simplifyPath(self, path): 3 | """ 4 | :type path: str 5 | :rtype: str 6 | """ 7 | dirs = path.split("/") 8 | 9 | stack = [] 10 | 11 | for d in dirs: 12 | if d == "" or d == ".": 13 | continue 14 | elif d == "..": 15 | if stack: 16 | stack.pop() 17 | else: 18 | stack.append(d) 19 | return "/" + "/".join(stack) 20 | -------------------------------------------------------------------------------- /python/Stack/Valid Parentheses/Valid Parentheses.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isValid(self, s: str) -> bool: 3 | stack = [] 4 | for ch in s: 5 | if not stack: 6 | stack.append(ch) 7 | else: 8 | if ch == ")" and stack[-1] == "(": 9 | stack.pop() 10 | elif ch == "]" and stack[-1] == "[": 11 | stack.pop() 12 | elif ch == "}" and stack[-1] == "{": 13 | stack.pop() 14 | else: 15 | stack.append(ch) 16 | return len(stack) == 0 17 | -------------------------------------------------------------------------------- /python/String/Equal Rational Numbers/Equal Rational Numbers.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isRationalEqual(self, S, T): 3 | """ 4 | :type S: str 5 | :type T: str 6 | :rtype: bool 7 | """ 8 | def f(s): 9 | index = s.find("(") 10 | if index!=-1: 11 | s = s[:index]+s[index+1:-1]*20 12 | return s[:20] 13 | return float(f(S))==float(f(T)) 14 | -------------------------------------------------------------------------------- /python/String/Find Winner on a Tic Tac Toe Game/Find Winner on a Tic Tac Toe Game.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def tictactoe(self, moves: List[List[int]]) -> str: 3 | chess = [[0 for i in range(3)] for j in range(3)] 4 | 5 | for i, move in enumerate(moves): 6 | if i % 2 == 0: 7 | chess[move[0]][move[1]] = 1 8 | else: 9 | chess[move[0]][move[1]] = 2 10 | 11 | for i in range(3): 12 | if chess[i] == [1, 1, 1]: 13 | return "A" 14 | if chess[i] == [2, 2, 2]: 15 | return "B" 16 | if [chess[0][i], chess[1][i], chess[2][i]] == [1, 1, 1]: 17 | return "A" 18 | if [chess[0][i], chess[1][i], chess[2][i]] == [2, 2, 2]: 19 | return "B" 20 | if [chess[0][0], chess[1][1], chess[2][2]] == [1, 1, 1]: 21 | return "A" 22 | if [chess[0][0], chess[1][1], chess[2][2]] == [2, 2, 2]: 23 | return "B" 24 | if [chess[0][2], chess[1][1], chess[2][0]] == [1, 1, 1]: 25 | return "A" 26 | if [chess[0][2], chess[1][1], chess[2][0]] == [2, 2, 2]: 27 | return "B" 28 | if sum([sum(i) for i in chess]) == 13: 29 | return "Draw" 30 | 31 | return "Pending" 32 | 33 | -------------------------------------------------------------------------------- /python/String/Hexspeak/Hexspeak.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def toHexspeak(self, num: str) -> str: 3 | h = hex(int(num))[2:] 4 | temp = [] 5 | for i in h: 6 | if i=="0": 7 | temp.append("O") 8 | elif i=="1": 9 | temp.append("I") 10 | else: 11 | temp.append(i.upper()) 12 | for i in temp: 13 | if i not in {"A", "B", "C", "D", "E", "F", "I", "O"}: 14 | return "ERROR" 15 | return "".join(temp) -------------------------------------------------------------------------------- /python/String/Split a String in Balanced Strings/Split a String in Balanced Strings.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def balancedStringSplit(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | count = 0 8 | res = 0 9 | for i in s: 10 | if i=="L": 11 | count-=1 12 | else: 13 | count+=1 14 | if count==0: 15 | res+=1 16 | return res 17 | -------------------------------------------------------------------------------- /python/Tree/Binary Tree Coloring Game/Binary Tree Coloring Game.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def btreeGameWinningMove(self, root, n, x): 10 | """ 11 | :type root: TreeNode 12 | :type n: int 13 | :type x: int 14 | :rtype: bool 15 | """ 16 | 17 | self.left = 0 18 | self.right = 0 19 | 20 | def count(node): 21 | if not node: 22 | return 0 23 | l = count(node.left) 24 | r = count(node.right) 25 | if node.val == x: 26 | self.left = l 27 | self.right = r 28 | return l + r + 1 29 | 30 | c = count(root) 31 | return max(self.left, self.right, c - self.left - self.right - 1) > (c // 2) 32 | -------------------------------------------------------------------------------- /python/Tree/Delete Tree Nodes/Delete Tree Nodes.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution: 5 | def deleteTreeNodes(self, nodes: int, parent: List[int], value: List[int]) -> int: 6 | 7 | child = defaultdict(list) 8 | 9 | for i, j in enumerate(parent): 10 | child[j].append(i) 11 | 12 | s = {} 13 | 14 | def dp(node): 15 | if len(child[node]) == 0: 16 | s[node] = value[node] 17 | return s[node] 18 | else: 19 | if node == -1: 20 | t = 0 21 | else: 22 | t = value[node] 23 | for i in child[node]: 24 | t += dp(i) 25 | s[node] = t 26 | return s[node] 27 | 28 | dp(-1) 29 | 30 | s[-1] = 1 31 | 32 | print(s) 33 | 34 | queue = [-1] 35 | res = 0 36 | 37 | while queue: 38 | for i in range(len(queue)): 39 | node = queue.pop() 40 | if s[node] == 0: 41 | pass 42 | else: 43 | res += 1 44 | for j in child[node]: 45 | queue.append(j) 46 | return res - 1 -------------------------------------------------------------------------------- /python/Tree/Lowest Common Ancestor of Deepest Leaves/Lowest Common Ancestor of Deepest Leaves.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def lcaDeepestLeaves(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: TreeNode 13 | """ 14 | 15 | def recur(node): 16 | if not node: 17 | return 0, None 18 | d1, left = recur(node.left) 19 | d2, right = recur(node.right) 20 | 21 | if d1 < d2: 22 | temp = right 23 | elif d1 > d2: 24 | temp = left 25 | else: 26 | temp = node 27 | return max(d1, d2) + 1, temp 28 | 29 | return recur(root)[1] 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /python/Tree/Scramble String/Scramble String.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isScramble(self, s1, s2): 3 | """ 4 | :type s1: str 5 | :type s2: str 6 | :rtype: bool 7 | """ 8 | if s1 == s2: 9 | return True 10 | if sorted(s1) != sorted(s2): 11 | return False 12 | 13 | for i in range(1, len(s1)): 14 | print(s1, s2) 15 | if self.isScramble(s1[:i], s2[:i]) and self.isScramble(s1[i:], s2[i:]): 16 | return True 17 | if self.isScramble(s1[:i], s2[-i:]) and self.isScramble(s1[i:], s2[:len(s1) - i]): 18 | return True 19 | return False 20 | -------------------------------------------------------------------------------- /python/Tree/Tree Diameter/Tree Diameter.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def treeDiameter(self, edges): 6 | """ 7 | :type edges: List[List[int]] 8 | :rtype: int 9 | """ 10 | self.res = 0 11 | 12 | graph = defaultdict(list) 13 | 14 | for i, j in edges: 15 | graph[i].append(j) 16 | graph[j].append(i) 17 | 18 | def bfs(node, parent): 19 | print(node, parent) 20 | if len(graph[node]) == 1: 21 | if graph[node][0] == parent: 22 | if 1 > self.res: 23 | self.res = 1 24 | return 1 25 | else: 26 | t = 1 + bfs(graph[node][0], node) 27 | if t > self.res: 28 | self.res = t 29 | return t 30 | else: 31 | res = [] 32 | for i in graph[node]: 33 | if i == parent: 34 | continue 35 | else: 36 | res.append(bfs(i, node)) 37 | print(res) 38 | if len(res) == 1: 39 | if res[0] > self.res: 40 | self.res = res[0] + 1 41 | return res[0] + 1 42 | else: 43 | res.sort() 44 | if res[-1] + res[-2] > self.res: 45 | self.res = res[-1] + res[-2] 46 | return 1 + res[-1] 47 | 48 | bfs(0, None) 49 | return self.res -------------------------------------------------------------------------------- /python/Tree/Two Sum BSTs/Two Sum BSTs.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def twoSumBSTs(self, root1, root2, target): 10 | """ 11 | :type root1: TreeNode 12 | :type root2: TreeNode 13 | :type target: int 14 | :rtype: bool 15 | """ 16 | 17 | def inorder(node): 18 | if not node: 19 | return [] 20 | else: 21 | return inorder(node.left) + [node.val] + inorder(node.right) 22 | 23 | t1 = inorder(root1) 24 | t2 = inorder(root2) 25 | 26 | i = 0 27 | j = len(t2) - 1 28 | 29 | while i < len(t1) and j >= 0: 30 | if t1[i] + t2[j] == target: 31 | return True 32 | else: 33 | if t1[i] + t2[j] > target: 34 | j -= 1 35 | else: 36 | i += 1 37 | return False 38 | -------------------------------------------------------------------------------- /python/Trie/Remove Sub-Folders from the Filesystem/Remove Sub-Folders from the Filesystem.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution(object): 5 | def removeSubfolders(self, folder): 6 | """ 7 | :type folder: List[str] 8 | :rtype: List[str] 9 | """ 10 | Trie = lambda: defaultdict(Trie) 11 | 12 | trie = Trie() 13 | END = True 14 | 15 | # for path in folder: 16 | # reduce(dict.__getitem__, path, trie)[END] = path 17 | 18 | for path in folder: 19 | t = trie 20 | p = path.split("/") 21 | # print(p) 22 | for i in range(1, len(p)): 23 | if True in t.keys(): 24 | break 25 | t = t[p[i]] 26 | if True not in t.keys(): 27 | t[True] = path 28 | # print(trie) 29 | 30 | res = set() 31 | for path in folder: 32 | temp = "/" 33 | t = trie 34 | p = path.split("/") 35 | for i in p[1:]: 36 | temp += i 37 | if True in t[i].keys(): 38 | res.add(temp) 39 | break 40 | t = t[i] 41 | temp += "/" 42 | res = list(res) 43 | return res 44 | 45 | -------------------------------------------------------------------------------- /python/Union Find/Accounts Merge/Accounts Merge.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class DSU: 5 | def __init__(self): 6 | self.parents = range(10001) 7 | self.rank = [0]*10001 8 | 9 | def find(self, x): 10 | if self.parents[x] != x: 11 | self.parents[x] = self.find(self.parents[x]) 12 | return self.parents[x] 13 | 14 | def union(self, x, y): 15 | xr, yr = self.find(x), self.find(y) 16 | if xr == yr: 17 | return 18 | if self.rank[xr] < self.rank[yr]: 19 | self.parents[xr] = yr 20 | elif self.rank[xr] > self.rank[yr]: 21 | self.parents[yr] = xr 22 | else: 23 | self.parents[xr] = yr 24 | self.rank[yr] += 1 25 | return 26 | 27 | 28 | class Solution(object): 29 | def accountsMerge(self, accounts): 30 | """ 31 | :type accounts: List[List[str]] 32 | :rtype: List[List[str]] 33 | """ 34 | dsu = DSU() 35 | em_to_name = {} 36 | em_to_id = {} 37 | i = 0 38 | for acc in accounts: 39 | name = acc[0] 40 | for email in acc[1:]: 41 | em_to_name[email] = name 42 | if email not in em_to_id: 43 | em_to_id[email] = i 44 | i += 1 45 | dsu.union(em_to_id[acc[1]], em_to_id[email]) 46 | 47 | ans = defaultdict(list) 48 | for email in em_to_name: 49 | ans[dsu.find(em_to_id[email])].append(email) 50 | 51 | res = [] 52 | for k in ans: 53 | temp = [] 54 | v = ans[k] 55 | temp.append(em_to_name[v[0]]) 56 | temp += (sorted(v)) 57 | res.append(temp) 58 | return res 59 | -------------------------------------------------------------------------------- /python/Union Find/Connecting Cities With Minimum Cost/Connecting Cities With Minimum Cost.py: -------------------------------------------------------------------------------- 1 | class DSU: 2 | def __init__(self): 3 | self.parents = range(10001) 4 | self.rank = [0 for i in range(10001)] 5 | 6 | def find(self, x): 7 | if self.parents[x] != x: 8 | self.parents[x] = self.find(self.parents[x]) 9 | return self.parents[x] 10 | 11 | def union(self, x, y): 12 | xr, yr = self.find(x), self.find(y) 13 | if xr == yr: 14 | return False 15 | if self.rank[xr] < self.rank[yr]: 16 | self.parents[xr] = yr 17 | elif self.rank[xr] > self.rank[yr]: 18 | self.parents[yr] = xr 19 | else: 20 | self.parents[xr] = yr 21 | self.rank[yr] += 1 22 | return True 23 | 24 | 25 | class Solution(object): 26 | def minimumCost(self, N, conections): 27 | """ 28 | :type N: int 29 | :type conections: List[List[int]] 30 | :rtype: int 31 | """ 32 | conections.sort(key=lambda x: x[-1]) 33 | 34 | count = N 35 | res = 0 36 | dsu = DSU() 37 | for i, j, v in conections: 38 | if dsu.union(i - 1, j - 1): 39 | count -= 1 40 | res += v 41 | if count == 1: 42 | return res 43 | else: 44 | return -1 45 | -------------------------------------------------------------------------------- /python/Union Find/DSU Structure/DSU Structure.py: -------------------------------------------------------------------------------- 1 | class DSU: 2 | def __init__(self): 3 | self.parents = range(10001) 4 | self.rank = [0 for i in range(10001)] 5 | 6 | def find(self, x): 7 | if self.parents[x]!=x: 8 | self.parents[x] = self.find(self.parents[x]) 9 | return self.parents[x] 10 | 11 | def union(self, x, y): 12 | xr,yr = self.find(x),self.find(y) 13 | if xr == yr: 14 | return False 15 | if self.rank[xr]self.rank[yr]: 18 | self.parents[yr] = xr 19 | else: 20 | self.parents[xr] = yr 21 | self.rank[yr] += 1 22 | return True 23 | -------------------------------------------------------------------------------- /python/Union Find/Minimize Malware Spread/Minimize Malware Spread.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | class DSU: 4 | def __init__(self, n): 5 | self.parents = range(n) 6 | self.rank = [0] * n 7 | 8 | def find(self, x): 9 | if self.parents[x] != x: 10 | self.parents[x] = self.find(self.parents[x]) 11 | return self.parents[x] 12 | 13 | def union(self, x, y): 14 | xr, yr = self.find(x), self.find(y) 15 | if xr == yr: 16 | return 17 | if self.rank[xr] > self.rank[yr]: 18 | self.parents[yr] = xr 19 | elif self.rank[yr] > self.rank[xr]: 20 | self.parents[xr] = yr 21 | else: 22 | self.parents[yr] = xr 23 | self.rank[xr] += 1 24 | return 25 | 26 | 27 | class Solution(object): 28 | def minMalwareSpread(self, graph, initial): 29 | """ 30 | :type graph: List[List[int]] 31 | :type initial: List[int] 32 | :rtype: int 33 | """ 34 | dsu = DSU(400) 35 | 36 | for i in range(len(graph)): 37 | for j in range(len(graph[i])): 38 | if graph[i][j] == 1: 39 | dsu.union(i, j) 40 | 41 | c = Counter([dsu.find(i) for i in initial]) 42 | cc = Counter([dsu.find(i) for i in range(len(graph))]) 43 | 44 | initial.sort() 45 | res = (initial[0], 0) 46 | for j in initial: 47 | root = dsu.find(j) 48 | if c[root] == 1: 49 | if cc[root] > res[1]: 50 | res = (j, cc[root]) 51 | return res[0] 52 | 53 | -------------------------------------------------------------------------------- /python/Union Find/Most Stones Removed with Same Row or Column/Most Stones Removed with Same Row or Column.py: -------------------------------------------------------------------------------- 1 | class DSU: 2 | def __init__(self): 3 | self.parents = range(20001) 4 | self.rank = [0] * 20001 5 | 6 | def find(self, x): 7 | if self.parents[x] != x: 8 | self.parents[x] = self.find(self.parents[x]) 9 | return self.parents[x] 10 | 11 | def union(self, x, y): 12 | xr, yr = self.find(x), self.find(y) 13 | if xr == yr: 14 | return 15 | else: 16 | if self.rank[xr] < self.rank[yr]: 17 | self.parents[xr] = yr 18 | elif self.rank[xr] > self.rank[xr]: 19 | self.parents[yr] = xr 20 | else: 21 | self.parents[yr] = xr 22 | self.rank[xr] += 1 23 | return 24 | 25 | 26 | class Solution(object): 27 | def removeStones(self, stones): 28 | """ 29 | :type stones: List[List[int]] 30 | :rtype: int 31 | """ 32 | dsu = DSU() 33 | for x, y in stones: 34 | dsu.union(x, y + 10000) 35 | 36 | return len(stones) - len(set([dsu.find(x) for x, y in stones])) 37 | -------------------------------------------------------------------------------- /python/Union Find/Optimize Water Distribution in a Village/Optimize Water Distribution in a Village.py: -------------------------------------------------------------------------------- 1 | class DSU: 2 | def __init__(self): 3 | self.parents = range(10001) 4 | self.rank = [0 for i in range(10001)] 5 | 6 | def find(self, x): 7 | if self.parents[x] != x: 8 | self.parents[x] = self.find(self.parents[x]) 9 | return self.parents[x] 10 | 11 | def union(self, x, y): 12 | xr, yr = self.find(x), self.find(y) 13 | if xr == yr: 14 | return False 15 | if self.rank[xr] < self.rank[yr]: 16 | self.parents[xr] = yr 17 | elif self.rank[xr] > self.rank[yr]: 18 | self.parents[yr] = xr 19 | else: 20 | self.parents[xr] = yr 21 | self.rank[yr] += 1 22 | return True 23 | 24 | 25 | class Solution(object): 26 | def minCostToSupplyWater(self, n, wells, pipes): 27 | """ 28 | :type n: int 29 | :type wells: List[int] 30 | :type pipes: List[List[int]] 31 | :rtype: int 32 | """ 33 | dsu = DSU() 34 | dic = {} 35 | for i, w in enumerate(wells): 36 | dic[(0, i + 1)] = w 37 | for i, j, p in pipes: 38 | dic[(i, j)] = p 39 | 40 | keys = sorted(dic.keys(), key=lambda x: dic[x]) 41 | res = 0 42 | for i, j in keys: 43 | if dsu.find(i) == dsu.find(j): 44 | continue 45 | else: 46 | dsu.union(i, j) 47 | res += dic[(i, j)] 48 | return res 49 | -------------------------------------------------------------------------------- /python/Union Find/Smallest String With Swaps/Smallest String With Swaps.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class DSU: 5 | def __init__(self): 6 | self.parents = range(100001) 7 | self.rank = [0 for i in range(100001)] 8 | 9 | def find(self, x): 10 | if self.parents[x] != x: 11 | self.parents[x] = self.find(self.parents[x]) 12 | return self.parents[x] 13 | 14 | def union(self, x, y): 15 | xr, yr = self.find(x), self.find(y) 16 | if xr == yr: 17 | return False 18 | if self.rank[xr] < self.rank[yr]: 19 | self.parents[xr] = yr 20 | elif self.rank[xr] > self.rank[yr]: 21 | self.parents[yr] = xr 22 | else: 23 | self.parents[xr] = yr 24 | self.rank[yr] += 1 25 | return True 26 | 27 | 28 | class Solution(object): 29 | def smallestStringWithSwaps(self, s, pairs): 30 | """ 31 | :type s: str 32 | :type pairs: List[List[int]] 33 | :rtype: str 34 | """ 35 | 36 | dsu = DSU() 37 | for pair in pairs: 38 | dsu.union(pair[0], pair[1]) 39 | 40 | dic = defaultdict(list) 41 | 42 | for i, j in enumerate(s): 43 | dic[dsu.find(i)].append(j) 44 | 45 | for key in dic.keys(): 46 | dic[key].sort() 47 | # print(dic) 48 | res = "" 49 | 50 | for i in range(len(s)): 51 | res += dic[dsu.find(i)].pop(0) 52 | return res 53 | -------------------------------------------------------------------------------- /python/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baldFemale/LeetCode-Solution/d89ebad5305e4d1a185b0c6f101a88691602b523/python/__init__.py --------------------------------------------------------------------------------