{"/":{"md":"---\ntitle: Introduction\ndescription: Structured dependency spine based roadmap for solving DSA Problems on leetcode.\nicon: play\n---\n\n## 1. Linear Structures\n\n:::tip\nData is read in one direction, from the first item to the last. The current position is recorded at each step. All later phases use this skill.\n:::\n\n**[Hash Table](/hash-table)**\n\nA key maps to a value in constant time, which removes the need for a full scan.\n\n**[Prefix Sum](/prefix-sum)**\n\nA running total is stored at each index, so the sum of any range is one subtraction.\n\n**[Two Pointers](/two-pointers)**\n\nTwo indices move through the data from different positions and meet at the answer.\n\n**[Sliding Window](/sliding-window)**\n\nA range with a start and an end moves across the data, and the contents are updated at each step.\n\n**[Binary Search](/binary-search)**\n\nHalf of a sorted range is removed at each step until the target is found.\n\n**[Stack](/stack)**\n\nItems are added and removed from one end, so the last item added is the first item removed.\n\n**[Monotonic Stack](/monotonic-stack)**\n\nA stack keeps its items in sorted order, which finds the next larger or smaller item in one pass.\n\n## 2. Nodal & Grid\n\n:::tip\nThe data is in separate parts. Each part points to the next part, or sits next to other parts on a flat surface. An index does not find the next item. The pointers or the neighbors give the path instead.\n:::\n\n**[Linked List](/linked-list)**\n\nEach node points to the next node, and the pointers give the path through the data.\n\n**[Hybrid Structures](/hybrid-structures)**\n\nTwo structures are combined, such as a hash map and a linked list, to get the best properties of each.\n\n**[Matrix Index Math](/matrix-index-math)**\n\nA two-dimensional grid is read as a flat array through a formula, and the neighbors are found by arithmetic.\n\n## 3. Hierarchical\n\n:::tip\nEach part points to one or more parts below it. Those parts do the same. The method that solves a small part also solves the large part. This is recursion.\n:::\n\n**[Tree DFS](/tree-dfs)**\n\nEach branch is followed to its end before the next branch is examined.\n\n**[Tree BFS](/tree-bfs)**\n\nAll nodes at one level are visited before the nodes at the next level.\n\n**[Binary Search Tree](/binary-search-tree)**\n\nEach node holds a value that is larger than its left subtree and smaller than its right subtree.\n\n**[Heap](/heap-priority-queue)**\n\nThe largest or smallest item is always at the top, and it is removed in logarithmic time.\n\n**[Trie](/trie)**\n\nEach node holds one character, and a path from the root spells a word.\n\n## 4. Relational\n\n:::tip\nEach part can point to any other part. Loops can occur. The method must visit each part one time only. The order of the parts, or the distance between them, is not given in the data. The method finds it.\n:::\n\n**[Graph DFS](/graph-dfs)**\n\nEach edge is followed to its end, and a visited set prevents a repeat visit.\n\n**[Graph BFS](/graph-bfs)**\n\nNodes are visited in order of distance from the start, which gives the shortest path in an unweighted graph.\n\n**[Topological Sort](/topological-sort)**\n\nNodes are put in an order where each node comes after all nodes that point to it.\n\n**[Union-Find](/union-find)**\n\nTwo sets are merged and the set of any item is found in near-constant time.\n\n## 5. Decision Space\n\n:::tip\nThe data has no structure. The method makes one. Each choice makes a new branch. The problem sets the correct method: examine all branches, keep a record of the results already found, or make one choice and do not go back.\n:::\n\n**[Backtracking](/backtracking)**\n\nEach choice makes a branch, and a branch is undone when it does not give a valid result.\n\n**[1-D DP](/1d-dynamic-programming)**\n\nThe result for each state is stored in a list, and each new result is computed from the results before it.\n\n**[Multi-D / Grid DP](/multi-d-grid-dp)**\n\nThe result for each state is stored in a table with two or more dimensions, and each cell is computed from its neighbors.\n\n**[Greedy](/greedy)**\n\nThe best local choice is made at each step and is not changed later.\n\n**[Intervals](/intervals)**\n\nRanges with a start and an end are sorted, and then merged, counted, or scheduled.\n","mdx":"---\ntitle: Introduction\ndescription: Structured dependency spine based roadmap for solving DSA Problems on leetcode.\nicon: play\n---\n\n## 1. Linear Structures\n\n:::tip\nData is read in one direction, from the first item to the last. The current position is recorded at each step. All later phases use this skill.\n:::\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n## 2. Nodal & Grid\n\n:::tip\nThe data is in separate parts. Each part points to the next part, or sits next to other parts on a flat surface. An index does not find the next item. The pointers or the neighbors give the path instead.\n:::\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n## 3. Hierarchical\n\n:::tip\nEach part points to one or more parts below it. Those parts do the same. The method that solves a small part also solves the large part. This is recursion.\n:::\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n## 4. Relational\n\n:::tip\nEach part can point to any other part. Loops can occur. The method must visit each part one time only. The order of the parts, or the distance between them, is not given in the data. The method finds it.\n:::\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n## 5. Decision Space\n\n:::tip\nThe data has no structure. The method makes one. Each choice makes a new branch. The problem sets the correct method: examine all branches, keep a record of the results already found, or make one choice and do not go back.\n:::\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n"},"/1d-dynamic-programming":{"mdx":"---\ntitle: 1-D Dynamic Programming\ndescription: 'The result for each state is stored in a list, and each new result is computed from the results before it.'\nhidden: true\n---\n"},"/1d-dynamic-programming/climbing-stairs":{"mdx":"---\ntitle: '70. Climbing Stairs'\ndescription: You are climbing a staircase. It takes n steps to reach the top\nicon: dot\ntopics:\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Memoization\", slug: \"memoization\" }\nissue: \"https://github.com/prdlk/leetcode/issues/157\"\ncompanies:\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 80.2 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Intuit\", period: \"Thirty Days\", frequency: 66.1 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Deloitte\", period: \"Six Months\", frequency: 81 }\nsidebar:\n label: 'Climbing Stairs'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `n = 2`\n- Output: `2`\n- Explanation: There are two ways to climb to the top. `1`. `1` step + `1` step `2`. `2` steps\n\n### Example 2:\n- Input: `n = 3`\n- Output: `3`\n- Explanation: There are three ways to climb to the top. `1`. `1` step + `1` step + `1` step `2`. `1` step + `2` steps `3`. `2` steps + `1` step\n\n### Constraints:\n\n- `1 <= n <= 45`\n\n## Solution\n\n```py\nclass Solution:\n def climbStairs(self, n: int) -> int:\n if n == 1:\n return 1\n if n == 2:\n return 2\n\n first, second = 1, 2\n\n for _ in range(3, n + 1):\n third = first + second\n first, second = second, third\n\n return second\n```\n"},"/1d-dynamic-programming/coin-change":{"mdx":"---\ntitle: '322. Coin Change'\ndescription: You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Knapsack Problem\", slug: \"knapsack-problem\" }\n - { name: \"Complete Knapsack\", slug: \"complete-knapsack\" }\nissue: \"https://github.com/prdlk/leetcode/issues/159\"\ncompanies:\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 59.7 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 48.7 }\n - { name: \"Intuit\", period: \"Six Months\", frequency: 71.5 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 67.9 }\n - { name: \"Pinterest\", period: \"Six Months\", frequency: 64.4 }\nsidebar:\n label: 'Coin Change'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `coins = [1,2,5], amount = 11`\n- Output: `3`\n- Explanation: `11 = 5 + 5 + 1`\n\n### Example 2:\n- Input: `coins = [2], amount = 3`\n- Output: `-1`\n\n### Example 3:\n- Input: `coins = [1], amount = 0`\n- Output: `0`\n\n### Constraints:\n\n- `1 <= coins.length <= 12`\n- `1 <= coins[i] <= 2^31 - 1`\n- `0 <= amount <= 10^4`\n\n## Solution\n\n```py\nfrom math import inf\n\n\nclass Solution:\n def coinChange(self, coins: list[int], amount: int) -> int:\n n = len(coins)\n memo = [[-1] * (amount + 1) for _ in range(n + 1)]\n\n def min_coins(coins, i, amount, memo):\n if amount == 0:\n return 0\n if i == 0 or amount < 0:\n return inf\n if memo[i][amount] != -1:\n return memo[i][amount]\n\n skip = min_coins(coins, i - 1, amount, memo)\n use = min_coins(coins, i, amount - coins[i - 1], memo)\n if use != inf:\n use += 1\n\n memo[i][amount] = min(skip, use)\n return memo[i][amount]\n\n result = min_coins(coins, n, amount, memo)\n return result if result != inf else -1 # pyright: ignore[reportReturnType]\n```\n"},"/1d-dynamic-programming/house-robber":{"mdx":"---\ntitle: '198. House Robber'\ndescription: You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\nissue: \"https://github.com/prdlk/leetcode/issues/158\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 68.6 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 53.2 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Freecharge\", period: \"Six Months\", frequency: 100 }\n - { name: \"Agoda\", period: \"Six Months\", frequency: 65 }\nsidebar:\n label: 'House Robber'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,2,3,1]`\n- Output: `4`\n- Explanation: Rob house `1` (money = `1`) and then rob house `3` (money = `3`). Total amount you can rob = `1 + 3 = 4`.\n\n### Example 2:\n- Input: `nums = [2,7,9,3,1]`\n- Output: `12`\n- Explanation: Rob house `1` (money = `2`), rob house `3` (money = `9`) and rob house `5` (money = `1`). Total amount you can rob = `2 + 9 + 1 = 12`.\n\n### Constraints:\n\n- `1 <= nums.length <= 100`\n- `0 <= nums[i] <= 400`\n\n## Solution\n\n```py\nclass Solution:\n def rob(self, nums: list[int]) -> int:\n n = len(nums)\n if n == 0:\n return 0\n if n <= 2:\n return max(nums)\n\n dp = [0] * n\n dp[0] = nums[0]\n dp[1] = max(nums[0], nums[1])\n for i in range(2, n):\n dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])\n return dp[-1]\n```\n"},"/backtracking":{"mdx":"---\ntitle: Backtracking\ndescription: 'Backtracking is a depth-first search technique that builds a solution step by step and abandons (undoes) a partial choice as soon as it can’t lead to a valid complete solution.'\nhidden: true\n---\n\n## What it is\n\nBacktracking explores possible paths to a solution one step at a time. When a path reaches a dead end, you undo the last step and try a different option. Think of every problem as a decision tree. The root is an empty answer. Each level is a decision. Each branch is one option.\n\n## When to use it\n\nUse backtracking when you must generate **all** valid solutions or evaluate **all** combinations. Do not use it when you need only one solution or the optimal solution. For those, use greedy or dynamic programming. Backtracking has exponential time complexity.\n\n## The four components\n\nEvery backtracking problem has the same parts:\n\n1. **Base case** — when to save the current path and stop.\n2. **Choices** — the options at each step.\n3. **Constraints** — the rules that reject an invalid path early.\n4. **Backtrack step** — undo the last choice and try the next one.\n\n## The template\n\n```python\ndef solve(data):\n result = []\n path = []\n\n def backtrack(index):\n # 1. Base case\n if is_complete(index, path):\n result.append(path[:]) # copy — lists are passed by reference\n return\n\n # 2. Choices\n for choice in get_choices(index, data):\n # 3. Constraints\n if not is_valid(choice, path):\n continue\n\n path.append(choice) # make the choice\n backtrack(index + 1) # explore\n path.pop() # 4. Backtrack\n\n backtrack(0)\n return result\n```\n\n## Steps to apply the template\n\n1. Draw the decision tree for a small input. Name each level and each branch.\n2. Write the base case. Ask: when is the path complete?\n3. Write the choices. Ask: what can I add at this level?\n4. Write the constraints. Ask: what makes a path invalid? Reject it before recursion.\n5. Add the backtrack step. Pop what you appended.\n6. Copy the path when you save it. Never append the same list reference.\n\n## Four problems, one template\n\n### Subsets\n\nChoice: include or skip each number. No constraint. Base case: index equals list length.\n\n```python\ndef subsets(nums):\n result, path = [], []\n\n def backtrack(i):\n if i == len(nums):\n result.append(path[:])\n return\n path.append(nums[i]) # include\n backtrack(i + 1)\n path.pop()\n backtrack(i + 1) # skip\n\n backtrack(0)\n return result\n```\n\n### Permutations\n\nSame choices as subsets. Constraint: do not reuse a number already in the path. Base case: path length equals list length.\n\n```python\ndef permute(nums):\n result, path = [], []\n used = [False] * len(nums)\n\n def backtrack():\n if len(path) == len(nums):\n result.append(path[:])\n return\n for i in range(len(nums)):\n if used[i]:\n continue\n used[i] = True\n path.append(nums[i])\n backtrack()\n path.pop()\n used[i] = False\n\n backtrack()\n return result\n```\n\n### Combinations\n\nSame as subsets. Change one line: save the path only when its length equals `k`.\n\n```python\ndef combine(n, k):\n result, path = [], []\n\n def backtrack(start):\n if len(path) == k:\n result.append(path[:])\n return\n for i in range(start, n + 1):\n path.append(i)\n backtrack(i + 1)\n path.pop()\n\n backtrack(1)\n return result\n```\n\n### N-Queens\n\nChoice: which column to place the queen in the current row. Constraint: no shared column or diagonal. Base case: `n` queens placed. Backtrack: remove the last queen.\n\n```python\ndef solve_n_queens(n):\n result, cols = [], []\n used_cols, diag1, diag2 = set(), set(), set()\n\n def backtrack(row):\n if row == n:\n result.append(cols[:])\n return\n for col in range(n):\n if col in used_cols or row - col in diag1 or row + col in diag2:\n continue\n cols.append(col)\n used_cols.add(col); diag1.add(row - col); diag2.add(row + col)\n backtrack(row + 1)\n cols.pop()\n used_cols.remove(col); diag1.remove(row - col); diag2.remove(row + col)\n\n backtrack(0)\n return result\n```\n\n## Common mistakes\n\n- You append the `path` list itself instead of a copy. The result fills with empty lists.\n- You forget to pop. The path grows and never resets.\n- You check constraints after recursion instead of before. You waste time on dead paths.\n- You use backtracking when you need only one answer. Use greedy or DP instead.\n\n\n"},"/backtracking/combination-sum":{"mdx":"---\ntitle: '39. Combination Sum'\ndescription: Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Backtracking\", slug: \"backtracking\" }\nissue: \"https://github.com/prdlk/leetcode/issues/150\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 41 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 30.1 }\nsidebar:\n label: 'Combination Sum'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `candidates = [2,3,6,7], target = 7`\n- Output: `[[2,2,3],[7]]`\n- Explanation: `2` and `3` are `candidates`, and `2 + 2 + 3 = 7`. Note that `2` can be used multiple times. `7` is a candidate, and `7 = 7`. These are the only two combinations.\n\n### Example 2:\n- Input: `candidates = [2,3,5], target = 8`\n- Output: `[[2,2,2,2],[2,3,3],[3,5]]`\n\n### Example 3:\n- Input: `candidates = [2], target = 1`\n- Output: `[]`\n\n### Constraints:\n\n- `1 <= candidates.length <= 30`\n- `2 <= candidates[i] <= 40`\n- All elements of `candidates` are distinct.\n- `1 <= target <= 40`\n\n## Solution\n\n```py\nclass Solution:\n def combinationSum(self, candidates: list[int], target: int) -> list[list[int]]:\n candidates.sort()\n result, path = [], []\n\n def backtrack(start, remaining):\n if remaining == 0:\n result.append(path[:])\n return\n for i in range(start, len(candidates)):\n if candidates[i] > remaining:\n break\n\n path.append(candidates[i])\n backtrack(i, remaining - candidates[i])\n path.pop()\n\n backtrack(0, target)\n return result\n```\n"},"/backtracking/permutations":{"mdx":"---\ntitle: '46. Permutations'\ndescription: Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Backtracking\", slug: \"backtracking\" }\nissue: \"https://github.com/prdlk/leetcode/issues/151\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Google\", period: \"Three Months\", frequency: 32.7 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 67.9 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 43.4 }\nsidebar:\n label: 'Permutations'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,2,3]`\n- Output: `[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]`\n\n### Example 2:\n- Input: `nums = [0,1]`\n- Output: `[[0,1],[1,0]]`\n\n### Example 3:\n- Input: `nums = [1]`\n- Output: `[[1]]`\n\n### Constraints:\n\n- `1 <= nums.length <= 6`\n- `-10 <= nums[i] <= 10`\n- All the integers of `nums` are unique.\n\n## Solution\n\n```py\nclass Solution:\n def permute(self, nums: list[int]) -> list[list[int]]:\n result, path = [], []\n used = [False] * len(nums)\n\n def backtrack():\n if len(path) == len(nums):\n result.append(path[:])\n return\n for i in range(len(nums)):\n if used[i]:\n continue\n used[i] = True\n path.append(nums[i])\n backtrack()\n path.pop()\n used[i] = False\n\n backtrack()\n return result\n```\n"},"/backtracking/subsets":{"mdx":"---\ntitle: '78. Subsets'\ndescription: Given an integer array nums of unique elements, return all possible subsets (the power set)\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Backtracking\", slug: \"backtracking\" }\n - { name: \"Bit Manipulation\", slug: \"bit-manipulation\" }\nissue: \"https://github.com/prdlk/leetcode/issues/149\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 61.3 }\n - { name: \"Agoda\", period: \"Three Months\", frequency: 75.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 64.9 }\nsidebar:\n label: 'Subsets'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,2,3]`\n- Output: `[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]`\n\n### Example 2:\n- Input: `nums = [0]`\n- Output: `[[],[0]]`\n\n### Constraints:\n\n- `1 <= nums.length <= 10`\n- `-10 <= nums[i] <= 10`\n- All the numbers of `nums` are unique.\n\n## Solution\n\n```py\nclass Solution:\n def subsets(self, nums: list[int]) -> list[list[int]]:\n res = []\n\n def backtrack(i, path):\n res.append(path[:])\n for num_idx in range(i, len(nums)):\n path.append(nums[num_idx])\n backtrack(num_idx + 1, path)\n path.pop()\n\n backtrack(0, [])\n return res\n```\n"},"/binary-search":{"mdx":"---\ntitle: Binary Search\ndescription: 'Half of a sorted range is removed at each step until the target is found.'\nhidden: true\n---\n\nBinary search is an efficient array search algorithm. It works by narrowing down the search range by half each time. If you have looked up a word in a physical dictionary, you've already used binary search in real life. Let's look at a simple example:\n\n*Given a sorted array of integers and an integer called target, find the element that equals the target and return its index. If the element is not found, return -1.*\n\nThe key observation here is that the array is sorted. We pick a random element in the array and compare it to the target.\n\n- If we happen to pick the element that equals the target (how lucky!), then bingo. We don't need to do any more work; we return its index.\n- If the element is smaller than the target, then we know the target cannot be found in the section to the left of the current element, since everything to the left is even smaller. So, we discard the current element and everything on the left from the search range.\n- If the element is larger than the target, then we know the target cannot be found in the section to the right of the current element, since everything to the right is even larger. So, we discard the current element and everything on the right from the search range.\n\nWe repeat this process until we find the target. Instead of picking a random element, we always pick the **middle** element in the current search range. This way, we can discard half of the options and shrink the search range by half each time. This gives us `O(log(N))` runtime.\n\nThis idea can be implemented both iteratively and recursively. However, the major difference is that the iterative version of binary search uses `O(1)` memory while the recursive version uses `O(log(N))` memory.\n\n## Implementation\n\nThe search range is represented by the `left` and `right` indices that start from both ends of the array and move towards each other as we search. When moving the index, we discard elements and shrink the search range.\n\nTime Complexity: `O(log(n))`\n\n\n\n\n\n\n\n\n\n\n\n\n\n```python\ndef binary_search(arr: list[int], target: int) -> int:\n left, right = 0, len(arr) - 1\n # <= because left and right could point to the same element, < would miss it\n while left <= right:\n # double slash for integer division in python 3,\n # we don't have to worry about integer `left + right` overflow\n # since python integers can be arbitrarily large\n mid = (left + right) // 2\n # found target, return its index\n if arr[mid] == target:\n return mid\n # middle less than target, discard left half by making left search boundary `mid + 1`\n if arr[mid] < target:\n left = mid + 1\n # middle greater than target, discard right half by making right search boundary `mid - 1`\n else:\n right = mid - 1\n return -1 # if we get here we didn't hit above return so we didn't find target\n```\n\n### Calculating `mid`\n\nNote that when calculating `mid`, if the number of elements is even, there are two elements in the middle. We usually follow the convention of picking the first one, equivalent to doing integer division `(left + right) / 2`.\n\nIn most programming languages, we calculate `mid` with `left + floor((right-left) / 2)` to avoid potential integer overflow. However, in Python, we do not need to worry about integer overflow with `left + right` because Python3 integers can be arbitrarily large.\n\n## Deduction\n\nIt's essential to understand and deduce the algorithm yourself instead of memorizing it. In an actual interview, interviewers may ask you additional questions to test your understanding, so simply memorizing the algorithm may not be enough to convince the interviewer.\n\nKey elements in writing a correct binary search:\n\n### 1. When to terminate the loop\n\nMake sure the `while` loop includes an equality comparison; otherwise, we might skip the loop and miss the potential match for the edge case of a one-element array.\n\n### 2. Whether/how to update `left` and `right` boundary in the `if` conditions\n\nConsider which side to discard. If `arr[mid]` is smaller than the `target`, we should discard everything on the left by making `left = mid + 1`.\n\n### 3. Should I discard the current element?\n\nFor vanilla binary search, we can discard it since it cannot be the final answer if it is not equal to the target. There might be situations where you would want to think twice before discarding the current element. We'll discuss this in the next module.\n\n## When to use binary search\n\nInterestingly, binary search works beyond sorted arrays. **You can use binary search whenever you make a binary decision to shrink the search range.**\n"},"/binary-search-tree":{"mdx":"---\ntitle: Binary Search Tree\ndescription: 'Each node holds a value that is larger than its left subtree and smaller than its right subtree.'\nhidden: true\n---\n"},"/binary-search-tree/kth-smallest-element-in-a-bst":{"mdx":"---\ntitle: '230. Kth Smallest Element in a BST'\ndescription: Given the root of a binary search tree, and an integer k, return the k^th smallest value (1-indexed) of all the values of the nodes in the tree\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Binary Search Tree\", slug: \"binary-search-tree\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"5LUXSvjmGCw\"\nissue: \"https://github.com/prdlk/leetcode/issues/112\"\ncompanies:\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 74.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 71.5 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\nsidebar:\n label: 'Kth Smallest Element in a BST'\n badge: 'Medium'\n---\n\n::::warning\nIf the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?\n::::\n\n### Example 1:\n- Input: `root = [3,1,4,null,2], k = 1`\n- Output: `1`\n\n### Example 2:\n- Input: `root = [5,3,6,2,4,null,null,1], k = 3`\n- Output: `3`\n\n### Constraints:\n\n- The number of nodes in the tree is n.\n- `1 <= k <= n <= 10^4`\n- `0 <= Node.val <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"kthSmallest(root, k)\"]) --> I[\"n = 0, stack = [], cur = root\"]\n I --> W{\"cur or stack?\"}\n W -- no --> E([\"fall off the loop — unreachable, k <= n\"])\n W -- yes --> L{\"cur?\"}\n L -- yes --> P[\"stack.append(cur), cur = cur.left — push the whole left spine\"]\n P --> L\n L -- no --> O[\"cur = stack.pop(), n += 1 — nodes pop in ascending order\"]\n O --> K{\"n == k?\"}\n K -- yes --> R([\"return cur.val\"])\n K -- no --> N[\"cur = cur.right\"]\n N --> W\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nclass Solution:\n def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:\n n = 0\n stack = []\n cur = root\n\n while cur or stack:\n while cur:\n stack.append(cur)\n cur = cur.left\n\n cur = stack.pop()\n n += 1\n if n == k:\n return cur.val\n cur = cur.right\n```\n"},"/binary-search-tree/lowest-common-ancestor-of-a-binary-search-tree":{"mdx":"---\ntitle: '235. Lowest Common Ancestor of a Binary Search Tree'\ndescription: Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Binary Search Tree\", slug: \"binary-search-tree\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\n - { name: \"Binary Lifting\", slug: \"binary-lifting\" }\n - { name: \"Lowest Common Ancestor\", slug: \"lowest-common-ancestor\" }\nvideo: \"gs2LMfuOR9k\"\nissue: \"https://github.com/prdlk/leetcode/issues/113\"\ncompanies:\n - { name: \"BlackRock\", period: \"Thirty Days\", frequency: 76.6 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 30.1 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\n - { name: \"Google\", period: \"Six Months\", frequency: 21.9 }\nsidebar:\n label: 'Lowest Common Ancestor of a Binary Search Tree'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8`\n- Output: `6`\n- Explanation: The LCA of nodes `2` and `8` is `6`.\n\n### Example 2:\n- Input: `root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4`\n- Output: `2`\n- Explanation: The LCA of nodes `2` and `4` is `2`, since a node can be a descendant of itself according to the LCA definition.\n\n### Example 3:\n- Input: `root = [2,1], p = 2, q = 1`\n- Output: `2`\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [2, 10^5].\n- `-10^9 <= Node.val <= 10^9`\n- All Node.val are unique.\n- `p != q`\n- p and q will exist in the BST.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"lowestCommonAncestor(root, p, q)\"]) --> I[\"cur = root\"]\n I --> W{\"cur?\"}\n W -- no --> E([\"fall off the loop — unreachable, p and q exist in the BST\"])\n W -- yes --> A{\"p.val < cur.val and q.val < cur.val?\"}\n A -- yes --> L[\"cur = cur.left — both sit in the left subtree\"]\n L --> W\n A -- no --> B{\"p.val > cur.val and q.val > cur.val?\"}\n B -- yes --> R[\"cur = cur.right — both sit in the right subtree\"]\n R --> W\n B -- no --> C([\"return cur — the paths to p and q split here\"])\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, x):\n# self.val = x\n# self.left = None\n# self.right = None\n\n\nclass Solution:\n def lowestCommonAncestor(\n self, root: \"TreeNode\", p: \"TreeNode\", q: \"TreeNode\"\n ) -> \"TreeNode\":\n cur = root\n while cur:\n if p.val < cur.val and q.val < cur.val:\n cur = cur.left\n elif p.val > cur.val and q.val > cur.val:\n cur = cur.right\n else:\n return cur\n```\n"},"/binary-search-tree/validate-binary-search-tree":{"mdx":"---\ntitle: '98. Validate Binary Search Tree'\ndescription: Given the root of a binary tree, determine if it is a valid binary search tree (BST)\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Binary Search Tree\", slug: \"binary-search-tree\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"s6ATEkipzow\"\nissue: \"https://github.com/prdlk/leetcode/issues/111\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 76.7 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\nsidebar:\n label: 'Validate Binary Search Tree'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `root = [2,1,3]`\n- Output: `true`\n\n### Example 2:\n- Input: `root = [5,1,4,null,null,3,6]`\n- Output: `false`\n- Explanation: The `root` node's value is `5` but its right child's value is `4`.\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [1, 10^4].\n- `-2^31 <= Node.val <= 2^31 - 1`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"isValidBST(root)\"]) --> C[\"valid(root, float('-inf'), float('inf')) — the root may hold any value\"]\n C --> E([\"return that result\"])\n subgraph valid[\"valid(node, low, high)\"]\n V1{\"not node?\"}\n V1 -- yes --> V2([\"return True\"])\n V1 -- no --> V3{\"not (low < node.val < high)?\"}\n V3 -- yes --> V4([\"return False — node breaks a bound set by an ancestor\"])\n V3 -- no --> V5[\"valid(node.left, low, node.val) and valid(node.right, node.val, high) — each child tightens one bound\"]\n V5 --> V6([\"return that result\"])\n end\n C --> V1\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nclass Solution:\n def isValidBST(self, root: Optional[TreeNode]) -> bool:\n def valid(node, low, high):\n if not node:\n return True\n\n if not (low < node.val < high):\n return False\n\n return valid(node.left, low, node.val) and valid(node.right, node.val, high)\n\n return valid(root, float(\"-inf\"), float(\"inf\"))\n```\n"},"/binary-search/binary-search":{"mdx":"---\ntitle: '704. Binary Search'\ndescription: Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nvideo: \"s4DPM8ct1pI\"\nissue: \"https://github.com/prdlk/leetcode/issues/58\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 53.2 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 49.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 39.1 }\nsidebar:\n label: 'Binary Search'\n badge: 'Easy'\n---\n\n::::warning\nYou must write an algorithm with O(log n) runtime complexity.\n::::\n\n### Example 1:\n- Input: `nums = [-1,0,3,5,9,12], target = 9`\n- Output: `4`\n- Explanation: `9` exists in `nums` and its index is `4`\n\n### Example 2:\n- Input: `nums = [-1,0,3,5,9,12], target = 2`\n- Output: `-1`\n- Explanation: `2` does not exist in `nums` so return `-1`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^4`\n- `-10^4 < nums[i], target < 10^4`\n- All the integers in `nums` are unique.\n- `nums` is sorted in ascending order.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"search(nums, target)\"]) --> I[\"left = 0, right = n - 1\"]\n I --> W{\"left <= right?\"}\n W -- no --> E([\"return -1\"])\n W -- yes --> M[\"mid = left + floor((right - left) / 2)\"]\n M --> Q{\"nums[mid] vs target\"}\n Q -- equal --> R([\"return mid\"])\n Q -- \"nums[mid] < target\" --> L[\"left = mid + 1\"]\n L --> W\n Q -- \"nums[mid] > target\" --> H[\"right = mid - 1\"]\n H --> W\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n * @param {number} target\n * @return {number}\n */\nvar search = function(nums, target) {\n let left = 0;\n let right = nums.length - 1;\n\n while(left <= right) {\n const mid = left + Math.floor((right - left) / 2);\n if (nums[mid] === target) {\n return mid;\n } else if(nums[mid] < target){\n left = mid + 1;\n } else if (nums[mid] > target) {\n right = mid - 1;\n }\n }\n return -1;\n};\n```\n"},"/binary-search/find-first-and-last-position-of-element-in-sorted-array":{"mdx":"---\ntitle: '34. Find First and Last Position of Element in Sorted Array'\ndescription: Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nissue: \"https://github.com/prdlk/leetcode/issues/65\"\ncompanies:\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"TikTok\", period: \"Three Months\", frequency: 70.9 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Instacart\", period: \"Six Months\", frequency: 100 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 70.2 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 56.2 }\nsidebar:\n label: 'Find First and Last Position of Element in Sorted Array'\n badge: 'Medium'\n---\n\n::::warning\nYou must write an algorithm with O(log n) runtime complexity.\n::::\n\n### Example 1:\n- Input: `nums = [5,7,7,8,8,10], target = 8`\n- Output: `[3,4]`\n\n### Example 2:\n- Input: `nums = [5,7,7,8,8,10], target = 6`\n- Output: `[-1,-1]`\n\n### Example 3:\n- Input: `nums = [], target = 0`\n- Output: `[-1,-1]`\n\n### Constraints:\n\n- `0 <= nums.length <= 10^5`\n- `-10^9 <= nums[i] <= 10^9`\n- `nums` is a non-decreasing array.\n- `-10^9 <= target <= 10^9`\n\n## Solution\n\n```py\nclass Solution:\n def searchRange(self, nums: list[int], target: int) -> list[int]:\n def find(first):\n result = -1\n left, right = 0, len(nums) - 1\n while left <= right:\n mid = (left + right) // 2\n if nums[mid] == target:\n result = mid\n if first:\n right = mid - 1\n else:\n left = mid + 1\n elif nums[mid] < target:\n left = mid + 1\n else:\n right = mid - 1\n return result\n\n return [find(True), find(False)]\n```\n"},"/binary-search/find-minimum-in-rotated-sorted-array":{"mdx":"---\ntitle: '153. Find Minimum in Rotated Sorted Array'\ndescription: 'Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:'\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nvideo: \"nIVW4P8b1VA\"\nissue: \"https://github.com/prdlk/leetcode/issues/62\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 40.6 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Find Minimum in Rotated Sorted Array'\n badge: 'Medium'\n---\n\n::::warning\nNotice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]].\n::::\n\n### Example 1:\n- Input: `nums = [3,4,5,1,2]`\n- Output: `1`\n- Explanation: The original array was `[1,2,3,4,5]` rotated `3` times.\n\n### Example 2:\n- Input: `nums = [4,5,6,7,0,1,2]`\n- Output: `0`\n- Explanation: The original array was `[0,1,2,4,5,6,7]` and it was rotated `4` times.\n\n### Example 3:\n- Input: `nums = [11,13,15,17]`\n- Output: `11`\n- Explanation: The original array was `[11,13,15,17]` and it was rotated `4` times.\n\n### Constraints:\n\n- `n == nums.length`\n- `1 <= n <= 5000`\n- `-5000 <= nums[i] <= 5000`\n- All the integers of `nums` are unique.\n- `nums` is sorted and rotated between 1 and `n` times.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"findMin(nums)\"]) --> I[\"l = 0, r = n-1, lowest_index = -1\"]\n I --> W{\"l <= r?\"}\n W -- no --> E([\"return nums[lowest_index]\"])\n W -- yes --> M[\"m = (l + r) // 2\"]\n M --> C{\"nums[m] <= nums[-1]?\"}\n C -- yes --> A[\"in the right sorted run: record lowest_index = m, r = m - 1\"]\n A --> W\n C -- no --> B[\"still in the left sorted run: l = m + 1\"]\n B --> W\n```\n\n## Solution\n\n```py\nclass Solution:\n def findMin(self, nums: List[int]) -> int:\n l, r = 0, len(nums) - 1\n lowest_index = -1\n\n while l <= r:\n m = (l + r) // 2\n if nums[m] <= nums[-1]:\n lowest_index = m\n r = m - 1\n else:\n l = m + 1\n\n return nums[lowest_index]\n```\n"},"/binary-search/find-peak-element":{"mdx":"---\ntitle: '162. Find Peak Element'\ndescription: A peak element is an element that is strictly greater than its neighbors\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nissue: \"https://github.com/prdlk/leetcode/issues/64\"\ncompanies:\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 68.6 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 67.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 54.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 67.2 }\nsidebar:\n label: 'Find Peak Element'\n badge: 'Medium'\n---\n\n::::warning\nYou must write an algorithm that runs in O(log n) time.\n::::\n\n### Example 1:\n- Input: `nums = [1,2,3,1]`\n- Output: `2`\n- Explanation: `3` is a peak element and your function should return the index number `2`.\n\n### Example 2:\n- Input: `nums = [1,2,1,3,5,6,4]`\n- Output: `5`\n- Explanation: Your function can return either index number `1` where the peak element is `2`, or index number `5` where the peak element is `6`.\n\n### Constraints:\n\n- `1 <= nums.length <= 1000`\n- `-2^31 <= nums[i] <= 2^31 - 1`\n- `nums[i] != nums[i + 1] for all valid i.`\n\n## Solution\n\n```py\nclass Solution:\n def findPeakElement(self, nums: list[int]) -> int:\n left, right = 0, len(nums) - 1\n while left < right:\n mid = (left + right) // 2\n if nums[mid] < nums[mid + 1]:\n left = mid + 1\n else:\n right = mid\n\n return left\n```\n"},"/binary-search/koko-eating-bananas":{"mdx":"---\ntitle: '875. Koko Eating Bananas'\ndescription: Koko loves to eat bananas. There are n piles of bananas, the i^th pile has piles[i] bananas. The guards have gone and will come back in h hours\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nvideo: \"U2SozAs9RzA\"\nissue: \"https://github.com/prdlk/leetcode/issues/59\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Nvidia\", period: \"Three Months\", frequency: 100 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 87.4 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 62.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Coupang\", period: \"Six Months\", frequency: 100 }\n - { name: \"Swiggy\", period: \"Six Months\", frequency: 100 }\n - { name: \"Accenture\", period: \"Six Months\", frequency: 75 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 56.9 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\nsidebar:\n label: 'Koko Eating Bananas'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `piles = [3,6,7,11], h = 8`\n- Output: `4`\n\n### Example 2:\n- Input: `piles = [30,11,23,4,20], h = 5`\n- Output: `30`\n\n### Example 3:\n- Input: `piles = [30,11,23,4,20], h = 6`\n- Output: `23`\n\n### Constraints:\n\n- `1 <= piles.length <= 10^4`\n- `piles.length <= h <= 10^9`\n- `1 <= piles[i] <= 10^9`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"minEatingSpeed(piles, h)\"]) --> I[\"l = 1, r = max(piles)\"]\n I --> W{\"l < r?\"}\n W -- no --> E([\"return l — the smallest workable speed\"])\n W -- yes --> M[\"mid = floor((l + r) / 2)\"]\n M --> K[\"kWorks(mid): hours = sum of ceil(p / mid)\"]\n K --> Q{\"hours <= h?\"}\n Q -- yes --> A[\"r = mid — keep mid, try slower\"]\n Q -- no --> B[\"l = mid + 1 — too slow, speed up\"]\n A --> W\n B --> W\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} piles\n * @param {number} h\n * @return {number}\n */\nvar minEatingSpeed = function(piles, h) {\n // Function to determine if K works for the H\n function kWorks(k){\n let hours = 0;\n for (let p of piles){\n hours += Math.ceil(p/k)\n }\n return hours <= h;\n }\n\n // Setup Binary Search\n let l = 1;\n let r = Math.max(...piles);\n\n // Find the K value which works for H and consumes all bananas\n while (l < r){\n const mid = Math.floor((l + r) / 2);\n if (kWorks(mid)){\n r = mid;\n }else{\n l = mid + 1;\n }\n }\n return l;\n};\n```\n"},"/binary-search/median-of-two-sorted-arrays":{"mdx":"---\ntitle: '4. Median of Two Sorted Arrays'\ndescription: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\n - { name: \"Divide and Conquer\", slug: \"divide-and-conquer\" }\nissue: \"https://github.com/prdlk/leetcode/issues/66\"\ncompanies:\n - { name: \"Rippling\", period: \"Thirty Days\", frequency: 93 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 63.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 62 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"eBay\", period: \"Three Months\", frequency: 82.2 }\n - { name: \"Goldman Sachs\", period: \"Three Months\", frequency: 57 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Zoho\", period: \"Six Months\", frequency: 79.6 }\n - { name: \"DE Shaw\", period: \"Six Months\", frequency: 74.2 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 48.1 }\nsidebar:\n label: 'Median of Two Sorted Arrays'\n badge: 'Hard'\n---\n\n### Example 1:\n- Input: `nums1 = [1,3], nums2 = [2]`\n- Output: `2.00000`\n- Explanation: merged array = `[1,2,3]` and median is `2`.\n\n### Example 2:\n- Input: `nums1 = [1,2], nums2 = [3,4]`\n- Output: `2.50000`\n- Explanation: merged array = `[1,2,3,4]` and median is `(2 + 3`) / `2 = 2.5`.\n\n### Constraints:\n\n- `nums1.length == m`\n- `nums2.length == n`\n- `0 <= m <= 1000`\n- `0 <= n <= 1000`\n- `1 <= m + n <= 2000`\n- `-10^6 <= nums1[i], nums2[i] <= 10^6`\n\n## Solution\n\n```py\nclass Solution:\n def findMedianSortedArrays(self, nums1: list[int], nums2: list[int]) -> float:\n if len(nums1) > len(nums2):\n return self.findMedianSortedArrays(nums2, nums1)\n\n m, n = len(nums1), len(nums2)\n left, right = 0, m\n\n while left <= right:\n partA = (left + right) // 2\n partB = (m + n + 1) // 2 - partA\n\n maxLeftA = float(\"-inf\") if partA == 0 else nums1[partA - 1]\n minRightA = float(\"inf\") if partA == m else nums1[partA]\n maxLeftB = float(\"-inf\") if partB == 0 else nums2[partB - 1]\n minRightB = float(\"inf\") if partB == n else nums2[partB]\n\n if maxLeftA <= minRightB and maxLeftB <= minRightA:\n if (m + n) % 2 == 0:\n return (max(maxLeftA, maxLeftB) + min(minRightA, minRightB)) / 2\n else:\n return max(maxLeftA, maxLeftB)\n elif maxLeftA > minRightB:\n right = partA - 1\n else:\n left = partA + 1\n```\n"},"/binary-search/search-a-2d-matrix":{"mdx":"---\ntitle: '74. Search a 2D Matrix'\ndescription: 'You are given an m x n integer matrix matrix with the following two properties:'\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nvideo: \"Ber2pi2C0j0\"\nissue: \"https://github.com/prdlk/leetcode/issues/61\"\ncompanies:\n - { name: \"Goldman Sachs\", period: \"Thirty Days\", frequency: 62.9 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"SAP\", period: \"Six Months\", frequency: 100 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Search a 2D Matrix'\n badge: 'Medium'\n---\n\n::::warning\nYou must write a solution in O(log(m * n)) time complexity.\n::::\n\n### Example 1:\n- Input: `matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3`\n- Output: `true`\n\n### Example 2:\n- Input: `matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13`\n- Output: `false`\n\n### Constraints:\n\n- `m == matrix.length`\n- `n == matrix[i].length`\n- `1 <= m, n <= 100`\n- `-10^4 <= matrix[i][j], target <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"searchMatrix(matrix, target)\"]) --> I[\"top = 0, bot = ROWS - 1\"]\n I --> W1{\"top <= bot?\"}\n W1 -- yes --> R1[\"row = (top + bot) // 2\"]\n R1 --> C1{\"target vs that row's range\"}\n C1 -- \"above matrix[row][-1]\" --> U[\"top = row + 1\"]\n C1 -- \"below matrix[row][0]\" --> V[\"bot = row - 1\"]\n C1 -- inside --> B([\"break — row found\"])\n U --> W1\n V --> W1\n W1 -- no --> F([\"return False — no row can hold it\"])\n B --> P[\"row = (top + bot) // 2; l = 0, r = COLS - 1\"]\n P --> W2{\"l <= r?\"}\n W2 -- no --> G([\"return False\"])\n W2 -- yes --> M[\"m = (l + r) // 2\"]\n M --> C2{\"target vs matrix[row][m]\"}\n C2 -- greater --> X[\"l = m + 1\"]\n C2 -- smaller --> Y[\"r = m - 1\"]\n C2 -- equal --> T([\"return True\"])\n X --> W2\n Y --> W2\n```\n\n## Solution\n\n```py\nclass Solution:\n def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n ROWS, COLS = len(matrix), len(matrix[0])\n\n top, bot = 0, ROWS - 1\n while top <= bot:\n row = (top + bot) // 2\n if target > matrix[row][-1]:\n top = row + 1\n elif target < matrix[row][0]:\n bot = row - 1\n else:\n break\n\n if not (top <= bot):\n return False\n\n row = (top + bot) // 2\n l, r = 0, COLS - 1\n while l <= r:\n m = (l + r) // 2\n if target > matrix[row][m]:\n l = m + 1\n elif target < matrix[row][m]:\n r = m - 1\n else:\n return True\n return False\n```\n"},"/binary-search/search-in-rotated-sorted-array":{"mdx":"---\ntitle: '33. Search in Rotated Sorted Array'\ndescription: There is an integer array nums sorted in ascending order (with distinct values)\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nvideo: \"U8XENwh8Oy8\"\nissue: \"https://github.com/prdlk/leetcode/issues/60\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"Oracle\", period: \"Three Months\", frequency: 100 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 68.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 64.9 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 63.3 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 59.6 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 53.1 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 48.1 }\nsidebar:\n label: 'Search in Rotated Sorted Array'\n badge: 'Medium'\n---\n\n::::warning\nYou must write an algorithm with O(log n) runtime complexity.\n::::\n\n### Example 1:\n- Input: `nums = [4,5,6,7,0,1,2], target = 0`\n- Output: `4`\n\n### Example 2:\n- Input: `nums = [4,5,6,7,0,1,2], target = 3`\n- Output: `-1`\n\n### Example 3:\n- Input: `nums = [1], target = 0`\n- Output: `-1`\n\n### Constraints:\n\n- `1 <= nums.length <= 5000`\n- `-10^4 <= nums[i] <= 10^4`\n- All values of `nums` are unique.\n- `nums` is an ascending array that is possibly rotated.\n- `-10^4 <= target <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"search(nums, target)\"]) --> I[\"l = 0, r = n - 1\"]\n I --> W{\"l <= r?\"}\n W -- no --> E([\"return -1\"])\n W -- yes --> M[\"mid = floor((l + r) / 2)\"]\n M --> F{\"nums[mid] == target?\"}\n F -- yes --> R([\"return mid\"])\n F -- no --> H{\"nums[l] <= nums[mid]? — left half sorted\"}\n H -- yes --> A{\"target outside [nums[l], nums[mid]]?\"}\n A -- yes --> A1[\"l = mid + 1 — search the right half\"]\n A -- no --> A2[\"r = mid - 1\"]\n H -- no --> B{\"target outside [nums[mid], nums[r]]?\"}\n B -- yes --> B1[\"r = mid - 1 — search the left half\"]\n B -- no --> B2[\"l = mid + 1\"]\n A1 --> W\n A2 --> W\n B1 --> W\n B2 --> W\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n * @param {number} target\n * @return {number}\n */\nvar search = function(nums, target) {\n let l = 0, r = nums.length - 1; \n\n while (l <= r){\n let mid = Math.floor((l + r)/2);\n if (target === nums[mid]) {\n return mid\n }\n\n // Left sorted portion\n if (nums[l] <= nums[mid]){\n if (target > nums[mid] || target < nums[l]){\n l = mid + 1;\n }else{\n r = mid - 1;\n }\n }\n // Right sorted portion\n else{\n if(target < nums[mid] || target > nums[r]){\n r = mid - 1; \n }else{\n l = mid + 1;\n }\n }\n }\n return -1;\n};\n```\n"},"/binary-search/search-insert-position":{"mdx":"---\ntitle: '35. Search Insert Position'\ndescription: Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nvideo: \"K-RYzDZkzCI\"\nissue: \"https://github.com/prdlk/leetcode/issues/63\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Grammarly\", period: \"Three Months\", frequency: 84.8 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 49.8 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 56.2 }\nsidebar:\n label: 'Search Insert Position'\n badge: 'Easy'\n---\n\n::::warning\nYou must write an algorithm with O(log n) runtime complexity.\n::::\n\n### Example 1:\n- Input: `nums = [1,3,5,6], target = 5`\n- Output: `2`\n\n### Example 2:\n- Input: `nums = [1,3,5,6], target = 2`\n- Output: `1`\n\n### Example 3:\n- Input: `nums = [1,3,5,6], target = 7`\n- Output: `4`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^4`\n- `-10^4 <= nums[i] <= 10^4`\n- `nums` contains distinct values sorted in ascending order.\n- `-10^4 <= target <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"searchInsert(nums, target)\"]) --> I[\"l = 0, r = n - 1\"]\n I --> W{\"l <= r?\"}\n W -- yes --> M[\"m = (l + r) // 2\"]\n M --> Q{\"nums[m] vs target\"}\n Q -- equal --> R([\"return m\"])\n Q -- \"nums[m] < target\" --> L[\"l = m + 1\"]\n L --> W\n Q -- \"nums[m] > target\" --> H[\"r = m - 1\"]\n H --> W\n W -- no --> E([\"return (l + r) // 2 + 1 — the insert slot\"])\n```\n\n## Solution\n\n```py\nclass Solution:\n def searchInsert(self, nums: List[int], target: int) -> int:\n l, r = 0, len(nums) - 1\n\n while l <= r:\n m = (l + r) // 2\n if nums[m] == target:\n return m\n elif nums[m] < target:\n l = m + 1\n elif nums[m] > target:\n r = m - 1\n\n return (l + r) // 2 + 1\n```\n"},"/graph-bfs":{"mdx":"---\ntitle: Graph BFS\ndescription: 'Nodes are visited in order of distance from the start, which gives the shortest path in an unweighted graph.'\nhidden: true\n---\n"},"/graph-bfs/rotting-oranges":{"mdx":"---\ntitle: '994. Rotting Oranges'\ndescription: 'You are given an m x n grid where each cell can have one of three values:'\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nissue: \"https://github.com/prdlk/leetcode/issues/137\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 75.8 }\n - { name: \"OpenAI\", period: \"Thirty Days\", frequency: 69.7 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Anduril\", period: \"Three Months\", frequency: 94.2 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Cognizant\", period: \"Six Months\", frequency: 76.3 }\n - { name: \"Lyft\", period: \"Six Months\", frequency: 72.2 }\n - { name: \"Flipkart\", period: \"Six Months\", frequency: 57.1 }\n - { name: \"Pinterest\", period: \"Six Months\", frequency: 55.8 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\n - { name: \"Salesforce\", period: \"Six Months\", frequency: 50.2 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 45.7 }\nsidebar:\n label: 'Rotting Oranges'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `grid = [[2,1,1],[1,1,0],[0,1,1]]`\n- Output: `4`\n\n### Example 2:\n- Input: `grid = [[2,1,1],[0,1,1],[1,0,1]]`\n- Output: `-1`\n- Explanation: The orange in the bottom left corner (row `2`, column `0`) is never rotten, because rotting only happens 4-directionally.\n\n### Example 3:\n- Input: `grid = [[0,2]]`\n- Output: `0`\n- Explanation: Since there are already no fresh oranges at minute `0`, the answer is just `0`.\n\n### Constraints:\n\n- `m == grid.length`\n- `n == grid[i].length`\n- `1 <= m, n <= 10`\n- grid[i][j] is 0, 1, or 2.\n\n## Solution\n\n```py\nfrom collections import deque\n\n\nclass Solution:\n def orangesRotting(self, grid: list[list[int]]) -> int:\n q = deque()\n time, fresh = 0, 0\n\n rows, cols = len(grid), len(grid[0])\n for r in range(rows):\n for c in range(cols):\n if grid[r][c] == 1:\n fresh += 1\n if grid[r][c] == 2:\n q.append([r, c])\n\n directions = [[0, 1], [0, -1], [1, 0], [-1, 0]]\n\n while q and fresh > 0:\n for i in range(len(q)):\n r, c = q.popleft()\n for dr, dc in directions:\n row, col = dr + r, dc + c\n # check if in bounds\n if (\n row < 0\n or col < 0\n or row == len(grid)\n or col == len(grid[0])\n or grid[row][col] != 1\n ):\n continue\n grid[row][col] = 2\n q.append([row, col])\n fresh -= 1\n time += 1\n return time if fresh == 0 else -1\n```\n"},"/graph-bfs/word-ladder":{"mdx":"---\ntitle: '127. Word Ladder'\ndescription: 'A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:'\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Bidirectional Search\", slug: \"bidirectional-search\" }\nissue: \"https://github.com/prdlk/leetcode/issues/138\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 55.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 69 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Citadel\", period: \"Six Months\", frequency: 88 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 69.8 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Word Ladder'\n badge: 'Hard'\n---\n\n### Example 1:\n- Input: `beginWord = \"hit\", endWord = \"cog\", wordList = [\"hot\",\"dot\",\"dog\",\"lot\",\"log\",\"cog\"]`\n- Output: `5`\n- Explanation: One shortest transformation sequence is \"hit\" -> \"hot\" -> \"dot\" -> \"dog\" -> cog\", which is `5` words long.\n\n### Example 2:\n- Input: `beginWord = \"hit\", endWord = \"cog\", wordList = [\"hot\",\"dot\",\"dog\",\"lot\",\"log\"]`\n- Output: `0`\n- Explanation: The `endWord` \"cog\" is not in `wordList`, therefore there is no valid transformation sequence.\n\n### Constraints:\n\n- `1 <= beginWord.length <= 10`\n- `endWord.length == beginWord.length`\n- `1 <= wordList.length <= 5000`\n- `wordList[i].length == beginWord.length`\n- `beginWord`, `endWord`, and `wordList[i]` consist of lowercase English letters.\n- `beginWord != endWord`\n- All the words in `wordList` are unique.\n\n## Solution\n\n```py\nimport collections\n\n\nclass Solution:\n def ladderLength(self, beginWord: str, endWord: str, wordList: list[str]) -> int:\n if endWord not in wordList:\n return 0\n\n adj = collections.defaultdict(list)\n wordList.append(beginWord)\n\n for word in wordList:\n for j in range(len(word)):\n pattern = word[:j] + \"*\" + word[j + 1 :]\n adj[pattern].append(word)\n\n visit = set([beginWord])\n q = collections.deque([beginWord])\n res = 1\n\n while q:\n for i in range(len(q)):\n word = q.popleft()\n if word == endWord:\n return res\n for j in range(len(word)):\n pattern = word[:j] + \"*\" + word[j + 1 :]\n for adjWord in adj[pattern]:\n if adjWord not in visit:\n visit.add(adjWord)\n q.append(adjWord)\n res += 1\n return 0\n```\n"},"/graph-dfs":{"mdx":"---\ntitle: Graph DFS\ndescription: 'Each edge is followed to its end, and a visited set prevents a repeat visit.'\nhidden: true\n---\n"},"/graph-dfs/clone-graph":{"mdx":"---\ntitle: '133. Clone Graph'\ndescription: Given a reference of a node in a connected undirected graph\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Graph Theory\", slug: \"graph\" }\nissue: \"https://github.com/prdlk/leetcode/issues/131\"\ncompanies:\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\nsidebar:\n label: 'Clone Graph'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `adjList = [[2,4],[1,3],[2,4],[1,3]]`\n- Output: `[[2,4],[1,3],[2,4],[1,3]]`\n- Explanation: There are `4` nodes in the graph. 1st `node` (val = 1)'s neighbors are 2nd `node` (val = `2`) and 4th `node` (val = `4`). 2nd `node` (val = 2)'s neighbors are 1st `node` (val = `1`) and 3rd `node` (val = `3`). 3rd `node` (val = 3)'s neighbors are 2nd `node` (val = `2`) and 4th `node` (val = `4`). 4th `node` (val = 4)'s neighbors are 1st `node` (val = `1`) and 3rd `node` (val = `3`).\n\n### Example 2:\n- Input: `adjList = [[]]`\n- Output: `[[]]`\n- Explanation: Note that the input contains one empty list. The graph consists of only one `node` with val = `1` and it does not have any neighbors.\n\n### Example 3:\n- Input: `adjList = []`\n- Output: `[]`\n- Explanation: This an empty graph, it does not have any nodes.\n\n### Constraints:\n\n- The number of nodes in the graph is in the range [0, 100].\n- `1 <= Node.val <= 100`\n- Node.val is unique for each node.\n- There are no repeated edges and no self-loops in the graph.\n- The Graph is connected and all nodes can be visited starting from the given node.\n\n## Solution\n\n```py\n\"\"\"\n# Definition for a Node.\nclass Node:\n def __init__(self, val = 0, neighbors = None):\n self.val = val\n self.neighbors = neighbors if neighbors is not None else []\n\"\"\"\n\nfrom typing import Optional\n\n\nclass Solution:\n def cloneGraph(self, node: Optional[\"Node\"]) -> Optional[\"Node\"]:\n oldToNew = {}\n\n def dfs(node):\n if node in oldToNew:\n return oldToNew[node]\n\n copy = Node(node.val)\n oldToNew[node] = copy\n\n for n in node.neighbors:\n copy.neighbors.append(dfs(n))\n return copy\n\n return dfs(node) if node else None\n```\n"},"/graph-dfs/number-of-islands":{"mdx":"---\ntitle: '200. Number of Islands'\ndescription: Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Union-Find\", slug: \"union-find\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nissue: \"https://github.com/prdlk/leetcode/issues/130\"\ncompanies:\n - { name: \"Anduril\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Apple\", period: \"Thirty Days\", frequency: 81.7 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 65.8 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Qualcomm\", period: \"Three Months\", frequency: 100 }\n - { name: \"TikTok\", period: \"Three Months\", frequency: 89.3 }\n - { name: \"Uber\", period: \"Three Months\", frequency: 72.9 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Autodesk\", period: \"Six Months\", frequency: 100 }\n - { name: \"ByteDance\", period: \"Six Months\", frequency: 100 }\n - { name: \"Rivian\", period: \"Six Months\", frequency: 100 }\n - { name: \"Snap\", period: \"Six Months\", frequency: 100 }\n - { name: \"Waymo\", period: \"Six Months\", frequency: 100 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 95.1 }\n - { name: \"Visa\", period: \"Six Months\", frequency: 80.9 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 69.8 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 59.6 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 59 }\nsidebar:\n label: 'Number of Islands'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `grid = [ [\"1\",\"1\",\"1\",\"1\",\"0\"], [\"1\",\"1\",\"0\",\"1\",\"0\"], [\"1\",\"1\",\"0\",\"0\",\"0\"], [\"0\",\"0\",\"0\",\"0\",\"0\"] ]`\n- Output: `1`\n\n### Example 2:\n- Input: `grid = [ [\"1\",\"1\",\"0\",\"0\",\"0\"], [\"1\",\"1\",\"0\",\"0\",\"0\"], [\"0\",\"0\",\"1\",\"0\",\"0\"], [\"0\",\"0\",\"0\",\"1\",\"1\"] ]`\n- Output: `3`\n\n### Constraints:\n\n- `m == grid.length`\n- `n == grid[i].length`\n- `1 <= m, n <= 300`\n- grid[i][j] is '0' or '1'.\n\n## Solution\n\n```py\nclass Solution:\n def numIslands(self, grid: List[List[str]]) -> int:\n rows, cols = len(grid), len(grid[0])\n\n def dfs(r, c):\n if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] != \"1\":\n return\n else:\n grid[r][c] = \"0\"\n dfs(r, c + 1) # right\n dfs(r + 1, c) # bottom\n dfs(r, c - 1) # left\n dfs(r - 1, c) # top\n\n num_islands = 0\n for r in range(rows):\n for c in range(cols):\n if grid[r][c] == \"1\":\n num_islands += 1\n dfs(r, c)\n\n return num_islands\n```\n"},"/graph-dfs/pacific-atlantic-water-flow":{"mdx":"---\ntitle: '417. Pacific Atlantic Water Flow'\ndescription: There is an m x n rectangular island that borders both the Pacific Ocean and Atlantic Ocean. The Pacific Ocean touches the island's left and top edges, and the Atlantic Ocean touches the island's right and bottom edges\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nissue: \"https://github.com/prdlk/leetcode/issues/132\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Pacific Atlantic Water Flow'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]`\n- Output: `[[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]`\n- Explanation: The following cells can flow to the Pacific and Atlantic oceans, as shown below: `[0,4]`: `[0,4]` -> Pacific Ocean `[0,4]` -> Atlantic Ocean `[1,3]`: `[1,3]` -> `[0,3]` -> Pacific Ocean `[1,3]` -> `[1,4]` -> Atlantic Ocean `[1,4]`: `[1,4]` -> `[1,3]` -> `[0,3]` -> Pacific Ocean `[1,4]` -> Atlantic Ocean `[2,2]`: `[2,2]` -> `[1,2]` -> `[0,2]` -> Pacific Ocean `[2,2]` -> `[2,3]` -> `[2,4]` -> Atlantic Ocean `[3,0]`: `[3,0]` -> Pacific Ocean `[3,0]` -> `[4,0]` -> Atlantic Ocean `[3,1]`: `[3,1]` -> `[3,0]` -> Pacific Ocean `[3,1]` -> `[4,1]` -> Atlantic Ocean `[4,0]`: `[4,0]` -> Pacific Ocean `[4,0]` -> Atlantic Ocean Note that there are other possible paths for these cells to flow to the Pacific and Atlantic oceans.\n\n### Example 2:\n- Input: `heights = [[1]]`\n- Output: `[[0,0]]`\n- Explanation: The water can flow from the only cell to the Pacific and Atlantic oceans.\n\n### Constraints:\n\n- `m == heights.length`\n- `n == heights[r].length`\n- `1 <= m, n <= 200`\n- `0 <= heights[r][c] <= 10^5`\n\n## Solution\n\n```py\nclass Solution:\n def pacificAtlantic(self, heights: list[list[int]]) -> list[list[int]]:\n rows, cols = len(heights), len(heights[0])\n pac, atl = set(), set()\n\n def dfs(r, c, seen, prevHeight):\n if (\n (r, c) in seen\n or r < 0\n or c < 0\n or r == rows\n or c == cols\n or heights[r][c] < prevHeight\n ):\n return\n seen.add((r, c))\n dfs(r + 1, c, seen, heights[r][c])\n dfs(r - 1, c, seen, heights[r][c])\n dfs(r, c + 1, seen, heights[r][c])\n dfs(r, c - 1, seen, heights[r][c])\n\n for c in range(cols):\n dfs(0, c, pac, heights[0][c])\n dfs(rows - 1, c, atl, heights[rows - 1][c])\n\n for r in range(rows):\n dfs(r, 0, pac, heights[r][0])\n dfs(r, cols - 1, atl, heights[r][cols - 1])\n\n res = []\n for r in range(rows):\n for c in range(cols):\n if (r, c) in pac and (r, c) in atl:\n res.append([r, c])\n\n return res\n```\n"},"/greedy":{"md":"---\ntitle: Greedy\ndescription: 'The best local choice is made at each step and is not changed later.'\nhidden: true\n---\n\n## When to use greedy algorithms?\n\n- Solving optimization problems.\n- Ask to optimize some value and calculate it.\n- keywords (min/max, longest/shortest, largest/smallest, etc.)\n\n## Optimization problems\n\n1. Return the minimum number of swaps required to make s1 equal to s2.\n2. Return the minimum number of steps to make s and t anagrams of each other.\n3. Given three integers a, b, and c, return the longest possible happy string, if there are multiple such strings return any of them. if there is no such string, return empty string.\n\n## What are greedy algorithms?\n\n- Greedy algorithms follow this format:\n- identify what choices you have at every step\n - find the best choice\n - just do what looks best until done\n- assume that the best choice is the one that will lead to the best outcome\n\n## How do we know greedy works?\n- Write out a formal proof\n - too complicated to write out\n - too much time\n- better to use intuition\n - try a bunch of ideas\n - find counterexamples\n\n## Steps to use greedy algorithms\n\n1. **Identify the different steps and choices**\n\n - Choices have to be comparable\n - must determine if a choice is better than another\n\n2. **Check if greedy works**\n\n - try finding small cases where greedy is not optimal\n - if cases pass, try to deduce why greedy is optimal\n\n## Why use greedy algorithms?\n\n- simple to code\n- doesn't use complex algorithms (BFS, DFS, etc.)\n- runtime is fast, usually 0(n) or O(nlogn)\n- however, greedy algorithms are not always optimal\n\n## The Greedy Skeleton\n\n### Type 1: Walk and Carry\n\n:::info\nNo sort. Walk the list once. Carry one number. At each step, decide: keep it, or drop it.\n:::\n\n```python\ndef walk_and_carry(nums):\n carry = start_value\n best = start_value\n for n in nums:\n if carry_is_useless(carry):\n carry = fresh_start\n carry = update(carry, n)\n best = max(best, carry)\n return best\n```\n\n### Type 2: Sort and Pick\n\n:::info\nUsed when order doesn't matter, so you pick the order. Meeting rooms, intervals, \"most tasks by a deadline.\"\n:::\n\n```python\ndef greedy(items):\n # 1. Sort by the greedy key (deadline, end time, size, ratio, ...)\n items.sort(key=greedy_key)\n result = 0\n state = initial_state()\n for item in items:\n # 2. Take the item only if the locally best choice is valid\n if is_feasible(item, state):\n result += take(item, state)\n # 3. Correctness relies on an exchange argument, not just passing tests\n return result\n```\n","mdx":"---\ntitle: Greedy\ndescription: 'The best local choice is made at each step and is not changed later.'\nhidden: true\n---\n\n## When to use greedy algorithms?\n\n- Solving optimization problems.\n- Ask to optimize some value and calculate it.\n- keywords (min/max, longest/shortest, largest/smallest, etc.)\n\n## Optimization problems\n\n1. Return the minimum number of swaps required to make s1 equal to s2.\n2. Return the minimum number of steps to make s and t anagrams of each other.\n3. Given three integers a, b, and c, return the longest possible happy string, if there are multiple such strings return any of them. if there is no such string, return empty string.\n\n## What are greedy algorithms?\n\n- Greedy algorithms follow this format:\n- identify what choices you have at every step\n - find the best choice\n - just do what looks best until done\n- assume that the best choice is the one that will lead to the best outcome\n\n## How do we know greedy works?\n- Write out a formal proof\n - too complicated to write out\n - too much time\n- better to use intuition\n - try a bunch of ideas\n - find counterexamples\n\n## Steps to use greedy algorithms\n\n\n \n - Choices have to be comparable\n - must determine if a choice is better than another\n \n \n - try finding small cases where greedy is not optimal\n - if cases pass, try to deduce why greedy is optimal\n \n\n\n## Why use greedy algorithms?\n\n- simple to code\n- doesn't use complex algorithms (BFS, DFS, etc.)\n- runtime is fast, usually 0(n) or O(nlogn)\n- however, greedy algorithms are not always optimal\n\n## The Greedy Skeleton\n\n### Type 1: Walk and Carry\n\n:::info\nNo sort. Walk the list once. Carry one number. At each step, decide: keep it, or drop it.\n:::\n\n```python\ndef walk_and_carry(nums):\n carry = start_value\n best = start_value\n for n in nums:\n if carry_is_useless(carry):\n carry = fresh_start\n carry = update(carry, n)\n best = max(best, carry)\n return best\n```\n\n### Type 2: Sort and Pick\n\n:::info\nUsed when order doesn't matter, so you pick the order. Meeting rooms, intervals, \"most tasks by a deadline.\"\n:::\n\n```python\ndef greedy(items):\n # 1. Sort by the greedy key (deadline, end time, size, ratio, ...)\n items.sort(key=greedy_key)\n result = 0\n state = initial_state()\n for item in items:\n # 2. Take the item only if the locally best choice is valid\n if is_feasible(item, state):\n result += take(item, state)\n # 3. Correctness relies on an exchange argument, not just passing tests\n return result\n```\n"},"/greedy/gas-station":{"mdx":"---\ntitle: '134. Gas Station'\ndescription: There are n gas stations along a circular route, where the amount of gas at the i^th station is gas[i]\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Greedy\", slug: \"greedy\" }\nissue: \"https://github.com/prdlk/leetcode/issues/176\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Sprinklr\", period: \"Three Months\", frequency: 95.9 }\n - { name: \"TikTok\", period: \"Three Months\", frequency: 70.9 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Adobe\", period: \"Six Months\", frequency: 74.3 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\n - { name: \"Google\", period: \"Six Months\", frequency: 17.4 }\nsidebar:\n label: 'Gas Station'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `gas = [1,2,3,4,5], cost = [3,4,5,1,2]`\n- Output: `3`\n- Explanation: Start at station `3` (index `3`) and fill up with `4` unit of `gas`. Your tank = `0 + 4 = 4` Travel to station `4`. Your tank = `4 - 1 + 5 = 8` Travel to station `0`. Your tank = `8 - 2 + 1 = 7` Travel to station `1`. Your tank = `7 - 3 + 2 = 6` Travel to station `2`. Your tank = `6 - 4 + 3 = 5` Travel to station `3`. The `cost` is `5`. Your `gas` is just enough to travel back to station `3`. Therefore, return `3` as the starting index.\n\n### Example 2:\n- Input: `gas = [2,3,4], cost = [3,4,3]`\n- Output: `-1`\n- Explanation: You can't start at station `0` or `1`, as there is not enough `gas` to travel to the next station. Let's start at station `2` and fill up with `4` unit of `gas`. Your tank = `0 + 4 = 4` Travel to station `0`. Your tank = `4 - 3 + 2 = 3` Travel to station `1`. Your tank = `3 - 3 + 3 = 3` You cannot travel back to station `2`, as it requires `4` unit of `gas` but you only have `3`. Therefore, you can't travel around the circuit once no matter where you start.\n\n### Constraints:\n\n- `n == gas.length == cost.length`\n- `1 <= n <= 10^5`\n- `0 <= gas[i], cost[i] <= 10^4`\n- The input is generated such that the answer is unique.\n\n## Solution\n\n```py\nclass Solution:\n def canCompleteCircuit(self, gas: list[int], cost: list[int]) -> int:\n start, tank, total = 0, 0, 0\n\n for i in range(len(gas)):\n drive = gas[i] - cost[i]\n tank = tank + drive\n\n if tank < 0:\n tank = 0\n start = i + 1\n total = total + drive\n\n return start if total >= 0 else -1\n```\n"},"/greedy/jump-game":{"mdx":"---\ntitle: '55. Jump Game'\ndescription: You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Greedy\", slug: \"greedy\" }\nissue: \"https://github.com/prdlk/leetcode/issues/175\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 54.8 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Google\", period: \"Three Months\", frequency: 45 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 56.2 }\nsidebar:\n label: 'Jump Game'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [2,3,1,1,4]`\n- Output: `true`\n- Explanation: Jump `1` step from index `0` to `1`, then `3` steps to the last index.\n\n### Example 2:\n- Input: `nums = [3,2,1,0,4]`\n- Output: `false`\n- Explanation: You will always arrive at index `3` no matter what. Its maximum jump length is `0`, which makes it impossible to reach the last index.\n\n### Constraints:\n\n- `1 <= nums.length <= 10^4`\n- `0 <= nums[i] <= 10^5`\n\n## Solution\n\n```py\nclass Solution:\n def canJump(self, nums: list[int]) -> bool:\n best, last = nums[0], len(nums) - 1\n\n for i in range(last):\n if i > best:\n return False\n else:\n pos = nums[i] + i\n best = max(best, pos)\n\n return best >= last\n```\n"},"/greedy/maximum-subarray":{"mdx":"---\ntitle: '53. Maximum Subarray'\ndescription: Given an integer array nums, find the subarray with the largest sum, and return its sum\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Divide and Conquer\", slug: \"divide-and-conquer\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\nissue: \"https://github.com/prdlk/leetcode/issues/174\"\ncompanies:\n - { name: \"Upstart\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 80.2 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 75.6 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 65.3 }\n - { name: \"Google\", period: \"Three Months\", frequency: 54.6 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 85.6 }\nsidebar:\n label: 'Maximum Subarray'\n badge: 'Medium'\n---\n\n::::warning\nIf you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.\n::::\n\n### Example 1:\n- Input: `nums = [-2,1,-3,4,-1,2,1,-5,4]`\n- Output: `6`\n- Explanation: The subarray `[4,-1,2,1]` has the largest sum `6`.\n\n### Example 2:\n- Input: `nums = [1]`\n- Output: `1`\n- Explanation: The subarray `[1]` has the largest sum `1`.\n\n### Example 3:\n- Input: `nums = [5,4,-1,7,8]`\n- Output: `23`\n- Explanation: The subarray `[5,4,-1,7,8]` has the largest sum `23`.\n\n### Constraints:\n\n- `1 <= nums.length <= 10^5`\n- `-10^4 <= nums[i] <= 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def maxSubArray(self, nums: list[int]) -> int:\n best, total = nums[0], nums[0]\n\n for i in range(1, len(nums)):\n if total < 0:\n total = nums[i]\n else:\n total = total + nums[i]\n best = max(best, total)\n\n return best\n```\n"},"/hash-table":{"md":"---\ntitle: Hash Table\ndescription: 'A key maps to a value in constant time, which removes the need for a full scan.'\nhidden: true\n---\n\nSometimes when programming, we need a data structure that maps an arbitrary data type to another arbitrary data type, like an array with non-integer indices. For example, a phone book that allows lookup by a person's name requires such data type.\n\nA **hash table** (or a hash map) is one way of representing this data structure. The idea of hash table is this:\n\nData is stored in a fix-sized array, where each data value has an unique index. When we add a new `(key, value)` pair to the array, we use a hash function to generate a hash value within the range of the array with the `key`. We then store the data `value` at the index indicated by the generated hash value. Later, when we retrieve the data with the `key` from the hash table, we hash the `key` again and look up the data in the array with the corresponding index. Since the hash function always returns the same hash values with the same input, we will always find the correct item in that index.\n\n\n\n\nHash Table Operations\n\n\n## Efficiency\n\nAssuming the hash function uses constant time, the average time complexity is `O(n / k)` for each insertion/access operation on the table, where `n` is the number of entries in the hash table and `k` is the array size of the table. This assumes the hash function distributes keys uniformly across the `k` buckets, so each bucket holds about `n / k` entries on average.\n\n### Frequency Counting\n\n```python\ndef get_counter(arr: list[int]) -> dict[int, int]:\n # initialize a hash map to store each number and its count\n counter: dict[int, int] = {}\n for num in arr:\n # check if num is a key in the hash map\n if num in counter:\n # update the count of num to increase by 1\n counter[num] += 1\n else:\n # set the count of num to 1\n counter[num] = 1\n return counter\n```\n\n:::tip\nPython provides a built-in [`collections.Counter`](https://docs.python.org/3/library/collections.html#collections.Counter) class that does this for us.\n:::\n\n```python\nfrom collections import Counter\n\nfq = Counter(arr)\n```\n","mdx":"---\ntitle: Hash Table\ndescription: 'A key maps to a value in constant time, which removes the need for a full scan.'\nhidden: true\n---\n\nSometimes when programming, we need a data structure that maps an arbitrary data type to another arbitrary data type, like an array with non-integer indices. For example, a phone book that allows lookup by a person's name requires such data type.\n\nA **hash table** (or a hash map) is one way of representing this data structure. The idea of hash table is this:\n\nData is stored in a fix-sized array, where each data value has an unique index. When we add a new `(key, value)` pair to the array, we use a hash function to generate a hash value within the range of the array with the `key`. We then store the data `value` at the index indicated by the generated hash value. Later, when we retrieve the data with the `key` from the hash table, we hash the `key` again and look up the data in the array with the corresponding index. Since the hash function always returns the same hash values with the same input, we will always find the correct item in that index.\n\n\n\n\n\n\n\n\n\n## Efficiency\n\nAssuming the hash function uses constant time, the average time complexity is `O(n / k)` for each insertion/access operation on the table, where `n` is the number of entries in the hash table and `k` is the array size of the table. This assumes the hash function distributes keys uniformly across the `k` buckets, so each bucket holds about `n / k` entries on average.\n\n### Frequency Counting\n\n```python\ndef get_counter(arr: list[int]) -> dict[int, int]:\n # initialize a hash map to store each number and its count\n counter: dict[int, int] = {}\n for num in arr:\n # check if num is a key in the hash map\n if num in counter:\n # update the count of num to increase by 1\n counter[num] += 1\n else:\n # set the count of num to 1\n counter[num] = 1\n return counter\n```\n\n:::tip\nPython provides a built-in [`collections.Counter`](https://docs.python.org/3/library/collections.html#collections.Counter) class that does this for us.\n:::\n\n```python\nfrom collections import Counter\n\nfq = Counter(arr)\n```\n"},"/hash-table/check-if-the-sentence-is-pangram":{"mdx":"---\ntitle: '1832. Check if the Sentence Is Pangram'\ndescription: A pangram is a sentence where every letter of the English alphabet appears at least once\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\ncompanies:\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 34.2 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 14.3 }\n - { name: \"Google\", period: \"Six Months\", frequency: 11.8 }\nsidebar:\n label: 'Check if the Sentence Is Pangram'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `sentence = \"thequickbrownfoxjumpsoverthelazydog\"`\n- Output: `true`\n- Explanation: `sentence` contains at least one of every letter of the English alphabet.\n\n### Example 2:\n- Input: `sentence = \"leetcode\"`\n- Output: `false`\n\n### Constraints:\n\n- `1 <= sentence.length <= 1000`\n- `sentence` consists of lowercase English letters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"checkIfPangram(sentence)\"]) --> I[\"freq = {}\"]\n I --> L{\"more char c?\"}\n L -- yes --> C[\"freq[c] = (freq[c] or 0) + 1\"]\n C --> L\n L -- no --> Q{\"distinct keys in freq == 26?\"}\n Q -- yes --> R([\"return true\"])\n Q -- no --> F([\"return false\"])\n```\n\n## Solution\n\n```js\n/**\n * @param {string} sentence\n * @return {boolean}\n */\nvar checkIfPangram = function(sentence) {\n const freq = {};\n for (let c of sentence) freq[c] = (freq[c] || 0) + 1;\n \n if (Object.keys(freq).length === 26){\n return true;\n }\n return false;\n};\n```\n"},"/hash-table/contains-duplicate":{"mdx":"---\ntitle: '217. Contains Duplicate'\ndescription: Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Sorting\", slug: \"sorting\" }\nvideo: \"3OamzN90kPg\"\nissue: \"https://github.com/prdlk/leetcode/issues/27\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\nsidebar:\n label: 'Contains Duplicate'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `nums = [1,2,3,1]`\n- Output: `true`\n- Explanation: The element `1` occurs at the indices `0` and `3`.\n\n### Example 2:\n- Input: `nums = [1,2,3,4]`\n- Output: `false`\n- Explanation: All elements are distinct.\n\n### Example 3:\n- Input: `nums = [1,1,1,3,3,4,3,2,4,2]`\n- Output: `true`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^5`\n- `-10^9 <= nums[i] <= 10^9`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"containsDuplicate(nums)\"]) --> I[\"freq = {}\"]\n I --> L{\"more n in nums?\"}\n L -- no --> E([\"return false\"])\n L -- yes --> C[\"freq[n] = (freq[n] or 0) + 1\"]\n C --> Q{\"freq[n] >= 2?\"}\n Q -- yes --> R([\"return true\"])\n Q -- no --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def containsDuplicate(self, nums: List[int]) -> bool:\n return len(set(nums)) != len(nums)\n```\n"},"/hash-table/first-unique-character-in-a-string":{"mdx":"---\ntitle: '387. First Unique Character in a String'\ndescription: Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Queue\", slug: \"queue\" }\n - { name: \"Counting\", slug: \"counting\" }\nvideo: \"rBENYgWy3xU\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Yandex\", period: \"Three Months\", frequency: 76.1 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 73.7 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"EPAM Systems\", period: \"Six Months\", frequency: 76.2 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 59 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'First Unique Character in a String'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `s = \"leetcode\"`\n- Output: `0`\n- Explanation: The character `'l'` at index `0` is the first character that does not occur at any other index.\n\n### Example 2:\n- Input: `s = \"loveleetcode\"`\n- Output: `2`\n\n### Example 3:\n- Input: `s = \"aabb\"`\n- Output: `-1`\n\n### Constraints:\n\n- `1 <= s.length <= 10^5`\n- `s` consists of only lowercase English letters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"firstUniqChar(s)\"]) --> F[\"Pass 1 — freq: count every char of s\"]\n F --> L{\"Pass 2 — more i in 0..len-1?\"}\n L -- no --> E([\"return -1\"])\n L -- yes --> Q{\"freq[s[i]] == 1?\"}\n Q -- yes --> R([\"return i — leftmost wins because the scan is in order\"])\n Q -- no --> L\n```\n\n## Solution\n\n```js\n/**\n * @param {string} s\n * @return {number}\n */\nvar firstUniqChar = function (s) {\n const freq = {};\n for (let c of s) freq[c] = (freq[c] || 0) + 1;\n\n for (let i = 0; i < s.length; i++) {\n if (freq[s[i]] === 1) {\n return i;\n }\n }\n return -1;\n};\n```\n"},"/hash-table/group-anagrams":{"mdx":"---\ntitle: '49. Group Anagrams'\ndescription: Given an array of strings strs, group the anagrams together. You can return the answer in any order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sorting\", slug: \"sorting\" }\nvideo: \"vzdNOK2oB2E\"\nissue: \"https://github.com/prdlk/leetcode/issues/30\"\ncompanies:\n - { name: \"Apple\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 78.4 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 76.7 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 58.2 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"CrowdStrike\", period: \"Three Months\", frequency: 100 }\n - { name: \"Deloitte\", period: \"Three Months\", frequency: 100 }\n - { name: \"HashedIn\", period: \"Three Months\", frequency: 100 }\n - { name: \"Smartsheet\", period: \"Three Months\", frequency: 100 }\n - { name: \"Walmart Labs\", period: \"Three Months\", frequency: 100 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Expedia\", period: \"Six Months\", frequency: 100 }\n - { name: \"Wipro\", period: \"Six Months\", frequency: 100 }\n - { name: \"Adobe\", period: \"Six Months\", frequency: 93.7 }\n - { name: \"Zoho\", period: \"Six Months\", frequency: 79.6 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"EPAM Systems\", period: \"Six Months\", frequency: 76.2 }\n - { name: \"Palo Alto Networks\", period: \"Six Months\", frequency: 75.9 }\n - { name: \"Visa\", period: \"Six Months\", frequency: 69.7 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 67.9 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 53.1 }\nsidebar:\n label: 'Group Anagrams'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `strs = [\"eat\",\"tea\",\"tan\",\"ate\",\"nat\",\"bat\"]`\n- Output: `[[\"bat\"],[\"nat\",\"tan\"],[\"ate\",\"eat\",\"tea\"]]`\n- Explanation: There is no string in `strs` that can be rearranged to form `\"bat\"`. The strings `\"nat\"` and `\"tan\"` are anagrams as they can be rearranged to form each other. The strings `\"ate\"`, `\"eat\"`, and `\"tea\"` are anagrams as they can be rearranged to form each other.\n\n### Example 2:\n- Input: `strs = [\"\"]`\n- Output: `[[\"\"]]`\n\n### Example 3:\n- Input: `strs = [\"a\"]`\n- Output: `[[\"a\"]]`\n\n### Constraints:\n\n- `1 <= strs.length <= 10^4`\n- `0 <= strs[i].length <= 100`\n- `strs[i]` consists of lowercase English letters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"groupAnagrams(strs)\"]) --> K[\"sorted[i] = letters of strs[i], sorted — the anagram key\"]\n K --> I[\"anagrams = {}\"]\n I --> L{\"more i in 0..n-1?\"}\n L -- no --> E([\"return Object.values(anagrams)\"])\n L -- yes --> Q{\"anagrams has sorted[i]?\"}\n Q -- no --> N[\"anagrams[sorted[i]] = [strs[i]]\"]\n Q -- yes --> P[\"anagrams[sorted[i]].push(strs[i])\"]\n N --> L\n P --> L\n```\n\n## Solution\n\n```js\n/**\n * @param {string[]} strs\n * @return {string[][]}\n */\nvar groupAnagrams = function(strs) {\n let sorted = strs.map(str => str.split(\"\").sort().join(\"\"));\n let anagrams = {};\n\n for (let i = 0; i < strs.length; i++){\n if(!anagrams[sorted[i]]){\n anagrams[sorted[i]] = [strs[i]]\n }else{\n anagrams[sorted[i]].push(strs[i])\n }\n }\n\n return Object.values(anagrams);\n};\n```\n"},"/hash-table/isomorphic-strings":{"mdx":"---\ntitle: '205. Isomorphic Strings'\ndescription: Given two strings s and t, determine if they are isomorphic\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\nissue: \"https://github.com/prdlk/leetcode/issues/33\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\nsidebar:\n label: 'Isomorphic Strings'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `s = \"egg\", t = \"add\"`\n- Output: `true`\n- Explanation: The strings `s` and `t` can be made identical by: • Mapping 'e' to 'a'. • Mapping 'g' to 'd'.\n\n### Example 2:\n- Input: `s = \"f11\", t = \"b23\"`\n- Output: `false`\n- Explanation: The strings `s` and `t` can not be made identical as `'1`' needs to be mapped to both `'2`' and `'3`'.\n\n### Example 3:\n- Input: `s = \"paper\", t = \"title\"`\n- Output: `true`\n\n### Constraints:\n\n- `1 <= s.length <= 5 * 10^4`\n- `t.length == s.length`\n- `s` and `t` consist of any valid ascii character.\n\n## Solution\n\n```py\nclass Solution:\n def isIsomorphic(self, s: str, t: str) -> bool:\n N = len(t)\n seen = {}\n\n for i in range(N):\n c1, c2 = s[i], t[i]\n if c1 in seen and seen[c1] != c2:\n return False\n elif c1 in seen and seen[c1] == c2:\n continue\n else:\n seen[c1] = c2\n\n return len(set(s)) == len(set(t))\n```\n"},"/hash-table/longest-consecutive-sequence":{"mdx":"---\ntitle: '128. Longest Consecutive Sequence'\ndescription: Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Union-Find\", slug: \"union-find\" }\nissue: \"https://github.com/prdlk/leetcode/issues/34\"\ncompanies:\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 74.3 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 65.8 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 53.2 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 69 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Paytm\", period: \"Six Months\", frequency: 100 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 91.1 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"Salesforce\", period: \"Six Months\", frequency: 50.2 }\nsidebar:\n label: 'Longest Consecutive Sequence'\n badge: 'Medium'\n---\n\n::::warning\nYou must write an algorithm that runs in O(n) time.\n::::\n\n### Example 1:\n- Input: `nums = [100,4,200,1,3,2]`\n- Output: `4`\n- Explanation: The longest consecutive elements sequence is [1, `2`, `3`, 4]. Therefore its length is `4`.\n\n### Example 2:\n- Input: `nums = [0,3,7,2,5,8,4,6,0,1]`\n- Output: `9`\n\n### Example 3:\n- Input: `nums = [1,0,1,2]`\n- Output: `3`\n\n### Constraints:\n\n- `0 <= nums.length <= 10^5`\n- `-10^9 <= nums[i] <= 10^9`\n\n## Solution\n\n```py\nclass Solution:\n def longestConsecutive(self, nums: list[int]) -> int:\n seen = set(nums)\n best = 0\n\n for n in seen:\n if n - 1 in seen:\n continue\n\n length = 1\n while length + n in seen:\n length += 1\n\n best = max(length, best)\n\n return best\n```\n"},"/hash-table/sort-characters-by-frequency":{"mdx":"---\ntitle: '451. Sort Characters By Frequency'\ndescription: Given a string s, sort it in decreasing order based on the frequency of the characters. The frequency of a character is the number of times it appears in the string\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sorting\", slug: \"sorting\" }\n - { name: \"Heap (Priority Queue)\", slug: \"heap-priority-queue\" }\n - { name: \"Bucket Sort\", slug: \"bucket-sort\" }\n - { name: \"Counting\", slug: \"counting\" }\nvideo: \"OXdXc9HTrIg\"\ncompanies:\n - { name: \"Meta\", period: \"Three Months\", frequency: 49.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 20.9 }\nsidebar:\n label: 'Sort Characters By Frequency'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `s = \"tree\"`\n- Output: `\"eert\"`\n- Explanation: `'e'` appears twice while `'r'` and `'t'` both appear once. So `'e'` must appear before both `'r'` and `'t'`. Therefore `\"eetr\"` is also a valid answer.\n\n### Example 2:\n- Input: `s = \"cccaaa\"`\n- Output: `\"aaaccc\"`\n- Explanation: Both `'c'` and `'a'` appear three times, so both `\"cccaaa\"` and `\"aaaccc\"` are valid answers. Note that `\"cacaca\"` is incorrect, as the same characters must be together.\n\n### Example 3:\n- Input: `s = \"Aabb\"`\n- Output: `\"bbAa\"`\n- Explanation: `\"bbaA\"` is also a valid answer, but `\"Aabb\"` is incorrect. Note that `'A'` and `'a'` are treated as two different characters.\n\n### Constraints:\n\n- `1 <= s.length <= 5 * 10^5`\n- `s` consists of uppercase and lowercase English letters and digits.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"frequencySort(s)\"]) --> F[\"freq: count every char of s\"]\n F --> C[\"split s and sort with a two-key comparator\"]\n C --> K1[\"primary: freq[b] - freq[a] — most frequent first\"]\n C --> K2[\"tie-break: a.localeCompare(b) — alphabetical\"]\n K1 --> R([\"join and return\"])\n K2 --> R\n```\n\n## Solution\n\n```js\n/**\n * @param {string} s\n * @return {string}\n */\nvar frequencySort = function (s) {\n // count the frequency of each character\n const freq = {};\n for (let c of s) freq[c] = (freq[c] || 0) + 1;\n\n // sort the characters by frequency\n return s\n .split(\"\")\n .sort((a, b) => freq[b] - freq[a] || a.localeCompare(b))\n .join(\"\");\n};\n```\n"},"/hash-table/top-k-frequent-elements":{"mdx":"---\ntitle: '347. Top K Frequent Elements'\ndescription: Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Divide and Conquer\", slug: \"divide-and-conquer\" }\n - { name: \"Sorting\", slug: \"sorting\" }\n - { name: \"Heap (Priority Queue)\", slug: \"heap-priority-queue\" }\n - { name: \"Bucket Sort\", slug: \"bucket-sort\" }\n - { name: \"Counting\", slug: \"counting\" }\n - { name: \"Quickselect\", slug: \"quickselect\" }\nvideo: \"YPTqKIgVk-k\"\nissue: \"https://github.com/prdlk/leetcode/issues/31\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 72.9 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Snap\", period: \"Six Months\", frequency: 100 }\n - { name: \"SoFi\", period: \"Six Months\", frequency: 100 }\n - { name: \"PayPal\", period: \"Six Months\", frequency: 88.4 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 81.4 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"eBay\", period: \"Six Months\", frequency: 75.2 }\n - { name: \"Visa\", period: \"Six Months\", frequency: 69.7 }\n - { name: \"Snowflake\", period: \"Six Months\", frequency: 58.7 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 50.6 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 48.1 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\nsidebar:\n label: 'Top K Frequent Elements'\n badge: 'Medium'\n---\n\n::::warning\nYour algorithm's time complexity must be better than O(n log n), where n is the array's size.\n::::\n\n### Example 1:\n- Input: `nums = [1,1,1,2,2,3], k = 2`\n- Output: `[1,2]`\n\n### Example 2:\n- Input: `nums = [1], k = 1`\n- Output: `[1]`\n\n### Example 3:\n- Input: `nums = [1,2,1,2,1,2,3,1,3,2], k = 2`\n- Output: `[1,2]`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^5`\n- `-10^4 <= nums[i] <= 10^4`\n- `k` is in the range `[1, the number of unique elements in the array]`.\n- It is guaranteed that the answer is unique.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"topKFrequent(nums, k)\"]) --> F[\"freq: count every value in nums\"]\n F --> K[\"keys of freq, cast to Number\"]\n K --> O[\"sort by freq[b] - freq[a] — most frequent first\"]\n O --> R([\"return slice(0, k)\"])\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n * @param {number} k\n * @return {number[]}\n */\nvar topKFrequent = function (nums, k) {\n const freq = {};\n for (let n of nums) freq[n] = (freq[n] || 0) + 1;\n\n return Object.keys(freq)\n .map(Number)\n .sort((a, b) => freq[b] - freq[a])\n .slice(0, k);\n};\n```\n"},"/hash-table/two-sum":{"mdx":"---\ntitle: '1. Two Sum'\ndescription: You are given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\nvideo: \"KLlXCFG5TnA\"\nissue: \"https://github.com/prdlk/leetcode/issues/29\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 79.6 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 76.7 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 68.6 }\n - { name: \"Altimetrik\", period: \"Three Months\", frequency: 100 }\n - { name: \"Capgemini\", period: \"Three Months\", frequency: 100 }\n - { name: \"Microstrategy\", period: \"Three Months\", frequency: 100 }\n - { name: \"MongoDB\", period: \"Three Months\", frequency: 100 }\n - { name: \"Cognizant\", period: \"Three Months\", frequency: 88.7 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 80.4 }\n - { name: \"Barclays\", period: \"Six Months\", frequency: 100 }\n - { name: \"Cisco\", period: \"Six Months\", frequency: 100 }\n - { name: \"Deloitte\", period: \"Six Months\", frequency: 100 }\n - { name: \"Expedia\", period: \"Six Months\", frequency: 100 }\n - { name: \"NetApp\", period: \"Six Months\", frequency: 100 }\n - { name: \"Samsung\", period: \"Six Months\", frequency: 100 }\n - { name: \"Sony\", period: \"Six Months\", frequency: 100 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 91.2 }\n - { name: \"Qualcomm\", period: \"Six Months\", frequency: 80.7 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 77.2 }\n - { name: \"eBay\", period: \"Six Months\", frequency: 75.2 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 70.5 }\n - { name: \"Flipkart\", period: \"Six Months\", frequency: 57.1 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\nsidebar:\n label: 'Two Sum'\n badge: 'Easy'\n---\n\n::::warning\nCan you come up with an algorithm that is less than O(n^2) time complexity?\n::::\n\n### Example 1:\n- Input: `nums = [2,7,11,15], target = 9`\n- Output: `[0,1]`\n- Explanation: Because `nums[0] + nums[1]` == `9`, we return [0, 1].\n\n### Example 2:\n- Input: `nums = [3,2,4], target = 6`\n- Output: `[1,2]`\n\n### Example 3:\n- Input: `nums = [3,3], target = 6`\n- Output: `[0,1]`\n\n### Constraints:\n\n- `2 <= nums.length <= 10^4`\n- `-10^9 <= nums[i] <= 10^9`\n- `-10^9 <= target <= 10^9`\n- Only one valid answer exists.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"twoSum(nums, target)\"]) --> I[\"seen = {} — value to index\"]\n I --> L{\"more (i, num) in nums?\"}\n L -- no --> E([\"return []\"])\n L -- yes --> C[\"complement = target - num\"]\n C --> H{\"complement in seen?\"}\n H -- yes --> R([\"return [seen[complement], i]\"])\n H -- no --> W[\"seen[num] = i\"]\n W --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def twoSum(self, nums: List[int], target: int) -> List[int]:\n seen = {}\n for i, num in enumerate(nums):\n complement = target - num\n if complement in seen:\n return [seen[complement], i]\n seen[num] = i\n return []\n```\n"},"/hash-table/valid-anagram":{"mdx":"---\ntitle: '242. Valid Anagram'\ndescription: Given two strings s and t, return true if t is an anagram of s, and false otherwise\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sorting\", slug: \"sorting\" }\nvideo: \"9UtInBqnCgA\"\nissue: \"https://github.com/prdlk/leetcode/issues/28\"\ncompanies:\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 58.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 53.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"IBM\", period: \"Three Months\", frequency: 100 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 64.4 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 58.9 }\n - { name: \"Deloitte\", period: \"Six Months\", frequency: 81 }\nsidebar:\n label: 'Valid Anagram'\n badge: 'Easy'\n---\n\n::::warning\nWhat if the inputs contain Unicode characters? How would you adapt your solution to such a case?\n::::\n\n### Example 1:\n- Input: `s = \"anagram\", t = \"nagaram\"`\n- Output: `true`\n\n### Example 2:\n- Input: `s = \"rat\", t = \"car\"`\n- Output: `false`\n\n### Constraints:\n\n- `1 <= s.length, t.length <= 5 * 10^4`\n- `s` and `t` consist of lowercase English letters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"isAnagram(s, t)\"]) --> I[\"freq: count every char of s\"]\n I --> L{\"more char c in t?\"}\n L -- no --> E([\"return true\"])\n L -- yes --> Q{\"freq[c] missing or 0?\"}\n Q -- yes --> R([\"return false — t has a char s cannot cover\"])\n Q -- no --> D[\"freq[c] -= 1\"]\n D --> L\n```\n\n## Solution\n\n```js\n/**\n * @param {string} s\n * @param {string} t\n * @return {boolean}\n */\nvar isAnagram = function(s, t) {\n let freq = {};\n for (let c of s) freq[c] = (freq[c] || 0) + 1;\n \n for (let c of t) {\n if(!freq[c] || freq[c] === 0){\n return false;\n }\n freq[c] = freq[c] - 1;\n }\n return true;\n};\n```\n"},"/hash-table/word-pattern":{"mdx":"---\ntitle: '290. Word Pattern'\ndescription: Given a pattern and a string s, find if s follows the same pattern\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\nissue: \"https://github.com/prdlk/leetcode/issues/35\"\ncompanies:\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 20.9 }\nsidebar:\n label: 'Word Pattern'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `pattern = \"abba\", s = \"dog cat cat dog\"`\n- Output: `true`\n- Explanation: The bijection can be established as: • 'a' maps to \"dog\". • 'b' maps to \"cat\".\n\n### Example 2:\n- Input: `pattern = \"abba\", s = \"dog cat cat fish\"`\n- Output: `false`\n\n### Example 3:\n- Input: `pattern = \"aaaa\", s = \"dog cat cat dog\"`\n- Output: `false`\n\n### Constraints:\n\n- `1 <= pattern.length <= 300`\n- `pattern` contains only lower-case English letters.\n- `1 <= s.length <= 3000`\n- `s` contains only lowercase English letters and spaces ' '.\n- `s` does not contain any leading or trailing spaces.\n- All the words in `s` are separated by a single space.\n\n## Solution\n\n```py\nclass Solution:\n def wordPattern(self, pattern: str, s: str) -> bool:\n if len(pattern) != len(s.split()):\n return False\n\n words = s.split()\n map = {}\n\n for i in range(len(pattern)):\n c = pattern[i]\n w = words[i]\n\n if c in map and map[c] != w:\n return False\n else:\n map[c] = w\n\n return len(set(pattern)) == len(set(words))\n```\n"},"/heap-priority-queue":{"mdx":"---\ntitle: Heap / Priority Queue\ndescription: 'The largest or smallest item is always at the top, and it is removed in logarithmic time.'\nhidden: true\n---\n"},"/heap-priority-queue/k-closest-points-to-origin":{"mdx":"---\ntitle: '973. K Closest Points to Origin'\ndescription: Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane and an integer k, return the k closest points to the origin (0, 0)\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Divide and Conquer\", slug: \"divide-and-conquer\" }\n - { name: \"Geometry\", slug: \"geometry\" }\n - { name: \"Sorting\", slug: \"sorting\" }\n - { name: \"Heap (Priority Queue)\", slug: \"heap-priority-queue\" }\n - { name: \"Quickselect\", slug: \"quickselect\" }\n - { name: \"K-D Tree\", slug: \"k-d-tree\" }\nvideo: \"rI2EBUEMfTk\"\nissue: \"https://github.com/prdlk/leetcode/issues/119\"\ncompanies:\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 47.3 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'K Closest Points to Origin'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `points = [[1,3],[-2,2]], k = 1`\n- Output: `[[-2,2]]`\n- Explanation: The distance between `(1`, `3`) and the origin is sqrt(10). The distance between `(-2`, `2`) and the origin is sqrt(8). Since sqrt(8) < sqrt(10), `(-2`, `2`) is closer to the origin. We only want the closest `k = 1 points` from the origin, so the answer is just [[-2,2]].\n\n### Example 2:\n- Input: `points = [[3,3],[5,-1],[-2,4]], k = 2`\n- Output: `[[3,3],[-2,4]]`\n- Explanation: The answer [[-2,4],[3,3]] would also be accepted.\n\n### Constraints:\n\n- `1 <= k <= points.length <= 10^4`\n- `-10^4 <= xi, yi <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"kClosest(points, k)\"]) --> I[\"minHeap = []\"]\n I --> F{\"more x, y in points?\"}\n F -- yes --> D[\"dist = x**2 + y**2 — squared distance orders the same as sqrt\"]\n D --> A[\"minHeap.append([dist, x, y])\"]\n A --> F\n F -- no --> H[\"heapq.heapify(minHeap), res = [] — O(n) build, smallest dist on top\"]\n H --> W{\"k > 0?\"}\n W -- yes --> P[\"dist, x, y = heapq.heappop(minHeap)\"]\n P --> R[\"res.append([x, y]), k -= 1\"]\n R --> W\n W -- no --> E([\"return res\"])\n```\n\n## Solution\n\n```py\nimport heapq\n\n\nclass Solution:\n def kClosest(self, points: List[List[int]], k: int) -> List[List[int]]:\n minHeap = []\n for x, y in points:\n dist = (x**2) + (y**2)\n minHeap.append([dist, x, y])\n\n heapq.heapify(minHeap)\n res = []\n\n while k > 0:\n dist, x, y = heapq.heappop(minHeap)\n res.append([x, y])\n k -= 1\n\n return res\n```\n"},"/heap-priority-queue/kth-largest-element-in-an-array":{"mdx":"---\ntitle: '215. Kth Largest Element in an Array'\ndescription: Given an integer array nums and an integer k, return the k^th largest element in the array\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Divide and Conquer\", slug: \"divide-and-conquer\" }\n - { name: \"Sorting\", slug: \"sorting\" }\n - { name: \"Heap (Priority Queue)\", slug: \"heap-priority-queue\" }\n - { name: \"Quickselect\", slug: \"quickselect\" }\nvideo: \"XEmy13g1Qxc\"\nissue: \"https://github.com/prdlk/leetcode/issues/118\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 70.8 }\n - { name: \"Spotify\", period: \"Three Months\", frequency: 90.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 32.7 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 70.5 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 70.1 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 63.3 }\n - { name: \"Flipkart\", period: \"Six Months\", frequency: 57.1 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 37.9 }\nsidebar:\n label: 'Kth Largest Element in an Array'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [3,2,1,5,6,4], k = 2`\n- Output: `5`\n\n### Example 2:\n- Input: `nums = [3,2,3,1,2,4,5,5,6], k = 4`\n- Output: `4`\n\n### Constraints:\n\n- `1 <= k <= nums.length <= 10^5`\n- `-10^4 <= nums[i] <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"findKthLargest(nums, k)\"]) --> F{\"more i in range(len(nums))?\"}\n F -- yes --> N[\"nums[i] = -nums[i] — negate so the min-heap acts as a max-heap\"]\n N --> F\n F -- no --> H[\"heapq.heapify(nums)\"]\n H --> W{\"more _ in range(k - 1)?\"}\n W -- yes --> P[\"heapq.heappop(nums) — discard the k-1 largest\"]\n P --> W\n W -- no --> E([\"return -heapq.heappop(nums)\"])\n```\n\n## Solution\n\n```py\nimport heapq\n\n\nclass Solution:\n def findKthLargest(self, nums: List[int], k: int) -> int:\n for i in range(len(nums)):\n nums[i] = -nums[i]\n\n heapq.heapify(nums)\n\n for _ in range(k - 1):\n heapq.heappop(nums)\n\n return -heapq.heappop(nums)\n```\n"},"/heap-priority-queue/merge-k-sorted-lists":{"mdx":"---\ntitle: '23. Merge k Sorted Lists'\ndescription: You are given an array of k linked-lists lists, each linked-list is sorted in ascending order\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Divide and Conquer\", slug: \"divide-and-conquer\" }\n - { name: \"Heap (Priority Queue)\", slug: \"heap-priority-queue\" }\n - { name: \"Merge Sort\", slug: \"merge-sort\" }\n - { name: \"Tournament Sort\", slug: \"tournament-sort\" }\nvideo: \"q5a5OiGbT6Q\"\nissue: \"https://github.com/prdlk/leetcode/issues/120\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"FreshWorks\", period: \"Three Months\", frequency: 100 }\n - { name: \"Snap\", period: \"Three Months\", frequency: 100 }\n - { name: \"Deloitte\", period: \"Three Months\", frequency: 89.1 }\n - { name: \"Salesforce\", period: \"Three Months\", frequency: 64.7 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 57.9 }\nsidebar:\n label: 'Merge k Sorted Lists'\n badge: 'Hard'\n---\n\n### Example 1:\n- Input: `lists = [[1,4,5],[1,3,4],[2,6]]`\n- Output: `[1,1,2,3,4,4,5,6]`\n- Explanation: The linked-lists are: [ 1->4->5, 1->3->4, 2->6 ] merging them into one sorted linked list: 1->1->2->3->4->4->5->6\n\n### Example 2:\n- Input: `lists = []`\n- Output: `[]`\n\n### Example 3:\n- Input: `lists = [[]]`\n- Output: `[]`\n\n### Constraints:\n\n- `k == lists.length`\n- `0 <= k <= 10^4`\n- `0 <= lists[i].length <= 500`\n- `-10^4 <= lists[i][j] <= 10^4`\n- `lists[i]` is sorted in ascending order.\n- The sum of lists[i].length will not exceed 10^4.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"mergeKLists(lists)\"]) --> I[\"heap = []\"]\n I --> F{\"more i, node in enumerate(lists)?\"}\n F -- yes --> C{\"node?\"}\n C -- yes --> P[\"heapq.heappush(heap, (node.val, i, node)) — i breaks ties so nodes are never compared\"]\n P --> F\n C -- no --> F\n F -- no --> D[\"D = ListNode(), cur = D\"]\n D --> W{\"heap?\"}\n W -- no --> E([\"return D.next\"])\n W -- yes --> O[\"val, i, node = heapq.heappop(heap) — the smallest head across all lists\"]\n O --> L[\"cur.next = node, cur = node, node = node.next\"]\n L --> N{\"node?\"}\n N -- yes --> Q[\"heapq.heappush(heap, (node.val, i, node))\"]\n Q --> W\n N -- no --> W\n```\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nimport heapq\n\n\nclass Solution:\n def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:\n heap = []\n\n # K log K\n for i, node in enumerate(lists):\n if node:\n heapq.heappush(heap, (node.val, i, node))\n\n D = ListNode()\n cur = D\n\n # n log k\n while heap:\n val, i, node = heapq.heappop(heap)\n cur.next = node\n cur = node\n node = node.next\n\n if node:\n heapq.heappush(heap, (node.val, i, node))\n\n # Time: O(N log k)\n # Space: O(n)\n return D.next\n```\n"},"/hybrid-structures":{"mdx":"---\ntitle: Hybrid Structures\ndescription: 'Two structures are combined, such as a hash map and a linked list, to get the best properties of each.'\nhidden: true\n---\n"},"/hybrid-structures/add-two-numbers":{"mdx":"---\ntitle: '2. Add Two Numbers'\ndescription: You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Recursion\", slug: \"recursion\" }\nvideo: \"wgFPrzTjm7s\"\nissue: \"https://github.com/prdlk/leetcode/issues/88\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 95.8 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 72.8 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 63.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 61.3 }\n - { name: \"EarnIn\", period: \"Six Months\", frequency: 100 }\n - { name: \"Jane Street\", period: \"Six Months\", frequency: 100 }\n - { name: \"Palo Alto Networks\", period: \"Six Months\", frequency: 75.9 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\nsidebar:\n label: 'Add Two Numbers'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `l1 = [2,4,3], l2 = [5,6,4]`\n- Output: `[7,0,8]`\n- Explanation: `342 + 465 = 807`.\n\n### Example 2:\n- Input: `l1 = [0], l2 = [0]`\n- Output: `[0]`\n\n### Example 3:\n- Input: `l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]`\n- Output: `[8,9,9,9,0,0,0,1]`\n\n### Constraints:\n\n- The number of nodes in each linked list is in the range [1, 100].\n- `0 <= Node.val <= 9`\n- It is guaranteed that the list represents a number that does not have leading zeros.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"addTwoNumbers(l1, l2)\"]) --> I[\"dummy = ListNode(), carry = 0, curr = dummy — dummy.next will be the head\"]\n I --> W{\"l1 or l2 or carry?\"}\n W -- no --> E([\"return dummy.next\"])\n W -- yes --> A[\"s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry — a missing digit counts as 0\"]\n A --> D[\"carry, val = divmod(s, 10)\"]\n D --> N[\"curr.next = ListNode(val), curr = curr.next\"]\n N --> V[\"l1 = l1.next if l1 else None, l2 = l2.next if l2 else None\"]\n V --> W\n```\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def addTwoNumbers(\n self, l1: Optional[ListNode], l2: Optional[ListNode]\n ) -> Optional[ListNode]:\n\n dummy = ListNode()\n carry = 0\n curr = dummy\n while l1 or l2 or carry:\n s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry\n carry, val = divmod(s, 10)\n\n curr.next = ListNode(val)\n curr = curr.next\n\n l1 = l1.next if l1 else None\n l2 = l2.next if l2 else None\n\n return dummy.next\n```\n"},"/hybrid-structures/insert-delete-getrandom-o1":{"mdx":"---\ntitle: '380. Insert Delete GetRandom O(1)'\ndescription: 'Implement the RandomizedSet class:'\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Design\", slug: \"design\" }\n - { name: \"Randomized\", slug: \"randomized\" }\nissue: \"https://github.com/prdlk/leetcode/issues/90\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 80.4 }\n - { name: \"Google\", period: \"Three Months\", frequency: 32.7 }\n - { name: \"Axon\", period: \"Six Months\", frequency: 100 }\n - { name: \"Okta\", period: \"Six Months\", frequency: 100 }\n - { name: \"Quora\", period: \"Six Months\", frequency: 100 }\n - { name: \"SoFi\", period: \"Six Months\", frequency: 100 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 61.9 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 59.6 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Insert Delete GetRandom O(1)'\n badge: 'Medium'\n---\n\n::::warning\nYou must implement the functions of the class such that each function works in average O(1) time complexity.\n::::\n\n### Example 1:\n- Input: ``\n- Output: ``\n- Explanation: Input [\"RandomizedSet\", \"insert\", \"remove\", \"insert\", \"getRandom\", \"remove\", \"insert\", \"getRandom\"] `[[]`, `[1]`, `[2]`, `[2]`, `[]`, `[1]`, `[2]`, []] Output [null, true, false, true, `2`, true, false, 2] Explanation RandomizedSet randomizedSet = new RandomizedSet(); randomizedSet.insert(1); // Inserts `1` to the set. Returns true as `1` was inserted successfully. randomizedSet.remove(2); // Returns false as `2` does not exist in the set. randomizedSet.insert(2); // Inserts `2` to the set, returns true. Set now contains `[1,2]`. randomizedSet.getRandom(); // getRandom() should return either `1` or `2` randomly. randomizedSet.remove(1); // Removes `1` from the set, returns true. Set now contains `[2]`. randomizedSet.insert(2); // `2` was already in the set, so return false. randomizedSet.getRandom(); // Since `2` is the only number in the set, getRandom() will always return `2`.\n\n### Constraints:\n\n- `-2^31 <= val <= 2^31 - 1`\n- At most 2 * 10^5 calls will be made to insert, remove, and getRandom.\n- There will be at least one element in the data structure when getRandom is called.\n\n## Solution\n\n```py\nfrom random import choice\n\n\nclass RandomizedSet:\n def __init__(self):\n self.list = []\n self.dict = {}\n\n def insert(self, val: int) -> bool:\n if val in self.dict:\n return False\n self.dict[val] = len(self.list)\n self.list.append(val)\n return True\n\n def remove(self, val: int) -> bool:\n if val in self.dict:\n last, idx = self.list[-1], self.dict[val]\n self.list[idx], self.dict[last] = last, idx\n self.list.pop()\n del self.dict[val]\n return True\n return False\n\n def getRandom(self) -> int:\n return choice(self.list)\n\n\n# Your RandomizedSet object will be instantiated and called as such:\n# obj = RandomizedSet()\n# param_1 = obj.insert(val)\n# param_2 = obj.remove(val)\n# param_3 = obj.getRandom()\n```\n"},"/hybrid-structures/lru-cache":{"mdx":"---\ntitle: '146. LRU Cache'\ndescription: Design a data structure that follows the constraints of a Least Recently Used (LRU) cache\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Design\", slug: \"design\" }\n - { name: \"Doubly-Linked List\", slug: \"doubly-linked-list\" }\nvideo: \"7ABFKPK2hD4\"\nissue: \"https://github.com/prdlk/leetcode/issues/87\"\ncompanies:\n - { name: \"NetApp\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Adobe\", period: \"Thirty Days\", frequency: 83.5 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"TikTok\", period: \"Three Months\", frequency: 100 }\n - { name: \"Palo Alto Networks\", period: \"Three Months\", frequency: 92.8 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 88.5 }\n - { name: \"Goldman Sachs\", period: \"Three Months\", frequency: 66.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 53.2 }\n - { name: \"Airwallex\", period: \"Six Months\", frequency: 100 }\n - { name: \"Docusign\", period: \"Six Months\", frequency: 100 }\n - { name: \"Moloco\", period: \"Six Months\", frequency: 100 }\n - { name: \"Nutanix\", period: \"Six Months\", frequency: 100 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 100 }\n - { name: \"Twitch\", period: \"Six Months\", frequency: 100 }\n - { name: \"Snap\", period: \"Six Months\", frequency: 92.4 }\n - { name: \"Qualcomm\", period: \"Six Months\", frequency: 92 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 91.1 }\n - { name: \"ByteDance\", period: \"Six Months\", frequency: 88.6 }\n - { name: \"MongoDB\", period: \"Six Months\", frequency: 87.7 }\n - { name: \"Expedia\", period: \"Six Months\", frequency: 87.5 }\n - { name: \"eBay\", period: \"Six Months\", frequency: 86.1 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 74.9 }\n - { name: \"Visa\", period: \"Six Months\", frequency: 69.7 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 61.9 }\n - { name: \"Salesforce\", period: \"Six Months\", frequency: 50.2 }\nsidebar:\n label: 'LRU Cache'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: ``\n- Output: ``\n- Explanation: Input [\"LRUCache\", \"put\", \"put\", \"get\", \"put\", \"get\", \"put\", \"get\", \"get\", \"get\"] `[[2]`, [1, 1], [2, 2], `[1]`, [3, 3], `[2]`, [4, 4], `[1]`, `[3]`, [4]] Output [null, null, null, `1`, null, `-1`, null, `-1`, `3`, 4] Explanation LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, `1`); // cache is {1=1} lRUCache.put(2, `2`); // cache is {1=1, 2=2} lRUCache.get(1); // return `1` lRUCache.put(3, `3`); // LRU `key` was `2`, evicts `key 2`, cache is {1=1, 3=3} lRUCache.get(2); // returns `-1` (not found) lRUCache.put(4, `4`); // LRU `key` was `1`, evicts `key 1`, cache is {4=4, 3=3} lRUCache.get(1); // return `-1` (not found) lRUCache.get(3); // return `3` lRUCache.get(4); // return `4`\n\n### Constraints:\n\n- `1 <= capacity <= 3000`\n- `0 <= key <= 10^4`\n- `0 <= value <= 10^5`\n- At most 2 * 10^5 calls will be made to get and put.\n\n## Approach\n\n```mermaid\nflowchart TD\n subgraph state[\"state — dict for O(1) lookup, doubly linked list for O(1) reorder\"]\n H[\"head — least recent\"] --- N[\"... nodes ...\"] --- T[\"tail — most recent\"]\n end\n subgraph get[\"get(key)\"]\n G1{\"key in cache?\"} -- no --> G2([\"return -1\"])\n G1 -- yes --> G3[\"_remove_node then _add_node — move it beside the tail\"]\n G3 --> G4([\"return node.value\"])\n end\n subgraph put[\"put(key, value)\"]\n P1{\"key in cache?\"} -- yes --> P2[\"update value, _remove_node then _add_node\"]\n P1 -- no --> P3[\"new Node, cache[key] = node, _add_node\"]\n P3 --> P4{\"len(cache) > capacity?\"}\n P4 -- yes --> P5[\"evict head.next — the least recent — and del cache[lru.key]\"]\n P4 -- no --> P6([\"done\"])\n P2 --> P6\n P5 --> P6\n end\n state --> get\n state --> put\n```\n\n## Solution\n\n```py\nclass Node:\n def __init__(self, key=0, value=0):\n self.key = key\n self.value = value\n self.prev = None\n self.next = None\n\n\nclass LRUCache:\n def __init__(self, capacity: int):\n self.capacity = capacity\n self.cache = {}\n self.head = Node()\n self.tail = Node()\n self.head.next = self.tail # pyright: ignore[reportAttributeAccessIssue]\n self.tail.prev = self.head # pyright: ignore[reportAttributeAccessIssue]\n\n def _remove_node(self, node):\n prev_node = node.prev\n next_node = node.next\n prev_node.next = next_node\n next_node.prev = prev_node\n\n def _add_node(self, node):\n # Insert just before the tail (most recent at end)\n node.next = self.tail\n node.prev = self.tail.prev\n self.tail.prev.next = node # pyright: ignore[reportAttributeAccessIssue]\n self.tail.prev = node\n\n def get(self, key: int) -> int:\n if key not in self.cache:\n return -1\n\n node = self.cache[key]\n self._remove_node(node)\n self._add_node(node)\n return node.value\n\n def put(self, key: int, value: int) -> None:\n if key in self.cache:\n node = self.cache[key]\n node.value = value\n self._remove_node(node)\n self._add_node(node)\n else:\n new_node = Node(key, value)\n self.cache[key] = new_node\n self._add_node(new_node)\n\n if len(self.cache) > self.capacity:\n lru = self.head.next # Oldest node is next to the head\n self._remove_node(lru)\n del self.cache[lru.key] # pyright: ignore[reportAttributeAccessIssue]\n\n\n# Your LRUCache object will be instantiated and called as such:\n# obj = LRUCache(capacity)\n# param_1 = obj.get(key)\n# obj.put(key,value)\n```\n"},"/intervals":{"md":"---\ntitle: Intervals\ndescription: 'Ranges with a start and an end are sorted, and then merged, counted, or scheduled.'\nhidden: true\n---\n\nAn interval is a pair `[start, end]` marking a stretch on a line:\n- the minutes a meeting occupies\n- the range a task runs\n- the span a sensor was active\n\n**What interval problems ask you?**\n\n- Do any two collide?\n- What does the timeline look like once you merge everything that touches?\n- How many rooms do you need so no two meetings share one?\n\n:::tip\nEvery one of those questions reduces to a single primitive: deciding whether two intervals overlap, and if they do, how to merge them or what part they share. Once that primitive is clear, the rest of the pattern is bookkeeping.\n:::\n\n## When two intervals overlap\n\nIt is easier to state when two intervals do not overlap. Interval `a` sits entirely before interval `b` when `a` finishes before `b` begins, that is `a.end < b.start`. By symmetry they also miss each other when `b` ends before `a` starts. If neither of those holds, the intervals overlap.\n\n\n\nNegating `a.end < b.start` or `b.end < a.start` gives the positive test directly: two intervals overlap exactly when `a.start <= b.end` and `b.start <= a.end`. That pair of comparisons is the whole overlap check.\n\n## The Merged Region\n\nWhen two intervals overlap, you can merge them into one interval that covers both. Its start is the earlier of the two starts, and its end is the later of the two ends: `[min(a.start, b.start), max(a.end, b.end)]`. The merged interval begins as soon as either interval starts, and it ends only once both have stopped.\n\n\n\n## The Shared Region\n\nWhen two intervals overlap, the part they share is itself an interval. Its start is the later of the two starts, and its end is the earlier of the two ends: `[max(a.start, b.start), min(a.end, b.end)]`. The overlap begins only once both intervals have started, and it ends the moment either one stops.\n\n\n\n:::tip\nMerge grows, overlap shrinks. Merge uses `[min, max]` and covers both intervals. Overlap uses `[max, min]` and keeps only the part both share.\n:::\n\n## Sort by Start first\n\nLeft unsorted, checking a list of intervals means comparing every pair, which is `O(n^2)`. Sorting the intervals by start time removes that cost. Once the list is in start order, any interval can only overlap ones that come after it and begin before it ends, so a single left-to-right pass is enough to merge, count, or detect collisions.\n\nSorting by start is the standard first line of almost every interval solution, and the problems below all lean on it.\n\nThat gives the template every interval problem in this section builds on: sort by start, then sweep once, comparing each interval against the last one you kept.\n\n\n:::note[Input]\n`[[1,3], [8,10], [2,6], [4,5], [10,12]]`\n:::\n\n:::note[After sort]\n`[[1,3], [2,6], [4,5], [8,10], [10,12]]`\n:::\n\n```python\n# Time: O(n log n)\n# Space: O(n)\ndef interval_pattern(intervals):\n # 1. Sort by start time\n intervals.sort(key=lambda x: x[0])\n result = []\n for start, end in intervals:\n # 2. Overlap with the last kept interval? start <= last end\n if result and start <= result[-1][1]:\n # Merge: extend the end of the last interval\n result[-1][1] = max(result[-1][1], end)\n else:\n # 3. No overlap: keep this interval as-is\n result.append([start, end])\n return result\n```\n\n**Show trace table**\n\n| i | `[start, end]` | `result[-1]` | `start <= result[-1][1]`? | Action | `result` after |\n|---|---|---|---|---|---|\n| 0 | `[1,3]` | — | — (empty) | append | `[[1,3]]` |\n| 1 | `[2,6]` | `[1,3]` | `2 <= 3` ✅ | end = `max(3,6)` = 6 | `[[1,6]]` |\n| 2 | `[4,5]` | `[1,6]` | `4 <= 6` ✅ | end = `max(6,5)` = 6 | `[[1,6]]` |\n| 3 | `[8,10]` | `[1,6]` | `8 <= 6` ❌ | append | `[[1,6], [8,10]]` |\n| 4 | `[10,12]` | `[8,10]` | `10 <= 10` ✅ | end = `max(10,12)` = 12 | `[[1,6], [8,12]]` |\n\n\n:::tip[Output]\n`[[1,6], [8,12]]`\n - **Row 2:** `[4,5]` sits inside `[1,6]`. Setting `end = 5` without `max` would cut the interval short. `max` keeps 6.\n - **Row 4:** `[8,10]` and `[10,12]` only touch at 10. The `<=` check merges them. With `<`, you would get two intervals.\n:::\n\n\n## Insert into a sorted list\n\nSometimes the list is already sorted and has no overlaps, and you must add one new interval. You could append it, sort, and run the template. That works, but it pays `O(n log n)` for a sort you do not need.\n\nA sorted list with no overlaps splits into three parts around the new interval, in this order:\n\n1. Intervals that end **before** the new one starts. Keep them as they are.\n2. Intervals that **overlap** the new one. Merge each into it with `[min, max]`.\n3. Intervals that start **after** the new one ends. Keep them as they are.\n\nWalk the list once and handle each part in turn. No sort, so the cost drops to `O(n)`.\n\n:::note[Intervals]\n`[[1,2], [3,5], [6,7], [8,10], [12,16]]`\n:::\n\n:::note[New interval]\n`[4,8]`\n:::\n\n```python\n# Time: O(n)\n# Space: O(n)\ndef insert_interval(intervals, new_interval):\n result = []\n i, n = 0, len(intervals)\n start, end = new_interval\n\n # 1. Ends before new starts: keep\n while i < n and intervals[i][1] < start:\n result.append(intervals[i])\n i += 1\n\n # 2. Overlaps new: grow new to cover it\n while i < n and intervals[i][0] <= end:\n start = min(start, intervals[i][0])\n end = max(end, intervals[i][1])\n i += 1\n result.append([start, end])\n\n # 3. Starts after new ends: keep\n result.extend(intervals[i:])\n return result\n```\n\n**Show trace table**\n\n| i | interval | Part | Check | Action | `[start, end]` | `result` after |\n|---|---|---|---|---|---|---|\n| 0 | `[1,2]` | 1 | `2 < 4` ✅ | keep | `[4,8]` | `[[1,2]]` |\n| 1 | `[3,5]` | 1 | `5 < 4` ❌ | go to part 2 | `[4,8]` | `[[1,2]]` |\n| 1 | `[3,5]` | 2 | `3 <= 8` ✅ | start = `min(4,3)` = 3 | `[3,8]` | `[[1,2]]` |\n| 2 | `[6,7]` | 2 | `6 <= 8` ✅ | end = `max(8,7)` = 8 | `[3,8]` | `[[1,2]]` |\n| 3 | `[8,10]` | 2 | `8 <= 8` ✅ | end = `max(8,10)` = 10 | `[3,10]` | `[[1,2]]` |\n| 4 | `[12,16]` | 2 | `12 <= 10` ❌ | append new | `[3,10]` | `[[1,2], [3,10]]` |\n| 4 | `[12,16]` | 3 | — | extend rest | — | `[[1,2], [3,10], [12,16]]` |\n\n:::tip[Output]\n`[[1,2], [3,10], [12,16]]`\n - **Row i=1:** The same interval shows up twice. The part 1 check fails, so that loop stops, and part 2 reads the same interval again. `i` does not move.\n - **Row i=3:** `[8,10]` only touches `[3,8]` at 8. The `<=` merges them, since one shared point counts as an overlap.\n - **Part 1 uses `<`, part 2 uses `<=`:** An interval that ends exactly at `start` touches the new interval. It must fail part 1 so part 2 can merge it.\n:::\n\n:::warning\nIf the input is already sorted, do not sort again. Interviewers add \"sorted\" to the problem on purpose. Name the `O(n log n)` cost of re-sorting before they do, then offer the `O(n)` three-part walk.\n:::\n\n### Footnote\n\nThe positive overlap test comes straight from De Morgan's law. Negating `(a.end < b.start)` or `(b.end < a.start)` gives `(a.end >= b.start)` and `(b.end >= a.start)`, which is the `a.start <= b.end` and `b.start <= a.end` condition rewritten.\n","mdx":"---\ntitle: Intervals\ndescription: 'Ranges with a start and an end are sorted, and then merged, counted, or scheduled.'\nhidden: true\n---\n\nAn interval is a pair `[start, end]` marking a stretch on a line:\n- the minutes a meeting occupies\n- the range a task runs\n- the span a sensor was active\n\n**What interval problems ask you?**\n\n- Do any two collide?\n- What does the timeline look like once you merge everything that touches?\n- How many rooms do you need so no two meetings share one?\n\n:::tip\nEvery one of those questions reduces to a single primitive: deciding whether two intervals overlap, and if they do, how to merge them or what part they share. Once that primitive is clear, the rest of the pattern is bookkeeping.\n:::\n\n## When two intervals overlap\n\nIt is easier to state when two intervals do not overlap. Interval `a` sits entirely before interval `b` when `a` finishes before `b` begins, that is `a.end < b.start`. By symmetry they also miss each other when `b` ends before `a` starts. If neither of those holds, the intervals overlap.\n\n\n\nNegating `a.end < b.start` or `b.end < a.start` gives the positive test directly: two intervals overlap exactly when `a.start <= b.end` and `b.start <= a.end`. That pair of comparisons is the whole overlap check.\n\n## The Merged Region\n\nWhen two intervals overlap, you can merge them into one interval that covers both. Its start is the earlier of the two starts, and its end is the later of the two ends: `[min(a.start, b.start), max(a.end, b.end)]`. The merged interval begins as soon as either interval starts, and it ends only once both have stopped.\n\n\n\n## The Shared Region\n\nWhen two intervals overlap, the part they share is itself an interval. Its start is the later of the two starts, and its end is the earlier of the two ends: `[max(a.start, b.start), min(a.end, b.end)]`. The overlap begins only once both intervals have started, and it ends the moment either one stops.\n\n\n\n:::tip\nMerge grows, overlap shrinks. Merge uses `[min, max]` and covers both intervals. Overlap uses `[max, min]` and keeps only the part both share.\n:::\n\n## Sort by Start first\n\nLeft unsorted, checking a list of intervals means comparing every pair, which is `O(n^2)`. Sorting the intervals by start time removes that cost. Once the list is in start order, any interval can only overlap ones that come after it and begin before it ends, so a single left-to-right pass is enough to merge, count, or detect collisions.\n\nSorting by start is the standard first line of almost every interval solution, and the problems below all lean on it.\n\nThat gives the template every interval problem in this section builds on: sort by start, then sweep once, comparing each interval against the last one you kept.\n\n\n:::note[Input]\n`[[1,3], [8,10], [2,6], [4,5], [10,12]]`\n:::\n\n:::note[After sort]\n`[[1,3], [2,6], [4,5], [8,10], [10,12]]`\n:::\n\n```python\n# Time: O(n log n)\n# Space: O(n)\ndef interval_pattern(intervals):\n # 1. Sort by start time\n intervals.sort(key=lambda x: x[0])\n result = []\n for start, end in intervals:\n # 2. Overlap with the last kept interval? start <= last end\n if result and start <= result[-1][1]:\n # Merge: extend the end of the last interval\n result[-1][1] = max(result[-1][1], end)\n else:\n # 3. No overlap: keep this interval as-is\n result.append([start, end])\n return result\n```\n\n\n\n | i | `[start, end]` | `result[-1]` | `start <= result[-1][1]`? | Action | `result` after |\n |---|---|---|---|---|---|\n | 0 | `[1,3]` | — | — (empty) | append | `[[1,3]]` |\n | 1 | `[2,6]` | `[1,3]` | `2 <= 3` ✅ | end = `max(3,6)` = 6 | `[[1,6]]` |\n | 2 | `[4,5]` | `[1,6]` | `4 <= 6` ✅ | end = `max(6,5)` = 6 | `[[1,6]]` |\n | 3 | `[8,10]` | `[1,6]` | `8 <= 6` ❌ | append | `[[1,6], [8,10]]` |\n | 4 | `[10,12]` | `[8,10]` | `10 <= 10` ✅ | end = `max(10,12)` = 12 | `[[1,6], [8,12]]` |\n\n\n :::tip[Output]\n `[[1,6], [8,12]]`\n - **Row 2:** `[4,5]` sits inside `[1,6]`. Setting `end = 5` without `max` would cut the interval short. `max` keeps 6.\n - **Row 4:** `[8,10]` and `[10,12]` only touch at 10. The `<=` check merges them. With `<`, you would get two intervals.\n :::\n\n\n\n\n## Insert into a sorted list\n\nSometimes the list is already sorted and has no overlaps, and you must add one new interval. You could append it, sort, and run the template. That works, but it pays `O(n log n)` for a sort you do not need.\n\nA sorted list with no overlaps splits into three parts around the new interval, in this order:\n\n1. Intervals that end **before** the new one starts. Keep them as they are.\n2. Intervals that **overlap** the new one. Merge each into it with `[min, max]`.\n3. Intervals that start **after** the new one ends. Keep them as they are.\n\nWalk the list once and handle each part in turn. No sort, so the cost drops to `O(n)`.\n\n:::note[Intervals]\n`[[1,2], [3,5], [6,7], [8,10], [12,16]]`\n:::\n\n:::note[New interval]\n`[4,8]`\n:::\n\n```python\n# Time: O(n)\n# Space: O(n)\ndef insert_interval(intervals, new_interval):\n result = []\n i, n = 0, len(intervals)\n start, end = new_interval\n\n # 1. Ends before new starts: keep\n while i < n and intervals[i][1] < start:\n result.append(intervals[i])\n i += 1\n\n # 2. Overlaps new: grow new to cover it\n while i < n and intervals[i][0] <= end:\n start = min(start, intervals[i][0])\n end = max(end, intervals[i][1])\n i += 1\n result.append([start, end])\n\n # 3. Starts after new ends: keep\n result.extend(intervals[i:])\n return result\n```\n\n\n\n\n | i | interval | Part | Check | Action | `[start, end]` | `result` after |\n |---|---|---|---|---|---|---|\n | 0 | `[1,2]` | 1 | `2 < 4` ✅ | keep | `[4,8]` | `[[1,2]]` |\n | 1 | `[3,5]` | 1 | `5 < 4` ❌ | go to part 2 | `[4,8]` | `[[1,2]]` |\n | 1 | `[3,5]` | 2 | `3 <= 8` ✅ | start = `min(4,3)` = 3 | `[3,8]` | `[[1,2]]` |\n | 2 | `[6,7]` | 2 | `6 <= 8` ✅ | end = `max(8,7)` = 8 | `[3,8]` | `[[1,2]]` |\n | 3 | `[8,10]` | 2 | `8 <= 8` ✅ | end = `max(8,10)` = 10 | `[3,10]` | `[[1,2]]` |\n | 4 | `[12,16]` | 2 | `12 <= 10` ❌ | append new | `[3,10]` | `[[1,2], [3,10]]` |\n | 4 | `[12,16]` | 3 | — | extend rest | — | `[[1,2], [3,10], [12,16]]` |\n\n :::tip[Output]\n `[[1,2], [3,10], [12,16]]`\n - **Row i=1:** The same interval shows up twice. The part 1 check fails, so that loop stops, and part 2 reads the same interval again. `i` does not move.\n - **Row i=3:** `[8,10]` only touches `[3,8]` at 8. The `<=` merges them, since one shared point counts as an overlap.\n - **Part 1 uses `<`, part 2 uses `<=`:** An interval that ends exactly at `start` touches the new interval. It must fail part 1 so part 2 can merge it.\n :::\n\n\n\n:::warning\nIf the input is already sorted, do not sort again. Interviewers add \"sorted\" to the problem on purpose. Name the `O(n log n)` cost of re-sorting before they do, then offer the `O(n)` three-part walk.\n:::\n\n### Footnote\n\nThe positive overlap test comes straight from De Morgan's law. Negating `(a.end < b.start)` or `(b.end < a.start)` gives `(a.end >= b.start)` and `(b.end >= a.start)`, which is the `a.start <= b.end` and `b.start <= a.end` condition rewritten.\n"},"/intervals/insert-interval":{"mdx":"---\ntitle: '57. Insert Interval'\ndescription: You are given an array of non-overlapping intervals intervals where intervals[i] = [starti, endi] represent the start and the end of the i^th interval and intervals is sorted in ascending order by starti. You are also given an interval newInterval = [start, end] that represents the start and end of another interval\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\nissue: \"https://github.com/prdlk/leetcode/issues/181\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 39.1 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Insert Interval'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `intervals = [[1,3],[6,9]], newInterval = [2,5]`\n- Output: `[[1,5],[6,9]]`\n\n### Example 2:\n- Input: `intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]`\n- Output: `[[1,2],[3,10],[12,16]]`\n- Explanation: Because the new interval `[4,8]` overlaps with [3,5],[6,7],[8,10].\n\n### Constraints:\n\n- `0 <= intervals.length <= 10^4`\n- `intervals[i].length == 2`\n- `0 <= starti <= endi <= 10^5`\n- intervals is sorted by starti in ascending order.\n- `newInterval.length == 2`\n- `0 <= start <= end <= 10^5`\n\n## Solution\n\n```py\nclass Solution:\n def insert(\n self, intervals: list[list[int]], newInterval: list[int]\n ) -> list[list[int]]:\n result = []\n i, n = 0, len(intervals)\n start, end = newInterval\n\n # Everything before\n while i < n and intervals[i][1] < start:\n result.append(intervals[i])\n i += 1\n\n # Everything merged\n while i < n and intervals[i][0] <= end:\n start = min(start, intervals[i][0])\n end = max(end, intervals[i][1])\n i += 1\n result.append([start, end])\n\n # Everything after\n result.extend(intervals[i:])\n return result\n```\n"},"/intervals/merge-intervals":{"mdx":"---\ntitle: '56. Merge Intervals'\ndescription: Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Sorting\", slug: \"sorting\" }\n - { name: \"Quicksort\", slug: \"quicksort\" }\nissue: \"https://github.com/prdlk/leetcode/issues/182\"\ncompanies:\n - { name: \"Palo Alto Networks\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 75.8 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 68.6 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 100 }\n - { name: \"Coupang\", period: \"Three Months\", frequency: 100 }\n - { name: \"IBM\", period: \"Three Months\", frequency: 100 }\n - { name: \"MongoDB\", period: \"Three Months\", frequency: 100 }\n - { name: \"Atlassian\", period: \"Three Months\", frequency: 89.6 }\n - { name: \"Salesforce\", period: \"Three Months\", frequency: 88 }\n - { name: \"Yandex\", period: \"Three Months\", frequency: 86.7 }\n - { name: \"Visa\", period: \"Three Months\", frequency: 80.9 }\n - { name: \"Goldman Sachs\", period: \"Three Months\", frequency: 57 }\n - { name: \"American Express\", period: \"Six Months\", frequency: 100 }\n - { name: \"Expedia\", period: \"Six Months\", frequency: 100 }\n - { name: \"General Motors\", period: \"Six Months\", frequency: 100 }\n - { name: \"Nextdoor\", period: \"Six Months\", frequency: 100 }\n - { name: \"Ozon\", period: \"Six Months\", frequency: 100 }\n - { name: \"Ripple\", period: \"Six Months\", frequency: 100 }\n - { name: \"Tesco\", period: \"Six Months\", frequency: 100 }\n - { name: \"Morgan Stanley\", period: \"Six Months\", frequency: 83.1 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 81.4 }\n - { name: \"Tesla\", period: \"Six Months\", frequency: 80.9 }\n - { name: \"Zoho\", period: \"Six Months\", frequency: 79.6 }\n - { name: \"eBay\", period: \"Six Months\", frequency: 75.2 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 64.9 }\n - { name: \"Capital One\", period: \"Six Months\", frequency: 64.2 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\nsidebar:\n label: 'Merge Intervals'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `intervals = [[1,3],[2,6],[8,10],[15,18]]`\n- Output: `[[1,6],[8,10],[15,18]]`\n- Explanation: Since `intervals [1,3]` and `[2,6]` overlap, merge them into `[1,6]`.\n\n### Example 2:\n- Input: `intervals = [[1,4],[4,5]]`\n- Output: `[[1,5]]`\n- Explanation: Intervals `[1,4]` and `[4,5]` are considered overlapping.\n\n### Example 3:\n- Input: `intervals = [[4,7],[1,4]]`\n- Output: `[[1,7]]`\n- Explanation: Intervals `[1,4]` and `[4,7]` are considered overlapping.\n\n### Constraints:\n\n- `1 <= intervals.length <= 10^4`\n- `intervals[i].length == 2`\n- `0 <= starti <= endi <= 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def merge(self, intervals: list[list[int]]) -> list[list[int]]:\n intervals.sort(key=lambda x: x[0])\n result = []\n\n for start, end in intervals:\n if result and start <= result[-1][1]:\n result[-1][1] = max(result[-1][1], end)\n else:\n result.append([start, end])\n\n return result\n```\n"},"/intervals/non-overlapping-intervals":{"mdx":"---\ntitle: '435. Non-overlapping Intervals'\ndescription: Given an array of intervals intervals where intervals[i] = [starti, endi], return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Greedy\", slug: \"greedy\" }\n - { name: \"Sorting\", slug: \"sorting\" }\nissue: \"https://github.com/prdlk/leetcode/issues/183\"\ncompanies:\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Grammarly\", period: \"Three Months\", frequency: 100 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 60.1 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Non-overlapping Intervals'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `intervals = [[1,2],[2,3],[3,4],[1,3]]`\n- Output: `1`\n- Explanation: `[1,3]` can be removed and the rest of the `intervals` are non-overlapping.\n\n### Example 2:\n- Input: `intervals = [[1,2],[1,2],[1,2]]`\n- Output: `2`\n- Explanation: You need to remove two `[1,2]` to make the rest of the `intervals` non-overlapping.\n\n### Example 3:\n- Input: `intervals = [[1,2],[2,3]]`\n- Output: `0`\n- Explanation: You don't need to remove any of the `intervals` since they're already non-overlapping.\n\n### Constraints:\n\n- `1 <= intervals.length <= 10^5`\n- `intervals[i].length == 2`\n- `-5 * 10^4 <= starti < endi <= 5 * 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def eraseOverlapIntervals(self, intervals: list[list[int]]) -> int:\n intervals.sort(key=lambda x: x[0])\n result = []\n\n for start, end in intervals:\n # Use '<' to avoid intervals which touch\n if result and start < result[-1][1]:\n result[-1][1] = min(result[-1][1], end)\n else:\n result.append([start, end])\n\n # Difference between original and result is to remove\n return len(intervals) - len(result)\n```\n"},"/keywords":{"mdx":"---\ntitle: Keywords\ndescription: Coding problems rarely tell you which algorithm to use, but the wording usually leaks it. \"K-th largest\" hints at a heap. \"Shortest path\" in an unweighted graph hints at BFS.\nicon: map\n---\n\nEach entry below names the keyword, the algorithm it points to, and a one-line reason. Where a keyword has more than one possible technique, each option is listed with the sub-signal that picks it. Techniques you haven't studied yet are covered later in the course.\n\n## \"Top K\"\n\nHeap — track the K-item boundary in O(n log K) instead of sorting all n. K Closest Points\n\n## \"Sorted\" / \"rotated sorted\" / \"in O(log n)\"\n\nBinary Search — halve the search space at each step using order. Works on any monotonic predicate, not just literal arrays. Binary Search\n\n## \"How many ways...\"\n\nCounting distinct outcomes — choose by what the input looks like.\n\n- DFS, when choices form a tree of decisions. Decode Ways\n- DP, when subproblems overlap on a grid or sequence. Robot Paths\n\n## \"Substring\"\n\nSliding Window — contiguous slices extend and shrink in O(1) at each step. Longest Substring Without Repeating Characters\n\n## \"Prefix\" / \"autocomplete\" / \"dictionary lookup\" / \"starts with\"\n\nTrie — share storage for common prefixes; lookup runs in O(length of word) regardless of dictionary size. Implement Trie\n\n## \"Palindrome\"\n\nPalindromes mirror around a center — choose by whether you're verifying or constructing.\n\n- Two Pointers, to verify a single string. Valid Palindrome\n- DFS, to enumerate every valid partition. Palindrome Partitioning\n- DP, to minimize cuts or count partitions. Palindrome Partitioning II\n\n## \"Tree\"\n\nOne question decides everything: do you care about depth, or just need to visit every node?\n\n- BFS, for level-order, shallowest depth, or \"right-side view\". Binary Tree Level-Order Traversal\n- DFS, for sums, heights, paths — anything not level-related. Max Depth\n\n## \"Parentheses\"\n\nStack — brackets close in reverse order, last opened first closed (LIFO). Valid Parentheses\n\n## \"Next greater\" / \"next smaller\" / \"warmer day\"\n\nMonotonic Stack — keep candidates in stack order so the answer for each element pops out in O(1) amortized. Next Greater Element II\n\n## \"Subarray\"\n\nContiguous slices, but the right tool depends on what you're computing.\n\n- Sliding Window, for fixed size or a monotonic constraint. Subarray Sum Fixed\n- Prefix Sum, for range-sum queries. Subarray Sum\n- Hashmap of prefix sums, for sum equals a target. Continuous Subarray Sum\n\n## \"Max subarray\"\n\nGreedy (Kadane's) — at each index, extend the run or restart; the choice is local. Kadane's Algorithm\n\n## \"Two sum / K sum\"\n\nTwo Pointers on a sorted array — each move strictly raises or lowers the sum. Two Sum\n\n## \"Max/longest sequence\"\n\n\"Longest\" usually means each position depends on earlier ones — except when a fixed window is involved.\n\n- DP / DFS with memoization, when a position depends on earlier positions. Longest Increasing Subsequence\n- Monotonic Deque, for max within a sliding window. Sliding Window Maximum\n\n## \"Minimum/Shortest\"\n\nThree very different problems wear the same word.\n\n- BFS, for fewest edges in an unweighted graph. Shortest Path\n- Dijkstra, for shortest path with non-negative edge weights. Dijkstra's Algorithm\n- DP / DFS, for cumulative cost on a grid or sequence. Minimal Path Sum\n\n## \"Partition/split\"\n\nDFS — each split point is a recursive choice; memoize if suffixes repeat. Decode Ways\n\n## \"Subsequence\"\n\nDP / DFS with memoization — pick-or-skip at each index, with overlapping subproblems. Longest Increasing Subsequence\n\n## \"All combinations / permutations / subsets\" / \"generate every\"\n\nBacktracking — DFS that records a partial solution, recurses, then undoes the choice on the way back up. Permutations, Subsets\n\n## \"Matrix\"\n\nA grid is a graph. Connectivity questions are BFS/DFS; optimization questions are DP.\n\n- BFS / DFS, for connectivity, flood-fill, or region counting. Flood Fill, Number of Islands\n- DP, for optimization where each cell builds on neighbors. Maximal Square\n\n## \"Jump\"\n\nGreedy when local-optimal is provably global; DP otherwise.\n\n- Greedy, when \"always reach as far as possible\" works (typically reachability). Jump Game\n- DP, when counting jumps or greedy fails. Jump Game II\n\n## \"Game\"\n\nDP on game states — \"can the player to move force a win?\" recurses with overlap. Divisor Game\n\n## \"Connected component\"\n\nUnion Find — near-O(1) union and find beat re-running BFS after each edge. Use BFS or DFS instead when the graph is built once and you only traverse a few times. Number of Connected Components\n\n## \"Schedule\" / \"prerequisites\" / \"build order\" / \"course\"\n\nTopological Sort (Kahn's BFS or DFS post-order) — directed dependencies must be linearized so every edge points forward. Detects cycles as a side effect. Course Schedule\n\n## \"Transitive relationship\"\n\nIf A relates to B and B relates to C means A relates to C, the relation is a graph in disguise. Items become nodes, relations become edges, and \"are these two related?\" becomes \"are they in the same component?\"\n\n- BFS, to answer a single query by traversing on the fly. Word Ladder\n- BFS or Union Find, for many queries on a fixed relation set. Sentence Similarity\n- BFS or Union Find, for numbers with divisional relationships. Evaluate Division\n\n## \"Interval\"\n\nGreedy after sorting — by start (merge) or by end (fit-in), then one pass. Interval Pattern\n"},"/linked-list":{"mdx":"---\ntitle: Linked List\ndescription: 'Each node points to the next node, and the pointers give the path through the data.'\nhidden: true\n---\n"},"/linked-list/linked-list-cycle":{"mdx":"---\ntitle: '141. Linked List Cycle'\ndescription: Given head, the head of a linked list, determine if the linked list has a cycle in it\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Floyd's Cycle Finding Algorithm\", slug: \"floyds-cycle-finding-algorithm\" }\nvideo: \"gBTe7lFR3vc\"\nissue: \"https://github.com/prdlk/leetcode/issues/79\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Nvidia\", period: \"Three Months\", frequency: 87.7 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Linked List Cycle'\n badge: 'Easy'\n---\n\n::::warning\nCan you solve it using O(1) (i.e. constant) memory?\n::::\n\n### Example 1:\n- Input: `head = [3,2,0,-4], pos = 1`\n- Output: `true`\n- Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).\n\n### Example 2:\n- Input: `head = [1,2], pos = 0`\n- Output: `true`\n- Explanation: There is a cycle in the linked list, where the tail connects to the 0th node.\n\n### Example 3:\n- Input: `head = [1], pos = -1`\n- Output: `false`\n- Explanation: There is no cycle in the linked list.\n\n### Constraints:\n\n- The number of the nodes in the list is in the range [0, 10^4].\n- `-10^5 <= Node.val <= 10^5`\n- pos is -1 or a valid index in the linked-list.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"hasCycle(head)\"]) --> I[\"fast = slow = head\"]\n I --> W{\"fast and fast.next?\"}\n W -- no --> E([\"return False — ran off the end, no cycle\"])\n W -- yes --> A[\"fast = fast.next.next — two steps\"]\n A --> B[\"slow = slow.next — one step\"]\n B --> Q{\"fast is slow?\"}\n Q -- yes --> R([\"return True — the gap closed, so it loops\"])\n Q -- no --> W\n```\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, x):\n# self.val = x\n# self.next = None\n\n\nclass Solution:\n def hasCycle(self, head: Optional[ListNode]) -> bool:\n fast = slow = head\n\n while fast and fast.next:\n fast = fast.next.next\n slow = slow.next\n if fast is slow:\n return True\n return False\n```\n"},"/linked-list/merge-two-sorted-lists":{"mdx":"---\ntitle: '21. Merge Two Sorted Lists'\ndescription: You are given the heads of two sorted linked lists list1 and list2\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Recursion\", slug: \"recursion\" }\nvideo: \"XIdigk956u0\"\nissue: \"https://github.com/prdlk/leetcode/issues/78\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Accenture\", period: \"Six Months\", frequency: 75 }\nsidebar:\n label: 'Merge Two Sorted Lists'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `list1 = [1,2,4], list2 = [1,3,4]`\n- Output: `[1,1,2,3,4,4]`\n\n### Example 2:\n- Input: `list1 = [], list2 = []`\n- Output: `[]`\n\n### Example 3:\n- Input: `list1 = [], list2 = [0]`\n- Output: `[0]`\n\n### Constraints:\n\n- The number of nodes in both lists is in the range [0, 50].\n- `-100 <= Node.val <= 100`\n- Both list1 and list2 are sorted in non-decreasing order.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"mergeTwoLists(list1, list2)\"]) --> G1{\"list1 empty?\"}\n G1 -- yes --> X1([\"return list2\"])\n G1 -- no --> G2{\"list2 empty?\"}\n G2 -- yes --> X2([\"return list1\"])\n G2 -- no --> H[\"head = the smaller first node; advance that list\"]\n H --> C[\"current = head\"]\n C --> W{\"list1 and list2 both non-empty?\"}\n W -- yes --> P[\"current.next = the smaller node; advance that list; current = current.next\"]\n P --> W\n W -- no --> T[\"current.next = list1 or list2 — append the leftover tail\"]\n T --> E([\"return head\"])\n```\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def mergeTwoLists(\n self, list1: Optional[ListNode], list2: Optional[ListNode]\n ) -> Optional[ListNode]:\n\n if not list1:\n return list2\n if not list2:\n return list1\n\n if list1.val < list2.val:\n head = list1\n list1 = list1.next\n else:\n head = list2\n list2 = list2.next\n\n current = head\n while list1 and list2:\n if list1.val < list2.val:\n current.next = list1\n list1 = list1.next\n else:\n current.next = list2\n list2 = list2.next\n current = current.next\n\n current.next = list1 or list2\n return head\n```\n"},"/linked-list/middle-of-the-linked-list":{"mdx":"---\ntitle: '876. Middle of the Linked List'\ndescription: Given the head of a singly linked list, return the middle node of the linked list\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\nissue: \"https://github.com/prdlk/leetcode/issues/82\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 49.8 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 39.1 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 60.1 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 37.9 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Middle of the Linked List'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `head = [1,2,3,4,5]`\n- Output: `[3,4,5]`\n- Explanation: The middle node of the list is node `3`.\n\n### Example 2:\n- Input: `head = [1,2,3,4,5,6]`\n- Output: `[4,5,6]`\n- Explanation: Since the list has two middle nodes with values `3` and `4`, we return the second one.\n\n### Constraints:\n\n- The number of nodes in the list is in the range [1, 100].\n- `1 <= Node.val <= 100`\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def middleNode(self, head: ListNode | None) -> ListNode | None:\n slow = fast = head\n while fast and fast.next:\n fast = fast.next.next\n slow = slow.next\n\n return slow\n```\n"},"/linked-list/remove-duplicates-from-sorted-list-ii":{"mdx":"---\ntitle: '82. Remove Duplicates from Sorted List II'\ndescription: You are given the head of a sorted linked list\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\nissue: \"https://github.com/prdlk/leetcode/issues/84\"\ncompanies:\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 34.2 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\nsidebar:\n label: 'Remove Duplicates from Sorted List II'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `head = [1,2,3,3,4,4,5]`\n- Output: `[1,2,5]`\n\n### Example 2:\n- Input: `head = [1,1,1,2,3]`\n- Output: `[2,3]`\n\n### Constraints:\n\n- The number of nodes in the list is in the range [0, 300].\n- `-100 <= Node.val <= 100`\n- The list is guaranteed to be sorted in ascending order.\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def deleteDuplicates(self, head: ListNode | None) -> ListNode | None:\n sentinel = ListNode(0, head)\n pred = sentinel\n\n while head:\n if head.next and head.val == head.next.val:\n while head.next and head.val == head.next.val:\n head = head.next\n\n pred.next = head.next\n else:\n pred = pred.next\n\n head = head.next\n\n return sentinel.next\n```\n"},"/linked-list/remove-nth-node-from-end-of-list":{"mdx":"---\ntitle: '19. Remove Nth Node From End of List'\ndescription: Given the head of a linked list, remove the n^th node from the end of the list and return its head\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\nissue: \"https://github.com/prdlk/leetcode/issues/80\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 51.1 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Remove Nth Node From End of List'\n badge: 'Medium'\n---\n\n::::warning\nCould you do this in one pass?\n::::\n\n### Example 1:\n- Input: `head = [1,2,3,4,5], n = 2`\n- Output: `[1,2,3,5]`\n\n### Example 2:\n- Input: `head = [1], n = 1`\n- Output: `[]`\n\n### Example 3:\n- Input: `head = [1,2], n = 1`\n- Output: `[1]`\n\n### Constraints:\n\n- The number of nodes in the list is sz.\n- `1 <= sz <= 30`\n- `0 <= Node.val <= 100`\n- `1 <= n <= sz`\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def removeNthFromEnd(self, head: ListNode | None, n: int) -> ListNode | None:\n dummy = ListNode(0)\n dummy.next = head\n\n fast = dummy\n for _ in range(n):\n if fast.next is None:\n return head\n fast = fast.next\n\n slow = dummy\n while fast.next is not None:\n slow = slow.next\n fast = fast.next\n\n slow.next = slow.next.next\n\n return dummy.next\n```\n"},"/linked-list/reorder-list":{"mdx":"---\ntitle: '143. Reorder List'\ndescription: 'You are given the head of a singly linked-list. The list can be represented as:'\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Recursion\", slug: \"recursion\" }\nissue: \"https://github.com/prdlk/leetcode/issues/81\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\nsidebar:\n label: 'Reorder List'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `head = [1,2,3,4]`\n- Output: `[1,4,2,3]`\n\n### Example 2:\n- Input: `head = [1,2,3,4,5]`\n- Output: `[1,5,2,4,3]`\n\n### Constraints:\n\n- The number of nodes in the list is in the range [1, 5 * 10^4].\n- `1 <= Node.val <= 1000`\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def reorderList(self, head: ListNode | None) -> None:\n # Find middle\n slow, fast = head, head.next\n while fast and fast.next:\n slow = slow.next\n fast = fast.next.next\n\n # Reverse second half\n second = slow.next\n prev = slow.next = None\n while second:\n tmp = second.next\n second.next = prev\n prev = second\n second = tmp\n\n # merge two halfs\n first, second = head, prev\n while second:\n tmp1, tmp2 = first.next, second.next\n first.next = second\n second.next = tmp1\n first, second = tmp1, tmp2\n```\n"},"/linked-list/reverse-linked-list":{"mdx":"---\ntitle: '206. Reverse Linked List'\ndescription: Given the head of a singly linked list, reverse the list, and return the reversed list\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\n - { name: \"Recursion\", slug: \"recursion\" }\nvideo: \"G0_I-ZF0S38\"\nissue: \"https://github.com/prdlk/leetcode/issues/77\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Nokia\", period: \"Three Months\", frequency: 100 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 78.4 }\nsidebar:\n label: 'Reverse Linked List'\n badge: 'Easy'\n---\n\n::::warning\nA linked list can be reversed either iteratively or recursively. Could you implement both?\n::::\n\n### Example 1:\n- Input: `head = [1,2,3,4,5]`\n- Output: `[5,4,3,2,1]`\n\n### Example 2:\n- Input: `head = [1,2]`\n- Output: `[2,1]`\n\n### Example 3:\n- Input: `head = []`\n- Output: `[]`\n\n### Constraints:\n\n- The number of nodes in the list is the range [0, 5000].\n- `-5000 <= Node.val <= 5000`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"reverseList(head)\"]) --> I[\"prev = None, curr = head\"]\n I --> W{\"curr?\"}\n W -- no --> E([\"return prev — the old tail is the new head\"])\n W -- yes --> A[\"next_ = curr.next — save it before overwriting\"]\n A --> B[\"curr.next = prev — flip the link\"]\n B --> C[\"prev = curr; curr = next_ — step forward\"]\n C --> W\n```\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n prev = None\n curr = head\n while curr:\n next_ = curr.next\n curr.next = prev\n prev = curr\n curr = next_\n return prev\n```\n"},"/linked-list/reverse-linked-list-ii":{"mdx":"---\ntitle: '92. Reverse Linked List II'\ndescription: Given the head of a singly linked list and two integers left and right where left <= right, reverse the nodes of the list from position left to position right, and return the reversed list\nicon: dot\ntopics:\n - { name: \"Linked List\", slug: \"linked-list\" }\nissue: \"https://github.com/prdlk/leetcode/issues/83\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Google\", period: \"Three Months\", frequency: 28.8 }\nsidebar:\n label: 'Reverse Linked List II'\n badge: 'Medium'\n---\n\n::::warning\nCould you do it in one pass?\n::::\n\n### Example 1:\n- Input: `head = [1,2,3,4,5], left = 2, right = 4`\n- Output: `[1,4,3,2,5]`\n\n### Example 2:\n- Input: `head = [5], left = 1, right = 1`\n- Output: `[5]`\n\n### Constraints:\n\n- The number of nodes in the list is n.\n- `1 <= n <= 500`\n- `-500 <= Node.val <= 500`\n- `1 <= left <= right <= n`\n\n## Solution\n\n```py\n# Definition for singly-linked list.\n# class ListNode:\n# def __init__(self, val=0, next=None):\n# self.val = val\n# self.next = next\nclass Solution:\n def reverseBetween(\n self, head: ListNode | None, left: int, right: int\n ) -> ListNode | None:\n cur, prev = head, None\n while left > 1:\n prev = cur\n cur = cur.next\n left, right = left - 1, right - 1\n\n tail, con = cur, prev\n while right:\n third = cur.next\n cur.next = prev\n prev = cur\n cur = third\n right -= 1\n\n if con:\n con.next = prev\n else:\n head = prev\n\n tail.next = cur\n return head\n```\n"},"/matrix-index-math":{"mdx":"---\ntitle: Matrix Index Math\ndescription: 'A two-dimensional grid is read as a flat array through a formula, and the neighbors are found by arithmetic.'\nhidden: true\n---\n"},"/matrix-index-math/rotate-image":{"mdx":"---\ntitle: '48. Rotate Image'\ndescription: You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise)\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nvideo: \"fMSJSS7eO1w\"\nissue: \"https://github.com/prdlk/leetcode/issues/91\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Three Months\", frequency: 51.1 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 64.8 }\n - { name: \"Capital One\", period: \"Six Months\", frequency: 64.2 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 60.1 }\nsidebar:\n label: 'Rotate Image'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `matrix = [[1,2,3],[4,5,6],[7,8,9]]`\n- Output: `[[7,4,1],[8,5,2],[9,6,3]]`\n\n### Example 2:\n- Input: `matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]`\n- Output: `[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]`\n\n### Constraints:\n\n- `n == matrix.length == matrix[i].length`\n- `1 <= n <= 20`\n- `-1000 <= matrix[i][j] <= 1000`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"rotate(matrix)\"]) --> N[\"n = len(matrix)\"]\n N --> F{\"more r in range(n)?\"}\n F -- yes --> G{\"more c in range(r + 1, n)?\"}\n G -- yes --> T[\"swap matrix[r][c] and matrix[c][r] — transpose across the diagonal\"]\n T --> G\n G -- no --> F\n F -- no --> H{\"more r in range(n)?\"}\n H -- yes --> R[\"matrix[r].reverse() — transpose then mirror is a clockwise turn\"]\n R --> H\n H -- no --> E([\"return None — rotated in place\"])\n```\n\n## Solution\n\n```py\nclass Solution:\n def rotate(self, matrix: List[List[int]]) -> None:\n n = len(matrix)\n for r in range(n):\n for c in range(r + 1, n):\n matrix[r][c], matrix[c][r] = matrix[c][r], matrix[r][c]\n\n for r in range(n):\n matrix[r].reverse()\n```\n"},"/matrix-index-math/set-matrix-zeroes":{"mdx":"---\ntitle: '73. Set Matrix Zeroes'\ndescription: Given an m x n integer matrix matrix, if an element is 0, set its entire row and column to 0's\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nvideo: \"T41rL0L3Pnw\"\nissue: \"https://github.com/prdlk/leetcode/issues/93\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 48.7 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Google\", period: \"Three Months\", frequency: 32.7 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\nsidebar:\n label: 'Set Matrix Zeroes'\n badge: 'Medium'\n---\n\n::::warning\nYou must do it in place.\n::::\n\n### Example 1:\n- Input: `matrix = [[1,1,1],[1,0,1],[1,1,1]]`\n- Output: `[[1,0,1],[0,0,0],[1,0,1]]`\n\n### Example 2:\n- Input: `matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]`\n- Output: `[[0,0,0,0],[0,4,5,0],[0,3,1,0]]`\n\n### Constraints:\n\n- `m == matrix.length`\n- `n == matrix[0].length`\n- `1 <= m, n <= 200`\n- `-2^31 <= matrix[i][j] <= 2^31 - 1`\n- A straightforward solution using O(mn) space is probably a bad idea.\n- A simple improvement uses O(m + n) space, but still not the best solution.\n- Could you devise a constant space solution?\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"setZeroes(matrix)\"]) --> I[\"m = len(matrix), n = len(matrix[0])\"]\n I --> Z[\"row0_zero = any(matrix[0][c] == 0), col0_zero = any(matrix[r][0] == 0) — remember before they become markers\"]\n Z --> F{\"more r in range(1, m)?\"}\n F -- yes --> G{\"more c in range(1, n)?\"}\n G -- yes --> Q{\"matrix[r][c] == 0?\"}\n Q -- yes --> M[\"matrix[r][0] = 0, matrix[0][c] = 0 — row 0 and column 0 are the marker lists\"]\n M --> G\n Q -- no --> G\n G -- no --> F\n F -- no --> H{\"more r in range(1, m)?\"}\n H -- yes --> J{\"more c in range(1, n)?\"}\n J -- yes --> K{\"matrix[r][0] == 0 or matrix[0][c] == 0?\"}\n K -- yes --> W[\"matrix[r][c] = 0\"]\n W --> J\n K -- no --> J\n J -- no --> H\n H -- no --> A{\"row0_zero?\"}\n A -- yes --> B[\"matrix[0][c] = 0 for c in range(n)\"]\n B --> C{\"col0_zero?\"}\n A -- no --> C\n C -- yes --> D[\"matrix[r][0] = 0 for r in range(m)\"]\n D --> E([\"return None — zeroed in place\"])\n C -- no --> E\n```\n\n## Solution\n\n```py\nclass Solution:\n def setZeroes(self, matrix: List[List[int]]) -> None:\n \"\"\"\n Do not return anything, modify matrix in-place instead.\n \"\"\"\n m, n = len(matrix), len(matrix[0])\n\n # 1. remember if row 0 or column 0 have their own zeros\n row0_zero = any(matrix[0][c] == 0 for c in range(n))\n col0_zero = any(matrix[r][0] == 0 for r in range(m))\n\n # 2. use row 0 and column 0 as marker lists\n for r in range(1, m):\n for c in range(1, n):\n if matrix[r][c] == 0:\n matrix[r][0] = 0\n matrix[0][c] = 0\n\n # 3. zero the inner cells from the markers\n for r in range(1, m):\n for c in range(1, n):\n if matrix[r][0] == 0 or matrix[0][c] == 0:\n matrix[r][c] = 0\n\n # 4. handle row 0 and column 0 last\n if row0_zero:\n for c in range(n):\n matrix[0][c] = 0\n if col0_zero:\n for r in range(m):\n matrix[r][0] = 0\n```\n"},"/matrix-index-math/spiral-matrix":{"mdx":"---\ntitle: '54. Spiral Matrix'\ndescription: Given an m x n matrix, return all elements of the matrix in spiral order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Matrix\", slug: \"matrix\" }\n - { name: \"Simulation\", slug: \"simulation\" }\nvideo: \"BJnMZNwUk1M\"\nissue: \"https://github.com/prdlk/leetcode/issues/92\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 46 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Capital One\", period: \"Six Months\", frequency: 73.8 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 69.7 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 64.8 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 56.2 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 55.2 }\nsidebar:\n label: 'Spiral Matrix'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `matrix = [[1,2,3],[4,5,6],[7,8,9]]`\n- Output: `[1,2,3,6,9,8,7,4,5]`\n\n### Example 2:\n- Input: `matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]`\n- Output: `[1,2,3,4,8,12,11,10,9,5,6,7]`\n\n### Constraints:\n\n- `m == matrix.length`\n- `n == matrix[i].length`\n- `1 <= m, n <= 10`\n- `-100 <= matrix[i][j] <= 100`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"spiralOrder(matrix)\"]) --> I[\"res = [], top = 0, bottom = len(matrix) - 1, left = 0, right = len(matrix[0]) - 1\"]\n I --> W{\"top <= bottom and left <= right?\"}\n W -- no --> E([\"return res\"])\n W -- yes --> T[\"append matrix[top][c] for c in left..right, then top += 1 — top row, shrink from above\"]\n T --> R[\"append matrix[r][right] for r in top..bottom, then right -= 1 — right column\"]\n R --> B{\"top <= bottom?\"}\n B -- yes --> C[\"append matrix[bottom][c] for c in right down to left, then bottom -= 1 — bottom row\"]\n C --> L{\"left <= right?\"}\n B -- no --> L\n L -- yes --> D[\"append matrix[r][left] for r in bottom down to top, then left += 1 — left column\"]\n D --> W\n L -- no --> W\n```\n\n## Solution\n\n```py\nclass Solution:\n def spiralOrder(self, matrix: List[List[int]]) -> List[int]:\n res = []\n top, bottom = 0, len(matrix) - 1\n left, right = 0, len(matrix[0]) - 1\n\n while top <= bottom and left <= right:\n # 1. Top Row\n for c in range(left, right + 1):\n res.append(matrix[top][c])\n top += 1\n\n # 2. Right Column\n for r in range(top, bottom + 1):\n res.append(matrix[r][right])\n right -= 1\n\n # 3. Bottom Row\n if top <= bottom:\n for c in range(right, left - 1, -1):\n res.append(matrix[bottom][c])\n bottom -= 1\n\n # 4. Left Column\n if left <= right:\n for r in range(bottom, top - 1, -1):\n res.append(matrix[r][left])\n left += 1\n\n return res\n```\n"},"/matrix-index-math/valid-sudoku":{"mdx":"---\ntitle: '36. Valid Sudoku'\ndescription: 'Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:'\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nissue: \"https://github.com/prdlk/leetcode/issues/94\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 69 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Confluent\", period: \"Six Months\", frequency: 100 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'Valid Sudoku'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `board = [[\"5\",\"3\",\".\",\".\",\"7\",\".\",\".\",\".\",\".\"] ,[\"6\",\".\",\".\",\"1\",\"9\",\"5\",\".\",\".\",\".\"] ,[\".\",\"9\",\"8\",\".\",\".\",\".\",\".\",\"6\",\".\"] ,[\"8\",\".\",\".\",\".\",\"6\",\".\",\".\",\".\",\"3\"] ,[\"4\",\".\",\".\",\"8\",\".\",\"3\",\".\",\".\",\"1\"] ,[\"7\",\".\",\".\",\".\",\"2\",\".\",\".\",\".\",\"6\"] ,[\".\",\"6\",\".\",\".\",\".\",\".\",\"2\",\"8\",\".\"] ,[\".\",\".\",\".\",\"4\",\"1\",\"9\",\".\",\".\",\"5\"] ,[\".\",\".\",\".\",\".\",\"8\",\".\",\".\",\"7\",\"9\"]]`\n- Output: `true`\n\n### Example 2:\n- Input: `board = [[\"8\",\"3\",\".\",\".\",\"7\",\".\",\".\",\".\",\".\"] ,[\"6\",\".\",\".\",\"1\",\"9\",\"5\",\".\",\".\",\".\"] ,[\".\",\"9\",\"8\",\".\",\".\",\".\",\".\",\"6\",\".\"] ,[\"8\",\".\",\".\",\".\",\"6\",\".\",\".\",\".\",\"3\"] ,[\"4\",\".\",\".\",\"8\",\".\",\"3\",\".\",\".\",\"1\"] ,[\"7\",\".\",\".\",\".\",\"2\",\".\",\".\",\".\",\"6\"] ,[\".\",\"6\",\".\",\".\",\".\",\".\",\"2\",\"8\",\".\"] ,[\".\",\".\",\".\",\"4\",\"1\",\"9\",\".\",\".\",\"5\"] ,[\".\",\".\",\".\",\".\",\"8\",\".\",\".\",\"7\",\"9\"]]`\n- Output: `false`\n- Explanation: Same as Example `1`, except with the `5` in the top left corner being modified to `8`. Since there are two 8's in the top left 3x3 sub-box, it is invalid.\n\n### Constraints:\n\n- `board.length == 9`\n- `board[i].length == 9`\n- board[i][j] is a digit 1-9 or '.'.\n\n## Solution\n\n```py\nimport collections\n\n\nclass Solution:\n def isValidSudoku(self, board: list[list[str]]) -> bool:\n cols = collections.defaultdict(set)\n rows = collections.defaultdict(set)\n squares = collections.defaultdict(set) # (r/3, c/3)\n\n for r in range(9):\n for c in range(9):\n if board[r][c] == \".\":\n continue\n if (\n board[r][c] in rows[r]\n or board[r][c] in cols[c]\n or board[r][c] in squares[(r // 3, c // 3)]\n ):\n return False\n cols[c].add(board[r][c])\n rows[r].add(board[r][c])\n squares[(r // 3, c // 3)].add(board[r][c])\n\n return True\n```\n"},"/monotonic-stack":{"md":"---\ntitle: Monotonic Stack\ndescription: 'A stack keeps its items in sorted order, which finds the next larger or smaller item in one pass.'\nhidden: true\n---\n\n\n[Monotonic Stack](https://www.youtube.com/watch?v=Dq_ObZwTY_Q)\n\nA monotonic stack keeps its values in sorted order as you push elements. The order can be increasing or decreasing, depending on the problem.\n\nA decreasing monotonic stack is the most common version. Before pushing a new value `x`, we pop from the top while the top is smaller than or equal to `x`. After those pops, pushing `x` keeps the stack decreasing from bottom to top.\n\nThis push rule is the whole idea. A monotonic deque uses the same rule, but a deque also lets you remove old elements from the front, which is useful for sliding window problems.\n\n## Example Implementation\n\nThis implementation maintains a decreasing monotonic stack.\n\n```python\ndef mono_stack(insert_entries):\n stack = []\n for entry in insert_entries:\n # Pop smaller (or equal) values so stack stays decreasing.\n while stack and stack[-1] <= entry:\n stack.pop()\n # Do something with the popped item here\n stack.append(entry)\n```\n\n:::tip\nIn interview problems, the stack usually stores indices instead of values. You can read the value from the original array when needed, and the index gives you distance information such as **\"how many steps away is the next greater element.\"**\n:::\n\nFor an array `nums`, if index `j` pops when you process index `i`, then `i` is the first index to the right that satisfies the stack condition for `j`. In a next-greater-element problem, that means `nums[i]` is the next greater value for `nums[j]`.\n\n","mdx":"---\ntitle: Monotonic Stack\ndescription: 'A stack keeps its items in sorted order, which finds the next larger or smaller item in one pass.'\nhidden: true\n---\n\n\n\n\nA monotonic stack keeps its values in sorted order as you push elements. The order can be increasing or decreasing, depending on the problem.\n\nA decreasing monotonic stack is the most common version. Before pushing a new value `x`, we pop from the top while the top is smaller than or equal to `x`. After those pops, pushing `x` keeps the stack decreasing from bottom to top.\n\nThis push rule is the whole idea. A monotonic deque uses the same rule, but a deque also lets you remove old elements from the front, which is useful for sliding window problems.\n\n## Example Implementation\n\nThis implementation maintains a decreasing monotonic stack.\n\n```python\ndef mono_stack(insert_entries):\n stack = []\n for entry in insert_entries:\n # Pop smaller (or equal) values so stack stays decreasing.\n while stack and stack[-1] <= entry:\n stack.pop()\n # Do something with the popped item here\n stack.append(entry)\n```\n\n:::tip\nIn interview problems, the stack usually stores indices instead of values. You can read the value from the original array when needed, and the index gives you distance information such as **\"how many steps away is the next greater element.\"**\n:::\n\nFor an array `nums`, if index `j` pops when you process index `i`, then `i` is the first index to the right that satisfies the stack condition for `j`. In a next-greater-element problem, that means `nums[i]` is the next greater value for `nums[j]`.\n\n"},"/monotonic-stack/car-fleet":{"mdx":"---\ntitle: '853. Car Fleet'\ndescription: There are n cars at given miles away from the starting mile 0, traveling to reach the mile target\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Sorting\", slug: \"sorting\" }\n - { name: \"Monotonic Stack\", slug: \"monotonic-stack\" }\nvideo: \"Pr6T-3yB9RM\"\nissue: \"https://github.com/prdlk/leetcode/issues/73\"\ncompanies:\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 26 }\nsidebar:\n label: 'Car Fleet'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]`\n- Output: `3`\n- Explanation: • The cars starting at `10 (speed 2`) and `8 (speed 4`) become a fleet, meeting each other at `12`. The fleet forms at `target`. • The car starting at `0 (speed 1`) does not catch up to any other car, so it is a fleet by itself. • The cars starting at `5 (speed 1`) and `3 (speed 3`) become a fleet, meeting each other at `6`. The fleet moves at `speed 1` until it reaches `target`.\n\n### Example 2:\n- Input: `target = 10, position = [3], speed = [3]`\n- Output: `1`\n- Explanation: There is only one car, hence there is only one fleet.\n\n### Example 3:\n- Input: `target = 100, position = [0,2,4], speed = [4,2,1]`\n- Output: `1`\n- Explanation: • The cars starting at `0 (speed 4`) and `2 (speed 2`) become a fleet, meeting each other at `4`. The car starting at `4 (speed 1`) travels to `5`. • Then, the fleet at `4 (speed 2`) and the car at `position 5 (speed 1`) become one fleet, meeting each other at `6`. The fleet moves at `speed 1` until it reaches `target`.\n\n### Constraints:\n\n- `n == position.length == speed.length`\n- `1 <= n <= 10^5`\n- `0 < target <= 10^6`\n- `0 <= position[i] < target`\n- All the values of `position` are unique.\n- `0 < speed[i] <= 10^6`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"carFleet(target, position, speed)\"]) --> O[\"zip and sort by position, descending — nearest the target first\"]\n O --> I[\"stack = [] — arrival time of each fleet's leader\"]\n I --> L{\"more (pos, spd)?\"}\n L -- no --> E([\"return len(stack) — one entry per fleet\"])\n L -- yes --> T[\"time = (target - pos) / spd\"]\n T --> Q{\"stack empty or time > stack[-1]?\"}\n Q -- yes --> A[\"stack.append(time) — slower, so it starts a new fleet\"]\n Q -- no --> B[\"discard — it catches the car ahead and joins that fleet\"]\n A --> L\n B --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def carFleet(self, target: int, position: List[int], speed: List[int]) -> int:\n stack = []\n for pos, spd in sorted(zip(position, speed), reverse=True):\n time = (target - pos) / spd\n if not stack or time > stack[-1]:\n stack.append(time)\n\n return len(stack)\n```\n"},"/monotonic-stack/daily-temperatures":{"mdx":"---\ntitle: '739. Daily Temperatures'\ndescription: Given an array of integers temperatures represents the daily temperatures, return an array answer such that answer[i] is the number of days you have to wait after the i^th day to get a warmer temperature. If there is no future day for which this is possible, keep answer[i] == 0 instead\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Monotonic Stack\", slug: \"monotonic-stack\" }\nvideo: \"cTBiBSnjO3c\"\nissue: \"https://github.com/prdlk/leetcode/issues/72\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Chime\", period: \"Three Months\", frequency: 100 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 59.7 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 42.8 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Anduril\", period: \"Six Months\", frequency: 92.8 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 42.5 }\nsidebar:\n label: 'Daily Temperatures'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `temperatures = [73,74,75,71,69,72,76,73]`\n- Output: `[1,1,4,2,1,1,0,0]`\n\n### Example 2:\n- Input: `temperatures = [30,40,50,60]`\n- Output: `[1,1,1,0]`\n\n### Example 3:\n- Input: `temperatures = [30,60,90]`\n- Output: `[1,1,0]`\n\n### Constraints:\n\n- `1 <= temperatures.length <= 10^5`\n- `30 <= temperatures[i] <= 100`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"dailyTemperatures(temperatures)\"]) --> I[\"ans = zeros(n), stack = [] — indices of days still waiting\"]\n I --> L{\"more (i, temp)?\"}\n L -- no --> E([\"return ans\"])\n L -- yes --> W{\"stack non-empty and temperatures[stack[-1]] < temp?\"}\n W -- yes --> P[\"prev = stack.pop(); ans[prev] = i - prev — today resolves that day\"]\n P --> W\n W -- no --> A[\"stack.append(i)\"]\n A --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def dailyTemperatures(self, temperatures: List[int]) -> List[int]:\n ans = [0] * len(temperatures)\n stack = []\n for i, temp in enumerate(temperatures):\n while stack and temperatures[stack[-1]] < temp:\n prev = stack.pop()\n ans[prev] = i - prev\n stack.append(i)\n return ans\n```\n"},"/monotonic-stack/largest-rectangle-in-histogram":{"mdx":"---\ntitle: '84. Largest Rectangle in Histogram'\ndescription: Given an array of integers heights representing the histogram's bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Monotonic Stack\", slug: \"monotonic-stack\" }\n - { name: \"Range Minimum/Maximum Query\", slug: \"range-minimum-maximum-query\" }\nissue: \"https://github.com/prdlk/leetcode/issues/76\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Accenture\", period: \"Three Months\", frequency: 88.6 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 73.7 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\nsidebar:\n label: 'Largest Rectangle in Histogram'\n badge: 'Hard'\n---\n\n### Example 1:\n- Input: `heights = [2,1,5,6,2,3]`\n- Output: `10`\n- Explanation: The above is a histogram where width of each bar is `1`. The largest rectangle is shown in the red area, which has an area = `10` units.\n\n### Example 2:\n- Input: `heights = [2,4]`\n- Output: `4`\n\n### Constraints:\n\n- `1 <= heights.length <= 10^5`\n- `0 <= heights[i] <= 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def largestRectangleArea(self, heights: list[int]) -> int:\n maxArea = 0\n stack = []\n\n for i, h in enumerate(heights):\n start = i\n while stack and stack[-1][1] > h:\n index, height = stack.pop()\n width = i - index\n maxArea = max(maxArea, height * width)\n start = index\n stack.append((start, h))\n\n for i, h in stack:\n maxArea = max(maxArea, h * (len(heights) - i))\n\n return maxArea\n```\n"},"/monotonic-stack/next-greater-element-i":{"mdx":"---\ntitle: '496. Next Greater Element I'\ndescription: The next greater element of some element x in an array is the first greater element that is to the right of x in the same array\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Monotonic Stack\", slug: \"monotonic-stack\" }\nissue: \"https://github.com/prdlk/leetcode/issues/74\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 46.6 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 59.7 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\nsidebar:\n label: 'Next Greater Element I'\n badge: 'Easy'\n---\n\n::::warning\nCould you find an O(nums1.length + nums2.length) solution?\n::::\n\n### Example 1:\n- Input: `nums1 = [4,1,2], nums2 = [1,3,4,2]`\n- Output: `[-1,3,-1]`\n- Explanation:\n - The next greater element for each value of `nums1` is as follows:\n - `4` is underlined in `nums2 = [1,3,4,2]`. There is no next greater element, so the answer is `-1`.\n - `1` is underlined in `nums2 = [1,3,4,2]`. The next greater element is `3`.\n - `2` is underlined in `nums2 = [1,3,4,2]`. There is no next greater element, so the answer is `-1`.\n\n### Example 2:\n- Input: `nums1 = [2,4], nums2 = [1,2,3,4]`\n- Output: `[3,-1]`\n- Explanation:\n - The next greater element for each value of `nums1` is as follows:\n - `2` is underlined in `nums2 = [1,2,3,4]`. The next greater element is `3`.\n - `4` is underlined in `nums2 = [1,2,3,4]`. There is no next greater element, so the answer is `-1`.\n\n### Constraints:\n\n- `1 <= nums1.length <= nums2.length <= 1000`\n- `0 <= nums1[i], nums2[i] <= 10^4`\n- All integers in `nums1` and `nums2` are unique.\n- All the integers of `nums1` also appear in nums2.\n\n## Solution\n\n```py\nclass Solution:\n def nextGreaterElement(self, nums1: list[int], nums2: list[int]) -> list[int]:\n mono_stack = []\n next_greater = {}\n\n for cur in nums2:\n while mono_stack and cur > mono_stack[-1]:\n val = mono_stack.pop()\n next_greater[val] = cur\n mono_stack.append(cur)\n\n return [next_greater.get(x, -1) for x in nums1]\n```\n"},"/monotonic-stack/online-stock-span":{"mdx":"---\ntitle: '901. Online Stock Span'\ndescription: Design an algorithm that collects daily price quotes for some stock and returns the span of that stock's price for the current day\nicon: dot\ntopics:\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Design\", slug: \"design\" }\n - { name: \"Monotonic Stack\", slug: \"monotonic-stack\" }\n - { name: \"Data Stream\", slug: \"data-stream\" }\nissue: \"https://github.com/prdlk/leetcode/issues/75\"\ncompanies:\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Amazon\", period: \"Six Months\", frequency: 26 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Online Stock Span'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: ``\n- Output: ``\n- Explanation: Input [\"StockSpanner\", \"next\", \"next\", \"next\", \"next\", \"next\", \"next\", \"next\"] `[[]`, `[100]`, `[80]`, `[60]`, `[70]`, `[60]`, `[75]`, [85]] Output [null, `1`, `1`, `1`, `2`, `1`, `4`, 6] Explanation StockSpanner stockSpanner = new StockSpanner(); stockSpanner.next(100); // return `1` stockSpanner.next(80); // return `1` stockSpanner.next(60); // return `1` stockSpanner.next(70); // return `2` stockSpanner.next(60); // return `1` stockSpanner.next(75); // return `4`, because the last `4` prices (including today's `price` of `75`) were less than or equal to today's `price`. stockSpanner.next(85); // return `6`\n\n### Constraints:\n\n- `1 <= price <= 10^5`\n- At most 10^4 calls will be made to next.\n\n## Solution\n\n```py\nclass StockSpanner:\n def __init__(self):\n self.stack = []\n\n def next(self, price: int) -> int:\n ans = 1\n while self.stack and self.stack[-1][0] <= price:\n ans += self.stack.pop()[1]\n\n self.stack.append([price, ans])\n return ans\n\n\n# Your StockSpanner object will be instantiated and called as such:\n# obj = StockSpanner()\n# param_1 = obj.next(price)\n```\n"},"/multi-d-grid-dp":{"mdx":"---\ntitle: Multi-D / Grid DP\ndescription: 'The result for each state is stored in a table with two or more dimensions, and each cell is computed from its neighbors.'\nhidden: true\n---\n"},"/multi-d-grid-dp/longest-common-subsequence":{"mdx":"---\ntitle: '1143. Longest Common Subsequence'\ndescription: Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0\nicon: dot\ntopics:\n - { name: \"String\", slug: \"string\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Longest Common Subsequence\", slug: \"longest-common-subsequence\" }\nissue: \"https://github.com/prdlk/leetcode/issues/168\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 38.7 }\nsidebar:\n label: 'Longest Common Subsequence'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `text1 = \"abcde\", text2 = \"ace\"`\n- Output: `3`\n- Explanation: The longest common subsequence is \"ace\" and its length is `3`.\n\n### Example 2:\n- Input: `text1 = \"abc\", text2 = \"abc\"`\n- Output: `3`\n- Explanation: The longest common subsequence is \"abc\" and its length is `3`.\n\n### Example 3:\n- Input: `text1 = \"abc\", text2 = \"def\"`\n- Output: `0`\n- Explanation: There is no such common subsequence, so the result is `0`.\n\n### Constraints:\n\n- `1 <= text1.length, text2.length <= 1000`\n- `text1` and `text2` consist of only lowercase English characters.\n\n## Solution\n\n```py\nclass Solution:\n def longestCommonSubsequence(self, text1: str, text2: str) -> int:\n dp = [[0 for j in range(len(text2) + 1)] for i in range(len(text1) + 1)]\n\n for i in range(len(text1) - 1, -1, -1):\n for j in range(len(text2) - 1, -1, -1):\n if text1[i] == text2[j]:\n dp[i][j] = 1 + dp[i + 1][j + 1]\n else:\n dp[i][j] = max(dp[i][j + 1], dp[i + 1][j])\n\n return dp[0][0]\n```\n"},"/multi-d-grid-dp/minimum-path-sum":{"mdx":"---\ntitle: '64. Minimum Path Sum'\ndescription: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right, which minimizes the sum of all numbers along its path\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Matrix\", slug: \"matrix\" }\nissue: \"https://github.com/prdlk/leetcode/issues/167\"\ncompanies:\n - { name: \"Goldman Sachs\", period: \"Three Months\", frequency: 66.3 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'Minimum Path Sum'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `grid = [[1,3,1],[1,5,1],[4,2,1]]`\n- Output: `7`\n- Explanation: Because the path `1` → `3` → `1` → `1` → `1` minimizes the sum.\n\n### Example 2:\n- Input: `grid = [[1,2,3],[4,5,6]]`\n- Output: `12`\n\n### Constraints:\n\n- `m == grid.length`\n- `n == grid[i].length`\n- `1 <= m, n <= 200`\n- `0 <= grid[i][j] <= 200`\n\n## Solution\n\n```py\nclass Solution:\n def minPathSum(self, grid: list[list[int]]) -> int:\n if not grid or not grid[0]:\n return 0\n\n m = len(grid)\n n = len(grid[0])\n dp = [[0 for _ in range(n)] for _ in range(m)]\n\n for c in range(n):\n dp[0][c] = dp[0][c - 1] + grid[0][c] if c else grid[0][c]\n\n for r in range(m):\n dp[r][0] = dp[r - 1][0] + grid[r][0] if r else grid[r][0]\n\n for r in range(1, m):\n for c in range(1, n):\n dp[r][c] = min(dp[r - 1][c], dp[r][c - 1]) + grid[r][c]\n\n return dp[-1][-1]\n```\n"},"/multi-d-grid-dp/unique-paths":{"mdx":"---\ntitle: '62. Unique Paths'\ndescription: There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e., grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot can only move either down or right at any point in time\nicon: dot\ntopics:\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Combinatorics\", slug: \"combinatorics\" }\nissue: \"https://github.com/prdlk/leetcode/issues/166\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\nsidebar:\n label: 'Unique Paths'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `m = 3, n = 7`\n- Output: `28`\n\n### Example 2:\n- Input: `m = 3, n = 2`\n- Output: `3`\n- Explanation: From the top-left corner, there are a total of `3` ways to reach the bottom-right corner: `1`. Right -> Down -> Down `2`. Down -> Down -> Right `3`. Down -> Right -> Down\n\n### Constraints:\n\n- `1 <= m, n <= 100`\n\n## Solution\n\n```py\nclass Solution:\n def uniquePaths(self, m: int, n: int) -> int:\n dp = [[0 for _ in range(n)] for _ in range(m)]\n\n for c in range(n):\n dp[0][c] = 1\n\n for r in range(m):\n dp[r][0] = 1\n\n for r in range(1, m):\n for c in range(1, n):\n dp[r][c] = dp[r - 1][c] + dp[r][c - 1]\n\n return dp[-1][-1]\n```\n"},"/prefix-sum":{"md":"---\ntitle: Prefix Sum\ndescription: 'A running total is stored at each index, so the sum of any range is one subtraction.'\nhidden: true\n---\n\nSuppose you are handed an array and asked for the sum of the elements between index `i` and index `j`. One query is easy: loop from `i` to `j` and add. But now imagine thousands of such queries over the same array, or a search that inspects the sum of every possible subarray. Recomputing each range from scratch costs `O(n)` per query, and the work piles up fast.\n\nPrefix sum removes that repetition. You spend `O(n)` once to precompute running totals, and afterward every range sum collapses into a single subtraction that runs in `O(1)`, no matter how wide the range.\n\n[Prefix Sum Explained](https://www.youtube.com/watch?v=CRVxUgmIO8M)\n\n## Transformation\n\nA prefix sum turns an array into a new array of running totals. For an input array `arr` of length `n`, build a `prefix` array of length `n + 1`:\n\n`prefix[0] = 0`\n\n`prefix[k] = arr[0] + arr[1] + ... + arr[k-1]`\n\nEach entry is the previous total plus one more element, so a single pass builds the whole thing:\n\n`prefix[k] = prefix[k-1] + arr[k-1]`\n\nThe leading `prefix[0] = 0` is the sum of zero elements. That extra slot is what makes the range math below land exactly on the boundaries, which is why `prefix` has one more cell than `arr`.\n\n\n\n\nEach bar is the running total up to that index. Every step keeps the previous total (blue) and adds one new element (amber)\n\n## Any range sum is one subtraction\n\nThe sum of the subarray from index `i` up to (but not including) `j` is `prefix[j] - prefix[i]`. `prefix[j]` is the total of everything before `j`, and `prefix[i]` is the total of everything before `i`, so subtracting throws away the front you did not ask for and leaves the middle. \n\n## Watch the boundaries\n\nThe one place prefix sums trip people up is the off-by-one at the edges. Keep three facts straight: `prefix` has length `n + 1`, `prefix[0]` is `0`, and `sum(arr[i..j-1]) = prefix[j] - prefix[i]` uses an exclusive right index `j`. If a problem hands you an inclusive right index `r`, translate it to `prefix[r + 1] - prefix[i]`.\n\n## When to reach for it\n\nPrefix sums fit whenever you need repeated range sums over a fixed array, or when an algorithm searches across subarray boundaries. For a single one-off sum, a plain loop is simpler; the prefix array earns its `O(n)` setup only once the same array is queried many times.\n","mdx":"---\ntitle: Prefix Sum\ndescription: 'A running total is stored at each index, so the sum of any range is one subtraction.'\nhidden: true\n---\n\nSuppose you are handed an array and asked for the sum of the elements between index `i` and index `j`. One query is easy: loop from `i` to `j` and add. But now imagine thousands of such queries over the same array, or a search that inspects the sum of every possible subarray. Recomputing each range from scratch costs `O(n)` per query, and the work piles up fast.\n\nPrefix sum removes that repetition. You spend `O(n)` once to precompute running totals, and afterward every range sum collapses into a single subtraction that runs in `O(1)`, no matter how wide the range.\n\n\n\n## Transformation\n\nA prefix sum turns an array into a new array of running totals. For an input array `arr` of length `n`, build a `prefix` array of length `n + 1`:\n\n`prefix[0] = 0`\n\n`prefix[k] = arr[0] + arr[1] + ... + arr[k-1]`\n\nEach entry is the previous total plus one more element, so a single pass builds the whole thing:\n\n`prefix[k] = prefix[k-1] + arr[k-1]`\n\nThe leading `prefix[0] = 0` is the sum of zero elements. That extra slot is what makes the range math below land exactly on the boundaries, which is why `prefix` has one more cell than `arr`.\n\n\n\n\n\n\n\n\n\n## Any range sum is one subtraction\n\nThe sum of the subarray from index `i` up to (but not including) `j` is `prefix[j] - prefix[i]`. `prefix[j]` is the total of everything before `j`, and `prefix[i]` is the total of everything before `i`, so subtracting throws away the front you did not ask for and leaves the middle. \n\n## Watch the boundaries\n\nThe one place prefix sums trip people up is the off-by-one at the edges. Keep three facts straight: `prefix` has length `n + 1`, `prefix[0]` is `0`, and `sum(arr[i..j-1]) = prefix[j] - prefix[i]` uses an exclusive right index `j`. If a problem hands you an inclusive right index `r`, translate it to `prefix[r + 1] - prefix[i]`.\n\n## When to reach for it\n\nPrefix sums fit whenever you need repeated range sums over a fixed array, or when an algorithm searches across subarray boundaries. For a single one-off sum, a plain loop is simpler; the prefix array earns its `O(n)` setup only once the same array is queried many times.\n"},"/prefix-sum/contiguous-array":{"mdx":"---\ntitle: '525. Contiguous Array'\ndescription: Given a binary array nums, return the maximum length of a contiguous subarray with an equal number of 0 and 1\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nissue: \"https://github.com/prdlk/leetcode/issues/39\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Cisco\", period: \"Three Months\", frequency: 100 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 49.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Akamai\", period: \"Six Months\", frequency: 100 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 40.6 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'Contiguous Array'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [0,1]`\n- Output: `2`\n- Explanation: [0, 1] is the longest contiguous subarray with an equal number of `0` and `1`.\n\n### Example 2:\n- Input: `nums = [0,1,0]`\n- Output: `2`\n- Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of `0` and `1`.\n\n### Example 3:\n- Input: `nums = [0,1,1,1,1,1,0,0,0]`\n- Output: `6`\n- Explanation: `[1,1,1,0,0,0]` is the longest contiguous subarray with equal number of `0` and `1`.\n\n### Constraints:\n\n- `1 <= nums.length <= 10^5`\n- `nums[i]` is either 0 or 1.\n\n## Solution\n\n```py\nclass Solution:\n def findMaxLength(self, nums: List[int]) -> int:\n map = {0: -1}\n count = 0\n longest = 0\n\n for i, num in enumerate(nums):\n count += 1 if num == 1 else -1\n\n if count in map:\n longest = max(longest, i - map[count])\n else:\n map[count] = i\n\n return longest\n```\n"},"/prefix-sum/product-of-array-except-self":{"mdx":"---\ntitle: '238. Product of Array Except Self'\ndescription: Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i]\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nvideo: \"bNvIQI2wAjk\"\nissue: \"https://github.com/prdlk/leetcode/issues/37\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 70.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 61.3 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 59.7 }\n - { name: \"Asana\", period: \"Six Months\", frequency: 100 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 43.5 }\nsidebar:\n label: 'Product of Array Except Self'\n badge: 'Medium'\n---\n\n::::warning\nYou must write an algorithm that runs in O(n) time and without using the division operation.\nCan you solve the problem in O(1) extra space complexity? (The output array does not count as extra space for space complexity analysis.)\n::::\n\n### Example 1:\n- Input: `nums = [1,2,3,4]`\n- Output: `[24,12,8,6]`\n\n### Example 2:\n- Input: `nums = [-1,1,0,-3,3]`\n- Output: `[0,0,9,0,0]`\n\n### Constraints:\n\n- `2 <= nums.length <= 10^5`\n- `-30 <= nums[i] <= 30`\n- The input is generated such that `answer[i]` is guaranteed to fit in a 32-bit integer.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"productExceptSelf(nums)\"]) --> I[\"answer = ones(n), rightArr = ones(n)\"]\n I --> P1[\"Pass 1 — left to right: answer[i] = nums[i-1] * answer[i-1]\"]\n P1 --> P2[\"Pass 2 — right to left: rightArr[i] = nums[i+1] * rightArr[i+1]\"]\n P2 --> P3[\"Pass 3: answer[i] *= rightArr[i]\"]\n P3 --> E([\"return answer — no division needed\"])\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n * @return {number[]}\n */\nvar productExceptSelf = function(nums) {\n const n = nums.length;\n const answer = new Array(n).fill(1);\n const rightArr = new Array(n).fill(1);\n\n for (let i = 1; i < n; i++) {\n answer[i] = nums[i - 1] * answer[i - 1];\n }\n for (let i = n - 2; i >= 0; i--) {\n rightArr[i] = nums[i + 1] * rightArr[i + 1];\n }\n for (let i = 0; i < n; i++) {\n answer[i] *= rightArr[i];\n }\n return answer;\n};\n```\n"},"/prefix-sum/range-sum-query-immutable":{"mdx":"---\ntitle: '303. Range Sum Query - Immutable'\ndescription: Given an integer array nums, handle multiple queries of the following type\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Design\", slug: \"design\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nvideo: \"2pndAmo_sMA\"\nissue: \"https://github.com/prdlk/leetcode/issues/36\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Range Sum Query - Immutable'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `[\"NumArray\", \"sumRange\", \"sumRange\", \"sumRange\"]` `[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]`\n- Output: `[null, 1, -1, -3]`\n- Explanation: `NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);` `numArray.sumRange(0, 2); // return (-2) + 0 + 3 = 1` `numArray.sumRange(2, 5); // return 3 + (-5) + 2 + (-1) = -1` `numArray.sumRange(0, 5); // return (-2) + 0 + 3 + (-5) + 2 + (-1) = -3`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^4`\n- `-10^5 <= nums[i] <= 10^5`\n- `0 <= left <= right < nums.length`\n- At most `10^4` calls will be made to `sumRange`.\n\n## Approach\n\n```mermaid\nflowchart TD\n subgraph build[\"constructor(nums) — O(n) once\"]\n A[\"prefix = [0]\"] --> B{\"more n in nums?\"}\n B -- yes --> C[\"prefix.push(last + n)\"]\n C --> B\n end\n build --> Q\n subgraph Q[\"sumRange(left, right) — O(1) per call\"]\n D([\"return prefix[right + 1] - prefix[left]\"])\n end\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n */\nclass NumArray {\n constructor(nums) {\n this.prefix = [0];\n for (let n of nums){\n this.prefix.push(this.prefix[this.prefix.length - 1] + n);\n }\n }\n /**\n * @param {number} left\n * @param {number} right\n * @return {number}\n */\n sumRange(left, right) {\n return this.prefix[right + 1] - this.prefix[left];\n }\n}\n\n\n/** \n * Your NumArray object will be instantiated and called as such:\n * var obj = new NumArray(nums)\n * var param_1 = obj.sumRange(left,right)\n */\n```\n"},"/prefix-sum/subarray-sum-equals-k":{"mdx":"---\ntitle: '560. Subarray Sum Equals K'\ndescription: Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nvideo: \"fFVZt-6sgyo\"\nissue: \"https://github.com/prdlk/leetcode/issues/38\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 63.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Visa\", period: \"Three Months\", frequency: 80.9 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 74.8 }\n - { name: \"Salesforce\", period: \"Three Months\", frequency: 64.7 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 57.1 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Accenture\", period: \"Six Months\", frequency: 100 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 94.5 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 76.3 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 74.7 }\n - { name: \"josh technology\", period: \"Six Months\", frequency: 74 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 70.5 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 69.2 }\nsidebar:\n label: 'Subarray Sum Equals K'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,1,1], k = 2`\n- Output: `2`\n\n### Example 2:\n- Input: `nums = [1,2,3], k = 3`\n- Output: `2`\n\n### Constraints:\n\n- `1 <= nums.length <= 2 * 10^4`\n- `-1000 <= nums[i] <= 1000`\n- `-10^7 <= k <= 10^7`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"subarraySum(nums, k)\"]) --> I[\"map = {0: 1} — the empty prefix; sum = 0, count = 0\"]\n I --> L{\"more n in nums?\"}\n L -- no --> E([\"return count\"])\n L -- yes --> A[\"sum += n\"]\n A --> Q{\"map has sum - k?\"}\n Q -- yes --> C[\"count += map.get(sum - k) — every earlier prefix that closes a window\"]\n Q -- no --> W[\"map.set(sum, count of sum + 1)\"]\n C --> W\n W --> L\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n * @param {number} k\n * @return {number}\n */\nvar subarraySum = function(nums, k) {\n const map = new Map();\n map.set(0, 1);\n\n let sum = 0;\n let count = 0;\n\n for (let n of nums){\n sum += n;\n\n if(map.has(sum - k)){\n count += map.get(sum - k);\n }\n\n map.set(sum, (map.get(sum) || 0) + 1);\n }\n return count\n};\n```\n"},"/prefix-sum/subarray-sums-divisible-by-k":{"mdx":"---\ntitle: '974. Subarray Sums Divisible by K'\ndescription: Given an integer array nums and an integer k, return the number of non-empty subarrays that have a sum divisible by k\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nissue: \"https://github.com/prdlk/leetcode/issues/40\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"TikTok\", period: \"Three Months\", frequency: 70.9 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Subarray Sums Divisible by K'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [4,5,0,-2,-3,1], k = 5`\n- Output: `7`\n- Explanation: There are `7` subarrays with a sum divisible by `k = 5`: [4, `5`, `0`, `-2`, `-3`, 1], `[5]`, [5, 0], [5, `0`, `-2`, -3], `[0]`, [0, `-2`, -3], [-2, -3]\n\n### Example 2:\n- Input: `nums = [5], k = 9`\n- Output: `0`\n\n### Constraints:\n\n- `1 <= nums.length <= 3 * 10^4`\n- `-10^4 <= nums[i] <= 10^4`\n- `2 <= k <= 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def subarraysDivByK(self, nums: list[int], k: int) -> int:\n remainder_counts = {0: 1}\n cur_sum = 0\n count = 0\n\n for n in nums:\n cur_sum += n\n remainder = cur_sum % k\n\n if remainder in remainder_counts:\n count += remainder_counts[remainder]\n\n remainder_counts[remainder] = remainder_counts.get(remainder, 0) + 1\n\n return count\n```\n"},"/sliding-window":{"md":"---\ntitle: Sliding Window\ndescription: 'Sliding window is a specialized two-pointer family where the pointers define a contiguous interval and you maintain information about that entire interval as it moves.'\nhidden: true\n---\n\n\n[Sliding Window](https://www.youtube.com/watch?v=tSTO9w3piAo)\n\n\nMany problems have two moving boundaries. That alone does not make them sliding window problems.\n\nA problem belongs to this family when:\n\n- the answer depends on the subarray or substring between left and right\n- you can update the window state incrementally as elements enter or leave\n- you maintain a condition that tells you whether the window is valid\n\n:::tip\nThe rule for all three: every element enters once and leaves once, so the whole thing runs in O(n).\n:::\n\n**What is an invariant?**\n\nAn invariant is a statement that stays true before and after every iteration. In a sliding window, that statement usually describes the window itself, such as “the window is valid,” “it has no duplicates,” or “its sum is at most the target.” It can also describe a helper structure, such as “the frequency map matches the characters currently inside the window.”\n\n**Why invariants matter?**\n\nWithout an invariant, shrinking the window is just a guess. You no longer know when the window is valid, when to update the answer, or why the left pointer should stop. The invariant is what makes the algorithm correct.\n\n**How sliding window differs from other two-pointer families?**\n\nSliding window is not the same as every other two-pointer pattern. In Container With Most Water, the interval is only the remaining search space. In sliding window, the interval itself is the thing you care about. In Remove Duplicates, the left side is already the finished answer prefix. In sliding window, both pointers describe a live window that is still being checked.\n\n\n## 1. Fixed-size windows\n\n:::tip\nThe window size never changes. The main task is updating the window state efficiently when one element enters and one leaves.\n:::\n\n\n\n\nSliding Window Fixed\n\n\n```python\ndef sliding_window_fixed(input, window_size):\n ans = window = input[0:window_size]\n for right in range(window_size, len(input)):\n left = right - window_size\n remove input[left] from window\n append input[right] to window\n ans = optimal(ans, window)\n return ans\n```\n\n1. Add `nums[right]` to the window.\n\n2. If the window has `k` elements, record the answer.\n\n3. Remove the leftmost element so the window stays at size `k`.\n\n\n## 2. Flexible-size windows with a validity rule\n\n:::tip\nHere the window expands until invalid, then shrinks until valid again.\n:::\n\n\n\nSliding Window Flexible\n\n\n**Longest Window**\n\n```python\ndef sliding_window_flexible_longest(input):\n initialize window, ans\n left = 0\n for right in range(len(input)):\n append input[right] to window\n while invalid(window): # update left until window is valid again\n remove input[left] from window\n left += 1\n ans = max(ans, window) # window is guaranteed to be valid here\n return ans\n\n```\n\n**Shortest Window**\n\n```python\ndef sliding_window_flexible_shortest(input):\n initialize window, ans\n left = 0\n for right in range(len(input)):\n append input[right] to window\n while valid(window):\n ans = min(ans, window) # window is guaranteed to be valid here\n remove input[left] from window\n left += 1\n return ans\n```\n\n1. Add `nums[right]` to the window.\n\n2. While the window is invalid, remove `nums[left]` and move `left` up.\n\n3. The window is now valid. Record its size.\n\n---\n\n## 3. Frequency-tracking windows\n\n:::tip\nThe difficulty comes from keeping the bookkeeping correct as characters enter and leave.\n:::\n\n\n\n\nFrequency-tracking windows\n\n```python\nfrom collections import defaultdict\n\ndef frequency_window(s):\n left = 0\n counts = defaultdict(int)\n best = 0\n\n for right in range(len(s)):\n counts[s[right]] += 1 # character enters\n\n while counts[s[right]] > 1: # rule: no repeats\n counts[s[left]] -= 1 # character leaves\n left += 1\n\n best = max(best, right - left + 1)\n\n return best\n```\n\n1. Add `s[right]` to the window.\n\n2. While the window has more than one character, remove `s[left]` and move `left` up.\n\n3. The window is now valid. Record its size.\n\n---\n\nFor anagram or \"minimum window substring\" problems, you also keep a target count. Track how many characters currently match the target with one integer (`matched`). Update it only when a count crosses the target value. This keeps each step `O(1)`.\n\n```python\ndef anagram_window(s, p):\n need = defaultdict(int)\n for c in p:\n need[c] += 1\n\n counts = defaultdict(int)\n matched = 0 # how many chars have counts[c] == need[c]\n result = []\n k = len(p)\n\n for right in range(len(s)):\n c = s[right]\n counts[c] += 1\n if counts[c] == need[c]:\n matched += 1\n\n if right >= k: # window too big, remove left\n d = s[right - k]\n if counts[d] == need[d]:\n matched -= 1\n counts[d] -= 1\n\n if matched == len(need):\n result.append(right - k + 1)\n\n return result\n```\n\n","mdx":"---\ntitle: Sliding Window\ndescription: 'Sliding window is a specialized two-pointer family where the pointers define a contiguous interval and you maintain information about that entire interval as it moves.'\nhidden: true\n---\n\n\n\n\n\nMany problems have two moving boundaries. That alone does not make them sliding window problems.\n\nA problem belongs to this family when:\n\n- the answer depends on the subarray or substring between left and right\n- you can update the window state incrementally as elements enter or leave\n- you maintain a condition that tells you whether the window is valid\n\n:::tip\nThe rule for all three: every element enters once and leaves once, so the whole thing runs in O(n).\n:::\n\n\n \n An invariant is a statement that stays true before and after every iteration. In a sliding window, that statement usually describes the window itself, such as “the window is valid,” “it has no duplicates,” or “its sum is at most the target.” It can also describe a helper structure, such as “the frequency map matches the characters currently inside the window.”\n \n \n Without an invariant, shrinking the window is just a guess. You no longer know when the window is valid, when to update the answer, or why the left pointer should stop. The invariant is what makes the algorithm correct.\n \n \n Sliding window is not the same as every other two-pointer pattern. In Container With Most Water, the interval is only the remaining search space. In sliding window, the interval itself is the thing you care about. In Remove Duplicates, the left side is already the finished answer prefix. In sliding window, both pointers describe a live window that is still being checked.\n \n\n\n\n## 1. Fixed-size windows\n\n:::tip\nThe window size never changes. The main task is updating the window state efficiently when one element enters and one leaves.\n:::\n\n\n\n\n\n\n\n\n\n```python\ndef sliding_window_fixed(input, window_size):\n ans = window = input[0:window_size]\n for right in range(window_size, len(input)):\n left = right - window_size\n remove input[left] from window\n append input[right] to window\n ans = optimal(ans, window)\n return ans\n```\n\n\n \n Add `nums[right]` to the window.\n \n \n If the window has `k` elements, record the answer.\n \n \n Remove the leftmost element so the window stays at size `k`.\n \n\n\n\n## 2. Flexible-size windows with a validity rule\n\n:::tip\nHere the window expands until invalid, then shrinks until valid again.\n:::\n\n\n\n\n\n\n\n\n\n \n\n```python\ndef sliding_window_flexible_longest(input):\n initialize window, ans\n left = 0\n for right in range(len(input)):\n append input[right] to window\n while invalid(window): # update left until window is valid again\n remove input[left] from window\n left += 1\n ans = max(ans, window) # window is guaranteed to be valid here\n return ans\n\n```\n\n \n \n\n```python\ndef sliding_window_flexible_shortest(input):\n initialize window, ans\n left = 0\n for right in range(len(input)):\n append input[right] to window\n while valid(window):\n ans = min(ans, window) # window is guaranteed to be valid here\n remove input[left] from window\n left += 1\n return ans\n```\n\n \n\n\n\n \n Add `nums[right]` to the window.\n \n \n While the window is invalid, remove `nums[left]` and move `left` up.\n \n \n The window is now valid. Record its size.\n \n\n\n---\n\n## 3. Frequency-tracking windows\n\n:::tip\nThe difficulty comes from keeping the bookkeeping correct as characters enter and leave.\n:::\n\n\n\n\n\n\n\n\n```python\nfrom collections import defaultdict\n\ndef frequency_window(s):\n left = 0\n counts = defaultdict(int)\n best = 0\n\n for right in range(len(s)):\n counts[s[right]] += 1 # character enters\n\n while counts[s[right]] > 1: # rule: no repeats\n counts[s[left]] -= 1 # character leaves\n left += 1\n\n best = max(best, right - left + 1)\n\n return best\n```\n\n\n \n Add `s[right]` to the window.\n \n \n While the window has more than one character, remove `s[left]` and move `left` up.\n \n \n The window is now valid. Record its size.\n \n\n\n---\n\nFor anagram or \"minimum window substring\" problems, you also keep a target count. Track how many characters currently match the target with one integer (`matched`). Update it only when a count crosses the target value. This keeps each step `O(1)`.\n\n```python\ndef anagram_window(s, p):\n need = defaultdict(int)\n for c in p:\n need[c] += 1\n\n counts = defaultdict(int)\n matched = 0 # how many chars have counts[c] == need[c]\n result = []\n k = len(p)\n\n for right in range(len(s)):\n c = s[right]\n counts[c] += 1\n if counts[c] == need[c]:\n matched += 1\n\n if right >= k: # window too big, remove left\n d = s[right - k]\n if counts[d] == need[d]:\n matched -= 1\n counts[d] -= 1\n\n if matched == len(need):\n result.append(right - k + 1)\n\n return result\n```\n\n"},"/sliding-window/best-time-to-buy-and-sell-stock":{"mdx":"---\ntitle: '121. Best Time to Buy and Sell Stock'\ndescription: You are given an array prices where prices[i] is the price of a given stock on the i^th day\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\nvideo: \"1pkOgXD63yU\"\nissue: \"https://github.com/prdlk/leetcode/issues/50\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 80.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 65.3 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 58.2 }\n - { name: \"Atlassian\", period: \"Three Months\", frequency: 100 }\n - { name: \"Media.net\", period: \"Three Months\", frequency: 100 }\n - { name: \"Nvidia\", period: \"Three Months\", frequency: 87.7 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 70.4 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 69 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 60.5 }\n - { name: \"Mastercard\", period: \"Six Months\", frequency: 79 }\n - { name: \"Accenture\", period: \"Six Months\", frequency: 75 }\n - { name: \"Adobe\", period: \"Six Months\", frequency: 74.3 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 70.5 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 70.1 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 53.1 }\nsidebar:\n label: 'Best Time to Buy and Sell Stock'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `prices = [7,1,5,3,6,4]`\n- Output: `5`\n- Explanation: Buy on day `2` (price = `1`) and sell on day `5` (price = `6`), profit = `6-1 = 5`. Note that buying on day `2` and selling on day `1` is not allowed because you must buy before you sell.\n\n### Example 2:\n- Input: `prices = [7,6,4,3,1]`\n- Output: `0`\n- Explanation: In this case, no transactions are done and the max profit = `0`.\n\n### Constraints:\n\n- `1 <= prices.length <= 10^5`\n- `0 <= prices[i] <= 10^4`\n\n## Approach\n\n::::warning\nThe diagram traces the code below literally. That code does not run: `curr` and `ans` are never initialised, so the first `curr > left` test raises `NameError`, and `left` holds a price rather than an index, so `prices[left]` indexes by value.\n::::\n\n```mermaid\nflowchart TD\n S([\"maxProfit(prices)\"]) --> I[\"left = min(prices)\"]\n I --> F{\"more right in range(len(prices))?\"}\n F -- no --> E([\"return ans\"])\n F -- yes --> W{\"curr > left?\"}\n W -- yes --> P[\"curr -= prices[left]; left += 1\"]\n P --> W\n W -- no --> M[\"ans = max(ans, curr)\"]\n M --> F\n```\n\n## Solution\n\n```py\nclass Solution:\n def maxProfit(self, prices: List[int]) -> int:\n left = min(prices)\n for right in range(len(prices)):\n while curr > left:\n curr -= prices[left]\n left += 1\n ans = max(ans, curr)\n return ans\n```\n"},"/sliding-window/longest-repeating-character-replacement":{"mdx":"---\ntitle: '424. Longest Repeating Character Replacement'\ndescription: You are given a string s and an integer k. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most k times\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\nvideo: \"gqXU1UyA8pk\"\nissue: \"https://github.com/prdlk/leetcode/issues/52\"\ncompanies:\n - { name: \"Zoho\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 46.6 }\n - { name: \"DE Shaw\", period: \"Three Months\", frequency: 91.8 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Longest Repeating Character Replacement'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `s = \"ABAB\", k = 2`\n- Output: `4`\n- Explanation: Replace the two 'A's with two 'B's or vice versa.\n\n### Example 2:\n- Input: `s = \"AABABBA\", k = 1`\n- Output: `4`\n- Explanation: Replace the one 'A' in the middle with 'B' and form \"AABBBBA\". The substring \"BBBB\" has the longest repeating letters, which is `4`. There may exists other ways to achieve this answer too.\n\n### Constraints:\n\n- `1 <= s.length <= 10^5`\n- `s` consists of only uppercase English letters.\n- `0 <= k <= s.length`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"characterReplacement(s, k)\"]) --> I[\"count = {}, res = 0, l = 0, maxF = 0\"]\n I --> L{\"more (r, c) in s?\"}\n L -- no --> E([\"return res\"])\n L -- yes --> A[\"count[c] += 1; maxF = max(maxF, count[c])\"]\n A --> W{\"(r - l + 1) - maxF > k? — too many chars to replace\"}\n W -- yes --> P[\"count[s[l]] -= 1; l += 1 — shrink from the left\"]\n P --> W\n W -- no --> M[\"res = max(res, r - l + 1)\"]\n M --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def characterReplacement(self, s: str, k: int) -> int:\n count = {}\n res = 0\n\n l = 0\n maxF = 0\n for r, c in enumerate(s):\n count[c] = 1 + count.get(c, 0)\n maxF = max(maxF, count[c])\n\n while (r - l + 1) - maxF > k:\n count[s[l]] -= 1\n l += 1\n\n res = max(res, r - l + 1)\n return res\n```\n"},"/sliding-window/longest-substring-without-repeating-characters":{"mdx":"---\ntitle: '3. Longest Substring Without Repeating Characters'\ndescription: Given a string s, find the length of the longest substring without duplicate characters\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\nvideo: \"wiGpQwVHdE0\"\nissue: \"https://github.com/prdlk/leetcode/issues/51\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Visa\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 84.9 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 75.6 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 63.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 63.7 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 58.2 }\n - { name: \"Cognizant\", period: \"Three Months\", frequency: 100 }\n - { name: \"Optum\", period: \"Three Months\", frequency: 100 }\n - { name: \"Spotify\", period: \"Three Months\", frequency: 100 }\n - { name: \"Deloitte\", period: \"Three Months\", frequency: 89.1 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 87.4 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 69 }\n - { name: \"Goldman Sachs\", period: \"Three Months\", frequency: 66.3 }\n - { name: \"Media.net\", period: \"Six Months\", frequency: 100 }\n - { name: \"Wipro\", period: \"Six Months\", frequency: 100 }\n - { name: \"Wissen Technology\", period: \"Six Months\", frequency: 100 }\n - { name: \"Zoho\", period: \"Six Months\", frequency: 100 }\n - { name: \"Qualcomm\", period: \"Six Months\", frequency: 92 }\n - { name: \"Turing\", period: \"Six Months\", frequency: 89 }\n - { name: \"EPAM Systems\", period: \"Six Months\", frequency: 86.7 }\n - { name: \"Netflix\", period: \"Six Months\", frequency: 83.1 }\n - { name: \"Tesla\", period: \"Six Months\", frequency: 80.9 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 69.2 }\n - { name: \"Agoda\", period: \"Six Months\", frequency: 65 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 60.1 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\nsidebar:\n label: 'Longest Substring Without Repeating Characters'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `s = \"abcabcbb\"`\n- Output: `3`\n- Explanation: The answer is \"abc\", with the length of `3`. Note that \"bca\" and \"cab\" are also correct answers.\n\n### Example 2:\n- Input: `s = \"bbbbb\"`\n- Output: `1`\n- Explanation: The answer is \"b\", with the length of `1`.\n\n### Example 3:\n- Input: `s = \"pwwkew\"`\n- Output: `3`\n- Explanation: The answer is \"wke\", with the length of `3`. Notice that the answer must be a substring, \"pwke\" is a subsequence and not a substring.\n\n### Constraints:\n\n- `0 <= s.length <= 10^5`\n- `s` consists of English letters, digits, symbols and spaces.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"lengthOfLongestSubstring(s)\"]) --> I[\"left = 0, ans = 0, window = set()\"]\n I --> L{\"more (right, c) in s?\"}\n L -- no --> E([\"return ans\"])\n L -- yes --> W{\"c already in window?\"}\n W -- yes --> P[\"window.remove(s[left]); left += 1 — shrink until c is free\"]\n P --> W\n W -- no --> A[\"window.add(c)\"]\n A --> M[\"ans = max(ans, right - left + 1)\"]\n M --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def lengthOfLongestSubstring(self, s: str) -> int:\n left = 0\n ans = 0\n window = set()\n for right, c in enumerate(s):\n while c in window:\n window.remove(s[left])\n left += 1\n window.add(c)\n ans = max(ans, right - left + 1)\n\n return ans\n```\n"},"/sliding-window/max-consecutive-ones-iii":{"mdx":"---\ntitle: '1004. Max Consecutive Ones III'\ndescription: Given a binary array nums and an integer k, return the maximum number of consecutive 1's in the array if you can flip at most k 0's\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nissue: \"https://github.com/prdlk/leetcode/issues/56\"\ncompanies:\n - { name: \"EPAM Systems\", period: \"Thirty Days\", frequency: 89.8 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Tekion\", period: \"Three Months\", frequency: 100 }\n - { name: \"DE Shaw\", period: \"Three Months\", frequency: 80.2 }\n - { name: \"Google\", period: \"Three Months\", frequency: 38.7 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 67.9 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 59.6 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 42.5 }\nsidebar:\n label: 'Max Consecutive Ones III'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2`\n- Output: `6`\n- Explanation: `[1,1,1,0,0,1,1,1,1,1,1]` Bolded numbers were flipped from `0` to `1`. The longest subarray is underlined.\n\n### Example 2:\n- Input: `nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3`\n- Output: `10`\n- Explanation: `[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]` Bolded numbers were flipped from `0` to `1`. The longest subarray is underlined.\n\n### Constraints:\n\n- `1 <= nums.length <= 10^5`\n- `nums[i]` is either 0 or 1.\n- `0 <= k <= nums.length`\n\n## Solution\n\n```py\nclass Solution:\n def longestOnes(self, nums: list[int], k: int) -> int:\n left = 0\n cur = 0\n ans = 0\n\n for right in range(len(nums)):\n if nums[right] == 0:\n cur += 1\n while cur > k:\n if nums[left] == 0:\n cur -= 1\n left += 1\n\n ans = max(ans, right - left + 1)\n\n return ans\n```\n"},"/sliding-window/maximum-average-subarray-i":{"mdx":"---\ntitle: '643. Maximum Average Subarray I'\ndescription: You are given an integer array nums consisting of n elements, and an integer k\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\nissue: \"https://github.com/prdlk/leetcode/issues/55\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 55.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Maximum Average Subarray I'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `nums = [1,12,-5,-6,50,3], k = 4`\n- Output: `12.75000`\n- Explanation: Maximum average is `(12 - 5 - 6 + 50`) / `4 = 51 / 4 = 12.75`\n\n### Example 2:\n- Input: `nums = [5], k = 1`\n- Output: `5.00000`\n\n### Constraints:\n\n- `n == nums.length`\n- `1 <= k <= n <= 10^5`\n- `-10^4 <= nums[i] <= 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def findMaxAverage(self, nums: list[int], k: int) -> float:\n window_sum = 0\n for i in range(k):\n window_sum += nums[i]\n largest = window_sum\n\n for right in range(k, len(nums)):\n left = right - k\n window_sum -= nums[left]\n window_sum += nums[right]\n largest = max(largest, window_sum)\n\n return largest / k\n```\n"},"/sliding-window/minimum-size-subarray-sum":{"mdx":"---\ntitle: '209. Minimum Size Subarray Sum'\ndescription: Given an array of positive integers nums and a positive integer target, return the minimal length of a subarray whose sum is greater than or equal to target. If there is no such subarray, return 0 instead\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\n - { name: \"Prefix Sum\", slug: \"prefix-sum\" }\nissue: \"https://github.com/prdlk/leetcode/issues/54\"\ncompanies:\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 45 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\nsidebar:\n label: 'Minimum Size Subarray Sum'\n badge: 'Medium'\n---\n\n::::warning\nIf you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log(n)).\n::::\n\n### Example 1:\n- Input: `target = 7, nums = [2,3,1,2,4,3]`\n- Output: `2`\n- Explanation: The subarray `[4,3]` has the minimal length under the problem constraint.\n\n### Example 2:\n- Input: `target = 4, nums = [1,4,4]`\n- Output: `1`\n\n### Example 3:\n- Input: `target = 11, nums = [1,1,1,1,1,1,1,1]`\n- Output: `0`\n\n### Constraints:\n\n- `1 <= target <= 10^9`\n- `1 <= nums.length <= 10^5`\n- `1 <= nums[i] <= 10^4`\n\n## Solution\n\n```py\nclass Solution:\n def minSubArrayLen(self, target: int, nums: list[int]) -> int:\n window_sum = 0\n length = len(nums) + 1\n left = 0\n\n for right in range(len(nums)):\n window_sum += nums[right]\n while window_sum >= target:\n length = min(length, right - left + 1)\n window_sum -= nums[left]\n left += 1\n if length > len(nums):\n return 0\n return length\n```\n"},"/sliding-window/minimum-window-substring":{"mdx":"---\ntitle: '76. Minimum Window Substring'\ndescription: Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string \"\"\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\nissue: \"https://github.com/prdlk/leetcode/issues/57\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 55.9 }\n - { name: \"Lyft\", period: \"Three Months\", frequency: 93.3 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Minimum Window Substring'\n badge: 'Hard'\n---\n\n::::warning\nCould you find an algorithm that runs in O(m + n) time?\n::::\n\n### Example 1:\n- Input: `s = \"ADOBECODEBANC\", t = \"ABC\"`\n- Output: `\"BANC\"`\n- Explanation: The minimum window substring \"BANC\" includes 'A', 'B', and 'C' from string `t`.\n\n### Example 2:\n- Input: `s = \"a\", t = \"a\"`\n- Output: `\"a\"`\n- Explanation: The entire string `s` is the minimum window.\n\n### Example 3:\n- Input: `s = \"a\", t = \"aa\"`\n- Output: `\"\"`\n- Explanation: Both 'a's from `t` must be included in the window. Since the largest window of `s` only has one 'a', return empty string.\n\n### Constraints:\n\n- `m == s.length`\n- `n == t.length`\n- `1 <= m, n <= 10^5`\n- `s` and `t` consist of uppercase and lowercase English letters.\n\n## Solution\n\n```py\nclass Solution:\n def minWindow(self, s: str, t: str) -> str:\n```\n"},"/sliding-window/permutation-in-string":{"mdx":"---\ntitle: '567. Permutation in String'\ndescription: Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Sliding Window\", slug: \"sliding-window\" }\nvideo: \"UbyhOgBN834\"\nissue: \"https://github.com/prdlk/leetcode/issues/53\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 63.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 48.1 }\nsidebar:\n label: 'Permutation in String'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `s1 = \"ab\", s2 = \"eidbaooo\"`\n- Output: `true`\n- Explanation: `s2` contains one permutation of `s1` (\"ba\").\n\n### Example 2:\n- Input: `s1 = \"ab\", s2 = \"eidboaoo\"`\n- Output: `false`\n\n### Constraints:\n\n- `1 <= s1.length, s2.length <= 10^4`\n- `s1` and `s2` consist of lowercase English letters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"checkInclusion(s1, s2)\"]) --> G{\"k = len(s1) > len(s2)?\"}\n G -- yes --> X([\"return False\"])\n G -- no --> I[\"need = Counter(s1), window = Counter()\"]\n I --> L{\"more (right, c) in s2?\"}\n L -- no --> E([\"return False\"])\n L -- yes --> A[\"window[c] += 1\"]\n A --> B{\"right >= k? — window is now longer than k\"}\n B -- yes --> C[\"drop s2[right - k] from window, deleting the key at 0\"]\n B -- no --> Q\n C --> Q{\"window == need?\"}\n Q -- yes --> R([\"return True\"])\n Q -- no --> L\n```\n\n## Solution\n\n```py\nfrom collections import Counter\n\n\nclass Solution:\n def checkInclusion(self, s1: str, s2: str) -> bool:\n k = len(s1)\n if k > len(s2):\n return False\n\n need = Counter(s1)\n window = Counter()\n\n for right, c in enumerate(s2):\n window[c] += 1\n if right >= k:\n left_char = s2[right - k]\n window[left_char] -= 1\n if window[left_char] == 0:\n del window[left_char]\n if window == need:\n return True\n\n return False\n```\n"},"/stack":{"mdx":"---\ntitle: Stack\ndescription: 'Items are added and removed from one end, so the last item added is the first item removed.'\nhidden: true\n---\n\nA stack works like a stack of plates in a cafeteria. You add new plates on top. When you need a plate, you take from the top. The last plate you added is the first one you remove.\n\nThis is **Last-In-First-Out (LIFO)**. The most recent item goes out first.\n\n\n\n## Core Stack Operations\n\nA stack has two fundamental operations:\n\n- **Push**: add an item to the top of the stack\n- **Pop**: remove the item at the top of the stack\n\nSome stacks have additional operations:\n\n- **Peek**: get the item at the top of the stack without removing it\n- **IsEmpty**: check if the stack is empty\n\n\n\n```python\n# Using Python list as a stack\nstack = []\n\n# Push elements\nstack.append(10)\nstack.append(20)\nstack.append(30)\n# Stack: [10, 20, 30] (30 is on top)\n\n# Pop element\ntop = stack.pop() # Returns 30\n# Stack: [10, 20]\n\n# Peek at top\nif stack:\n top_element = stack[-1] # Returns 20 without removing\n```\n\nPython lists provide `append()` for pushing and `pop()` for popping. The `peek()` method is not built-in, but you can implement it yourself.\n\n## Last in, First out\n\nThe defining characteristic of a stack is LIFO order. Whatever you put in last comes out first. This is different from a queue, which is First-In-First-Out (FIFO).\n\nAdd items: A, B, C\n\n- Stack: [A, B, C] (C on top)\n\nRemove items:\n\n- First pop: C\n- Second pop: B\n- Third pop: A\n\nThe order reverses. Items come out in the opposite order they went in.\n"},"/stack/basic-calculator":{"mdx":"---\ntitle: '224. Basic Calculator'\ndescription: Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation\nicon: dot\ntopics:\n - { name: \"Math\", slug: \"math\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Recursion\", slug: \"recursion\" }\nissue: \"https://github.com/prdlk/leetcode/issues/71\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\nsidebar:\n label: 'Basic Calculator'\n badge: 'Hard'\n---\n\n### Example 1:\n- Input: `s = \"1 + 1\"`\n- Output: `2`\n\n### Example 2:\n- Input: `s = \" 2-1 + 2 \"`\n- Output: `3`\n\n### Example 3:\n- Input: `s = \"(1+(4+5+2)-3)+(6+8)\"`\n- Output: `23`\n\n### Constraints:\n\n- `1 <= s.length <= 3 * 10^5`\n- `s` consists of digits, '+', '-', '(', ')', and ' '.\n- `s` represents a valid expression.\n- '+' is not used as a unary operation (i.e., \"+1\" and \"+(2 + 3)\" is invalid).\n- '-' could be used as a unary operation (i.e., \"-1\" and \"-(2 + 3)\" is valid).\n- There will be no two consecutive operators in the input.\n- Every number and running calculation will fit in a signed 32-bit integer.\n\n## Solution\n\n```py\nclass Solution:\n def calculate(self, s: str) -> int:\n```\n"},"/stack/evaluate-reverse-polish-notation":{"mdx":"---\ntitle: '150. Evaluate Reverse Polish Notation'\ndescription: You are given an array of strings tokens that represents an arithmetic expression in a Reverse Polish Notation\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Stack\", slug: \"stack\" }\nvideo: \"iu0082c4HDE\"\nissue: \"https://github.com/prdlk/leetcode/issues/69\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Three Months\", frequency: 17.3 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 59.6 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 38.7 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Evaluate Reverse Polish Notation'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `tokens = [\"2\",\"1\",\"+\",\"3\",\"*\"]`\n- Output: `9`\n- Explanation: `((2 + 1`) * `3`) = `9`\n\n### Example 2:\n- Input: `tokens = [\"4\",\"13\",\"5\",\"/\",\"+\"]`\n- Output: `6`\n- Explanation: `(4 + (13 / 5`)) = `6`\n\n### Example 3:\n- Input: `tokens = [\"10\",\"6\",\"9\",\"3\",\"+\",\"-11\",\"*\",\"/\",\"*\",\"17\",\"+\",\"5\",\"+\"]`\n- Output: `22`\n- Explanation: `((10 * (6 / ((9 + 3`) * `-11`))) + `17`) + `5 = ((10 * (6 / (12 * -11`))) + `17`) + `5 = ((10 * (6 / -132`)) + `17`) + `5 = ((10 * 0`) + `17`) + `5 = (0 + 17`) + `5 = 17 + 5 = 22`\n\n### Constraints:\n\n- `1 <= tokens.length <= 10^4`\n- `tokens[i]` is either an operator: \"+\", \"-\", \"*\", or \"/\", or an integer in the range [-200, 200].\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"evalRPN(tokens)\"]) --> I[\"stack = [], operations = + - * /\"]\n I --> L{\"more token c?\"}\n L -- no --> E([\"return stack[0]\"])\n L -- yes --> Q{\"c is an operator?\"}\n Q -- no --> N[\"stack.append(int(c))\"]\n N --> L\n Q -- yes --> P[\"y = stack.pop(), x = stack.pop() — order matters\"]\n P --> C[\"stack.append(operations[c](x, y))\"]\n C --> L\n```\n\n## Solution\n\n```py\nclass Solution:\n def evalRPN(self, tokens: List[str]) -> int:\n stack = []\n operations = {\n \"+\": lambda x, y: int(x + y),\n \"-\": lambda x, y: int(x - y),\n \"*\": lambda x, y: int(x * y),\n \"/\": lambda x, y: int(x / y),\n }\n\n for c in tokens:\n if c in operations:\n y = stack.pop()\n x = stack.pop()\n calc_func = operations[c]\n result = calc_func(x, y)\n stack.append(result)\n else:\n stack.append(int(c))\n\n return stack[0]\n```\n"},"/stack/min-stack":{"mdx":"---\ntitle: '155. Min Stack'\ndescription: Design a stack that supports push, pop, top, and retrieving the minimum element in constant time\nicon: dot\ntopics:\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Design\", slug: \"design\" }\nvideo: \"qkLl7nAwDPo\"\nissue: \"https://github.com/prdlk/leetcode/issues/68\"\ncompanies:\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Google\", period: \"Three Months\", frequency: 28.8 }\n - { name: \"Odoo\", period: \"Six Months\", frequency: 100 }\n - { name: \"UiPath\", period: \"Six Months\", frequency: 100 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 67.9 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 45.6 }\nsidebar:\n label: 'Min Stack'\n badge: 'Medium'\n---\n\n::::warning\nYou must implement a solution with O(1) time complexity for each function.\n::::\n\n### Example 1:\n- Input: ``\n- Output: ``\n- Explanation: Input `[\"MinStack\",\"push\",\"push\",\"push\",\"getMin\",\"pop\",\"top\",\"getMin\"]` [[],[-2],[0],[-3],[],[],[],[]] Output `[null,null,null,null,-3,null,0,-2]` Explanation MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); // return `-3` minStack.pop(); minStack.top(); // return `0` minStack.getMin(); // return `-2`\n\n### Constraints:\n\n- `-2^31 <= val <= 2^31 - 1`\n- Methods pop, top and getMin operations will always be called on non-empty stacks.\n- At most 3 * 10^4 calls will be made to push, pop, top, and getMin.\n\n## Approach\n\n```mermaid\nflowchart TD\n subgraph state[\"two parallel stacks — same depth, always\"]\n A[\"stack — the values\"]\n B[\"minStack — the minimum as of that depth\"]\n end\n state --> P\n subgraph P[\"push(value)\"]\n P1[\"stack.append(value)\"] --> P2[\"minStack.append(min(value, minStack[-1]))\"]\n end\n state --> O\n subgraph O[\"pop()\"]\n O1[\"pop both stacks together\"]\n end\n state --> R\n subgraph R[\"top() / getMin() — O(1)\"]\n R1([\"stack[-1] / minStack[-1]\"])\n end\n```\n\n## Solution\n\n```py\nclass MinStack:\n def __init__(self):\n self.stack = []\n self.minStack = []\n\n def push(self, value: int) -> None:\n self.stack.append(value)\n value = min(value, self.minStack[-1] if self.minStack else value)\n self.minStack.append(value)\n\n def pop(self) -> None:\n self.stack.pop()\n self.minStack.pop()\n\n def top(self) -> int:\n return self.stack[-1]\n\n def getMin(self) -> int:\n return self.minStack[-1]\n\n\n# Your MinStack object will be instantiated and called as such:\n# obj = MinStack()\n# obj.push(value)\n# obj.pop()\n# param_3 = obj.top()\n# param_4 = obj.getMin()\n```\n"},"/stack/simplify-path":{"mdx":"---\ntitle: '71. Simplify Path'\ndescription: You are given an absolute path for a Unix-style file system, which always begins with a slash '/'. Your task is to transform this absolute path into its simplified canonical path\nicon: dot\ntopics:\n - { name: \"String\", slug: \"string\" }\n - { name: \"Stack\", slug: \"stack\" }\nissue: \"https://github.com/prdlk/leetcode/issues/70\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 28.8 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"Snowflake\", period: \"Six Months\", frequency: 58.7 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 50.6 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Simplify Path'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `path = \"/home/\"`\n- Output: `\"/home\"`\n- Explanation: The trailing slash should be removed.\n\n### Example 2:\n- Input: `path = \"/home//foo/\"`\n- Output: `\"/home/foo\"`\n- Explanation: Multiple consecutive slashes are replaced by a single one.\n\n### Example 3:\n- Input: `path = \"/home/user/Documents/../Pictures\"`\n- Output: `\"/home/user/Pictures\"`\n- Explanation: A double period \"..\" refers to the directory up a level (the parent directory).\n\n### Example 4:\n- Input: `path = \"/../\"`\n- Output: `\"/\"`\n- Explanation: Going one level up from the root directory is not possible.\n\n### Example 5:\n- Input: `path = \"/.../a/../b/c/../d/./\"`\n- Output: `\"/.../b/d\"`\n- Explanation: \"...\" is a valid name for a directory in this problem.\n\n### Constraints:\n\n- `1 <= path.length <= 3000`\n- `path` consists of English letters, digits, period '.', slash '/' or '_'.\n- `path` is a valid absolute Unix path.\n\n## Solution\n\n```py\nclass Solution:\n def simplifyPath(self, path: str) -> str:\n stack = []\n segments = [item for item in path.split(\"/\") if item]\n\n for p in segments:\n if stack and p == \"..\":\n stack.pop()\n elif not stack and p == \"..\" or p == \".\":\n continue\n else:\n stack.append(p)\n\n return \"/\" + \"/\".join(stack)\n```\n"},"/stack/valid-parentheses":{"mdx":"---\ntitle: '20. Valid Parentheses'\ndescription: Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid\nicon: dot\ntopics:\n - { name: \"String\", slug: \"string\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Bracket Sequences\", slug: \"bracket-sequences\" }\nvideo: \"WTzjTskDFMg\"\nissue: \"https://github.com/prdlk/leetcode/issues/67\"\ncompanies:\n - { name: \"BlackRock\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 61.3 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Accolite\", period: \"Three Months\", frequency: 100 }\n - { name: \"Intuit\", period: \"Three Months\", frequency: 73.2 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 68.3 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 65.3 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Autodesk\", period: \"Six Months\", frequency: 100 }\n - { name: \"Criteo\", period: \"Six Months\", frequency: 100 }\n - { name: \"Odoo\", period: \"Six Months\", frequency: 100 }\n - { name: \"Tripadvisor\", period: \"Six Months\", frequency: 100 }\n - { name: \"Virtu Financial\", period: \"Six Months\", frequency: 100 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 91.1 }\n - { name: \"Epic Systems\", period: \"Six Months\", frequency: 89.6 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 85.6 }\nsidebar:\n label: 'Valid Parentheses'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `s = \"()\"`\n- Output: `true`\n\n### Example 2:\n- Input: `s = \"()[]{}\"`\n- Output: `true`\n\n### Example 3:\n- Input: `s = \"(]\"`\n- Output: `false`\n\n### Example 4:\n- Input: `s = \"([])\"`\n- Output: `true`\n\n### Example 5:\n- Input: `s = \"([)]\"`\n- Output: `false`\n\n### Constraints:\n\n- `1 <= s.length <= 10^4`\n- `s` consists of parentheses only '()[]{}'.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"isValid(s)\"]) --> I[\"stack = [], pairs = closer to opener\"]\n I --> L{\"more char c?\"}\n L -- no --> Z{\"stack empty?\"}\n Z -- yes --> T([\"return True\"])\n Z -- no --> U([\"return False — unclosed openers left\"])\n L -- yes --> Q{\"c is a closer?\"}\n Q -- no --> A[\"stack.append(c) — it is an opener\"]\n A --> L\n Q -- yes --> M{\"stack non-empty and pairs[c] == stack[-1]?\"}\n M -- yes --> P[\"stack.pop() — matched\"]\n P --> L\n M -- no --> F([\"return False — mismatch\"])\n```\n\n## Solution\n\n```py\nclass Solution:\n def isValid(self, s: str) -> bool:\n stack = []\n pairs = {\")\": \"(\", \"]\": \"[\", \"}\": \"{\"}\n\n for c in s:\n if c in pairs:\n if stack and pairs[c] == stack[-1]:\n stack.pop()\n else:\n return False\n else:\n stack.append(c)\n\n return True if not stack else False\n```\n"},"/topological-sort":{"mdx":"---\ntitle: Topological Sort\ndescription: 'Topological sort or topological ordering of a directed graph is an ordering of nodes such that every node appears in the ordering before all the nodes it points to. '\nhidden: true\n---\n\n## Directed Graph\n\nBefore we get started on topological order, let's talk about directed graphs first. A graph is directed when its edges have directions (these edges are also called arcs). Suppose that v, w are vertices in a directed graph. Let's get familiar with a few concepts.\n\n- **in-edge** - an edge pointing to or coming into the node\n- **out-edge** - an edge pointing away or going out from the node (we will refer those nodes on the other end of the out-edges of v to v's neighbors)\n- **in-degree** - the number of in-edges coming into the node\n- **out-degree** - the number of out-edges going out from the node\n- **dependency** - \"v depends on w\" / \"v is dependent on w\" means that there is a directed path from w to v where v, w are vertices in a directed graph. With these new terms under our belt, it will make more sense when we talk about directed graphs.\n\n## What is a topological order?\n\nTopological sort is not unique. For example, for a graph like this:\n\n\n\nBoth `[4, 5, 2]` and `[5, 4, 2]` are valid topological orders. \n\n\n\nTask 3 is completely independent of task 2 and 4, and it can be anywhere in the order as long as it is before task 1 which depends on it. All of the following ordering are valid topological orderings.\n\n`[4, 2, 3, 1], [4, 3, 2, 1], [3, 4, 2, 1]`\n\n\n:::warning[Graphs with Cycles Do Not Have Topological Ordering]\nIt should be obvious that if a graph with a cycle does not have a topological ordering. In the above example, 2 has to come before 5 which has come before 4 which has to come before 2 which has to come before 5... which is impossible.\n:::\n\n## Kahn's Algorithm\n\nTo obtain a topological order, we can use Kahn's algorithm which is very similar to Breadth First Search.\n\nIn order to understand why we must use this algorithm we first look at the problem it is trying to solve.\n\nGiven a directed graph does there exist a way to remove the nodes such that each time we remove a node we guarantee that no other nodes point to that particular node?\n\nFor this algorithm, we systematically remove one node at a time, each time removing a node such that no other nodes point to that node (in-degree is 0). If no such node exists, then there must be a cycle, and there is no way to order the nodes such that \"every node appears in the ordering before all the nodes it points to\" (no solution). After removing the current node, for each neighboring node the current node points to, we check whether any nodes point to this node. If there isn't any, we push this node into the queue. Notice it is important to keep track of the number of nodes pointing to a node (in-degree) in the question as we only push the node into the queue once all nodes the current node depended on have been removed. \n\nHere is a graphic to demonstrate the idea.\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Example Code\n\n:::tip\nNotice the topological sort algorithm is very similar to BFS. The main difference is that we only push nodes with 0 in-degree into the queue in topological sort whereas in BFS we push all the neighboring nodes into the queue.\n:::\n\n```py\nfrom collections import deque\n\ndef find_indegree(graph):\n indegree = { node: 0 for node in graph } # dict\n for node in graph:\n for neighbor in graph[node]:\n indegree[neighbor] += 1\n return indegree\n\n\ndef topo_sort(graph):\n res = []\n q = deque()\n indegree = find_indegree(graph)\n for node in indegree:\n if indegree[node] == 0:\n q.append(node)\n while len(q) > 0:\n node = q.popleft()\n res.append(node)\n for neighbor in graph[node]:\n indegree[neighbor] -= 1\n if indegree[neighbor] == 0:\n q.append(neighbor)\n return res if len(graph) == len(res) else None\n```\n"},"/topological-sort/course-schedule":{"mdx":"---\ntitle: '207. Course Schedule'\ndescription: There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai\nicon: dot\ntopics:\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Graph Theory\", slug: \"graph\" }\n - { name: \"Topological Sort\", slug: \"topological-sort\" }\n - { name: \"Directed Acyclic Graph\", slug: \"directed-acyclic-graph\" }\nissue: \"https://github.com/prdlk/leetcode/issues/142\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"TikTok\", period: \"Three Months\", frequency: 70.9 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 43.3 }\n - { name: \"ByteDance\", period: \"Six Months\", frequency: 88.6 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 70.5 }\n - { name: \"Anduril\", period: \"Six Months\", frequency: 65.4 }\n - { name: \"Snowflake\", period: \"Six Months\", frequency: 58.7 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 57.9 }\n - { name: \"Infosys\", period: \"Six Months\", frequency: 56.2 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 44.8 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'Course Schedule'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `numCourses = 2, prerequisites = [[1,0]]`\n- Output: `true`\n- Explanation: There are a total of `2` courses to take. To take course `1` you should have finished course `0`. So it is possible.\n\n### Example 2:\n- Input: `numCourses = 2, prerequisites = [[1,0],[0,1]]`\n- Output: `false`\n- Explanation: There are a total of `2` courses to take. To take course `1` you should have finished course `0`, and to take course `0` you should also have finished course `1`. So it is impossible.\n\n### Constraints:\n\n- `1 <= numCourses <= 2000`\n- `0 <= prerequisites.length <= 5000`\n- `prerequisites[i].length == 2`\n- `0 <= ai, bi < numCourses`\n- All the pairs `prerequisites[i]` are unique.\n\n## Solution\n\n```py\nclass Solution:\n def canFinish(self, numCourses: int, prerequisites: list[list[int]]) -> bool:\n indegree = [0] * numCourses\n adj = [[] for x in range(numCourses)]\n for prereq in prerequisites:\n adj[prereq[1]].append(prereq[0])\n indegree[prereq[0]] += 1\n\n queue = []\n\n for i in range(numCourses):\n if indegree[i] == 0:\n queue.append(i)\n\n visited = 0\n while queue:\n node = queue.pop(0)\n visited += 1\n for neighbor in adj[node]:\n indegree[neighbor] -= 1\n if indegree[neighbor] == 0:\n queue.append(neighbor)\n\n return numCourses == visited\n```\n"},"/topological-sort/course-schedule-ii":{"mdx":"---\ntitle: '210. Course Schedule II'\ndescription: There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai\nicon: dot\ntopics:\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Graph Theory\", slug: \"graph\" }\n - { name: \"Topological Sort\", slug: \"topological-sort\" }\nissue: \"https://github.com/prdlk/leetcode/issues/143\"\ncompanies:\n - { name: \"Salesforce\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Walmart Labs\", period: \"Thirty Days\", frequency: 100 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 80.4 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 39.1 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Audible\", period: \"Six Months\", frequency: 100 }\n - { name: \"Aurora\", period: \"Six Months\", frequency: 100 }\n - { name: \"Anduril\", period: \"Six Months\", frequency: 92.8 }\n - { name: \"Netflix\", period: \"Six Months\", frequency: 90.1 }\n - { name: \"DoorDash\", period: \"Six Months\", frequency: 89.7 }\n - { name: \"Snowflake\", period: \"Six Months\", frequency: 79.8 }\n - { name: \"Uber\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'Course Schedule II'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `numCourses = 2, prerequisites = [[1,0]]`\n- Output: `[0,1]`\n- Explanation: There are a total of `2` courses to take. To take course `1` you should have finished course `0`. So the correct course order is `[0,1]`.\n\n### Example 2:\n- Input: `numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]`\n- Output: `[0,2,1,3]`\n- Explanation: There are a total of `4` courses to take. To take course `3` you should have finished both courses `1` and `2`. Both courses `1` and `2` should be taken after you finished course `0`. So one correct course order is `[0,1,2,3]`. Another correct ordering is `[0,2,1,3]`.\n\n### Example 3:\n- Input: `numCourses = 1, prerequisites = []`\n- Output: `[0]`\n\n### Constraints:\n\n- `1 <= numCourses <= 2000`\n- `0 <= prerequisites.length <= numCourses * (numCourses - 1)`\n- `prerequisites[i].length == 2`\n- `0 <= ai, bi < numCourses`\n- `ai != bi`\n- All the pairs [ai, bi] are distinct.\n\n## Solution\n\n```py\nclass Solution:\n def findOrder(self, numCourses: int, prerequisites: list[list[int]]) -> list[int]:\n prereq = {c: [] for c in range(numCourses)}\n for crs, pre in prerequisites:\n prereq[crs].append(pre)\n\n # course has 3 possible states:\n # visited -> crs has been added to output\n # visiting -> crs not added to output, but added to cycle\n # unvisited -> crs not added to output nor cycle\n output = []\n visit, cycle = set(), set()\n\n def dfs(crs):\n if crs in cycle:\n return False\n if crs in visit:\n return True\n\n cycle.add(crs)\n for pre in prereq[crs]:\n if dfs(pre) == False:\n return False\n\n cycle.remove(crs)\n visit.add(crs)\n output.append(crs)\n return True\n\n for c in range(numCourses):\n if dfs(c) == False:\n return []\n\n return output\n```\n"},"/tree-bfs":{"mdx":"---\ntitle: Tree BFS\ndescription: 'All nodes at one level are visited before the nodes at the next level.'\nhidden: true\n---\n"},"/tree-bfs/binary-tree-level-order-traversal":{"mdx":"---\ntitle: '102. Binary Tree Level Order Traversal'\ndescription: Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level)\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"6ZnyEApgFYg\"\nissue: \"https://github.com/prdlk/leetcode/issues/106\"\ncompanies:\n - { name: \"Google\", period: \"Three Months\", frequency: 41 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 28.9 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\nsidebar:\n label: 'Binary Tree Level Order Traversal'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `root = [3,9,20,null,null,15,7]`\n- Output: `[[3],[9,20],[15,7]]`\n\n### Example 2:\n- Input: `root = [1]`\n- Output: `[[1]]`\n\n### Example 3:\n- Input: `root = []`\n- Output: `[]`\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [0, 2000].\n- `-1000 <= Node.val <= 1000`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"levelOrder(root)\"]) --> I[\"res = [], q = deque(), q.append(root)\"]\n I --> W{\"q non-empty?\"}\n W -- no --> E([\"return res\"])\n W -- yes --> L[\"qLen = len(q), level = [] — qLen freezes the current level's size\"]\n L --> F{\"more i in range(qLen)?\"}\n F -- no --> V{\"level non-empty?\"}\n V -- yes --> A[\"res.append(level)\"]\n A --> W\n V -- no --> W\n F -- yes --> P[\"node = q.popleft()\"]\n P --> N{\"node is not None?\"}\n N -- no --> F\n N -- yes --> C[\"level.append(node.val), q.append(node.left), q.append(node.right) — None children are filtered on the next level\"]\n C --> F\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nfrom collections import deque\n\n\nclass Solution:\n # T: O(n) S: O(n)\n def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:\n res = []\n\n q = deque()\n q.append(root)\n\n while q:\n qLen = len(q)\n level = []\n for i in range(qLen):\n node = q.popleft()\n if node:\n level.append(node.val)\n q.append(node.left)\n q.append(node.right)\n if level:\n res.append(level)\n\n return res\n```\n"},"/tree-bfs/binary-tree-right-side-view":{"mdx":"---\ntitle: '199. Binary Tree Right Side View'\ndescription: Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"d4zLyf32e3I\"\nissue: \"https://github.com/prdlk/leetcode/issues/107\"\ncompanies:\n - { name: \"Yandex\", period: \"Three Months\", frequency: 76.1 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 42.8 }\n - { name: \"Google\", period: \"Three Months\", frequency: 23.9 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 62.3 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 32 }\nsidebar:\n label: 'Binary Tree Right Side View'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `root = [1,2,3,null,5,null,4]`\n- Output: `[1,3,4]`\n\n### Example 2:\n- Input: `root = [1,2,3,4,null,null,null,5]`\n- Output: `[1,3,4,5]`\n\n### Example 3:\n- Input: `root = [1,null,3]`\n- Output: `[1,3]`\n\n### Example 4:\n- Input: `root = []`\n- Output: `[]`\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [0, 100].\n- `-100 <= Node.val <= 100`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"rightSideView(root)\"]) --> I[\"res = [], q = deque([root])\"]\n I --> W{\"q non-empty?\"}\n W -- no --> E([\"return res\"])\n W -- yes --> L[\"rightSide = None, qLen = len(q) — qLen freezes the current level's size\"]\n L --> F{\"more i in range(qLen)?\"}\n F -- no --> V{\"rightSide is not None?\"}\n V -- yes --> A[\"res.append(rightSide.val) — the last real node popped on this level is the rightmost\"]\n A --> W\n V -- no --> W\n F -- yes --> P[\"node = q.popleft()\"]\n P --> N{\"node is not None?\"}\n N -- no --> F\n N -- yes --> C[\"rightSide = node, q.append(node.left), q.append(node.right)\"]\n C --> F\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nfrom collections import deque\n\n\nclass Solution:\n def rightSideView(self, root: Optional[TreeNode]) -> List[int]:\n res = []\n q = deque([root])\n\n while q:\n rightSide = None\n qLen = len(q)\n\n for i in range(qLen):\n node = q.popleft()\n if node:\n rightSide = node\n q.append(node.left)\n q.append(node.right)\n\n if rightSide:\n res.append(rightSide.val)\n\n return res\n```\n"},"/tree-bfs/count-good-nodes-in-binary-tree":{"mdx":"---\ntitle: '1448. Count Good Nodes in Binary Tree'\ndescription: Given a binary tree root, a node X in the tree is named good if in the path from root to X there are no nodes with a value greater than X\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"7cp5imvDzl4\"\nissue: \"https://github.com/prdlk/leetcode/issues/108\"\ncompanies:\n - { name: \"josh technology\", period: \"Six Months\", frequency: 74 }\n - { name: \"Google\", period: \"Six Months\", frequency: 11.8 }\nsidebar:\n label: 'Count Good Nodes in Binary Tree'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `root = [3,1,4,3,null,1,5]`\n- Output: `4`\n- Explanation: Nodes in blue are good. Root Node `(3`) is always a good node. Node `4` -> (3,4) is the maximum value in the path starting from the `root`. Node `5` -> (3,4,5) is the maximum value in the path Node `3` -> (3,1,3) is the maximum value in the path.\n\n### Example 2:\n- Input: `root = [3,3,null,4,2]`\n- Output: `3`\n- Explanation: Node `2` -> `(3`, `3`, `2`) is not good, because `\"3`\" is higher than it.\n\n### Example 3:\n- Input: `root = [1]`\n- Output: `1`\n- Explanation: Root is considered as good.\n\n### Constraints:\n\n- The number of nodes in the binary tree is in the range [1, 10^5].\n- Each node's value is between [-10^4, 10^4].\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"goodNodes(root)\"]) --> C[\"dfs(root, root.val) — the root is always good\"]\n C --> E([\"return that count\"])\n subgraph dfs[\"dfs(node, max_val)\"]\n D1{\"node is None?\"} -- yes --> D2([\"return 0\"])\n D1 -- no --> D3[\"is_good = 1 if node.val >= max_val else 0 — max_val is the largest value on the path so far\"]\n D3 --> D4[\"new_max = max(max_val, node.val)\"]\n D4 --> D5[\"l = dfs(node.left, new_max), r = dfs(node.right, new_max)\"]\n D5 --> D6([\"return is_good + l + r\"])\n end\n C --> dfs\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nclass Solution:\n def goodNodes(self, root: TreeNode) -> int:\n def dfs(node, max_val):\n if not node:\n return 0\n\n is_good = 1 if node.val >= max_val else 0\n new_max = max(max_val, node.val)\n\n return is_good + dfs(node.left, new_max) + dfs(node.right, new_max)\n\n return dfs(root, root.val)\n```\n"},"/tree-dfs":{"mdx":"---\ntitle: Tree DFS\ndescription: 'Each branch is followed to its end before the next branch is examined.'\nhidden: true\n---\n"},"/tree-dfs/invert-binary-tree":{"mdx":"---\ntitle: '226. Invert Binary Tree'\ndescription: Given the root of a binary tree, invert the tree, and return its root\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"OnSn2XEQ4MY\"\nissue: \"https://github.com/prdlk/leetcode/issues/96\"\ncompanies:\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 57.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Invert Binary Tree'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `root = [4,2,7,1,3,6,9]`\n- Output: `[4,7,2,9,6,3,1]`\n\n### Example 2:\n- Input: `root = [2,1,3]`\n- Output: `[2,3,1]`\n\n### Example 3:\n- Input: `root = []`\n- Output: `[]`\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [0, 100].\n- `-100 <= Node.val <= 100`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"invertTree(root)\"]) --> B{\"root is None?\"}\n B -- yes --> Z([\"return None\"])\n B -- no --> L[\"left = invertTree(root.left), right = invertTree(root.right) — both subtrees are already inverted\"]\n L --> X[\"root.left = right, root.right = left\"]\n X --> E([\"return root\"])\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nclass Solution:\n def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:\n if not root:\n return None\n\n left = self.invertTree(root.left)\n right = self.invertTree(root.right)\n\n root.left = right\n root.right = left\n\n return root\n```\n"},"/tree-dfs/lowest-common-ancestor-of-a-binary-tree":{"mdx":"---\ntitle: '236. Lowest Common Ancestor of a Binary Tree'\ndescription: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\n - { name: \"Binary Lifting\", slug: \"binary-lifting\" }\n - { name: \"Lowest Common Ancestor\", slug: \"lowest-common-ancestor\" }\nissue: \"https://github.com/prdlk/leetcode/issues/98\"\ncompanies:\n - { name: \"BlackRock\", period: \"Thirty Days\", frequency: 76.6 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 55.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 36.7 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 36.8 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 56.1 }\nsidebar:\n label: 'Lowest Common Ancestor of a Binary Tree'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1`\n- Output: `3`\n- Explanation: The LCA of nodes `5` and `1` is `3`.\n\n### Example 2:\n- Input: `root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4`\n- Output: `5`\n- Explanation: The LCA of nodes `5` and `4` is `5`, since a node can be a descendant of itself according to the LCA definition.\n\n### Example 3:\n- Input: `root = [1,2], p = 1, q = 2`\n- Output: `1`\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [2, 10^5].\n- `-10^9 <= Node.val <= 10^9`\n- All Node.val are unique.\n- `p != q`\n- p and q will exist in the tree.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"lowestCommonAncestor(root, p, q)\"]) --> B{\"not root?\"}\n B -- yes --> N([\"return None\"])\n B -- no --> M{\"root == p or root == q?\"}\n M -- yes --> R([\"return root — a node is its own ancestor\"])\n M -- no --> L[\"l = self.lowestCommonAncestor(root.left, p, q)\"]\n L --> Q[\"r = self.lowestCommonAncestor(root.right, p, q)\"]\n Q --> D{\"l and r?\"}\n D -- yes --> A([\"return root — p and q were found on different sides\"])\n D -- no --> E([\"return l or r — pass up whichever side found something\"])\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, x):\n# self.val = x\n# self.left = None\n# self.right = None\n\n\nclass Solution:\n def lowestCommonAncestor(\n self, root: \"TreeNode\", p: \"TreeNode\", q: \"TreeNode\"\n ) -> \"TreeNode\":\n\n if not root:\n return None\n\n if root == p or root == q:\n return root\n\n l = self.lowestCommonAncestor(root.left, p, q)\n r = self.lowestCommonAncestor(root.right, p, q)\n\n if l and r:\n return root\n else:\n return l or r\n```\n"},"/tree-dfs/maximum-depth-of-binary-tree":{"mdx":"---\ntitle: '104. Maximum Depth of Binary Tree'\ndescription: Given the root of a binary tree, return its maximum depth\nicon: dot\ntopics:\n - { name: \"Tree\", slug: \"tree\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Binary Tree\", slug: \"binary-tree\" }\nvideo: \"hTM3phVI6YQ\"\nissue: \"https://github.com/prdlk/leetcode/issues/97\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"LinkedIn\", period: \"Six Months\", frequency: 54.1 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Maximum Depth of Binary Tree'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `root = [3,9,20,null,null,15,7]`\n- Output: `3`\n\n### Example 2:\n- Input: `root = [1,null,2]`\n- Output: `2`\n\n### Constraints:\n\n- The number of nodes in the tree is in the range [0, 10^4].\n- `-100 <= Node.val <= 100`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"maxDepth(root)\"]) --> B{\"root is None?\"}\n B -- yes --> Z([\"return 0\"])\n B -- no --> L[\"l = maxDepth(root.left), r = maxDepth(root.right)\"]\n L --> E([\"return 1 + max(l, r) — this node adds one level above its deeper subtree\"])\n```\n\n## Solution\n\n```py\n# Definition for a binary tree node.\n# class TreeNode:\n# def __init__(self, val=0, left=None, right=None):\n# self.val = val\n# self.left = left\n# self.right = right\nclass Solution:\n def maxDepth(self, root: Optional[TreeNode]) -> int:\n if not root:\n return 0\n\n return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))\n```\n"},"/trie":{"mdx":"---\ntitle: Trie\ndescription: 'Each node holds one character, and a path from the root spells a word.'\nhidden: true\n---\n"},"/trie/design-add-and-search-words-data-structure":{"mdx":"---\ntitle: '211. Design Add and Search Words Data Structure'\ndescription: Design a data structure that supports adding new words and finding if a string matches any previously added string\nicon: dot\ntopics:\n - { name: \"String\", slug: \"string\" }\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Design\", slug: \"design\" }\n - { name: \"Trie\", slug: \"trie\" }\nvideo: \"BTf05gs_8iU\"\nissue: \"https://github.com/prdlk/leetcode/issues/128\"\ncompanies:\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"Snowflake\", period: \"Six Months\", frequency: 58.7 }\nsidebar:\n label: 'Design Add and Search Words Data Structure'\n badge: 'Medium'\n---\n\n### Constraints:\n\n- `1 <= word.length <= 25`\n- `word` in addWord consists of lowercase English letters.\n- `word` in search consist of '.' or lowercase English letters.\n- There will be at most 2 dots in `word` for search queries.\n- At most 10^4 calls will be made to addWord and search.\n\n## Approach\n\n```mermaid\nflowchart TD\n subgraph state[\"state — root TrieNode; every node holds a children dict and an endOfWord flag\"]\n R[\"root\"] --- C[\"... children[c] ...\"] --- L[\"endOfWord = True — a word ends here\"]\n end\n subgraph addWord[\"addWord(word)\"]\n A1[\"cur = root\"] --> A2{\"more c in word?\"}\n A2 -- yes --> A3{\"c not in cur.children?\"}\n A3 -- yes --> A4[\"cur.children[c] = TrieNode()\"]\n A4 --> A5[\"cur = cur.children[c]\"]\n A3 -- no --> A5\n A5 --> A2\n A2 -- no --> A6[\"cur.endOfWord = True\"]\n A6 --> A7([\"done\"])\n end\n subgraph search[\"search(word)\"]\n S1[\"dfs(0, root) — match from index 0 at the root\"] --> S2[\"cur = root\"]\n S2 --> S3{\"more i in range(j, len(word))?\"}\n S3 -- no --> S4([\"return cur.endOfWord\"])\n S3 -- yes --> S5[\"c = word[i]\"]\n S5 --> S6{\"c == '.'?\"}\n S6 -- yes --> S7{\"more child in cur.children.values()?\"}\n S7 -- yes --> S8{\"dfs(i + 1, child)? — try the rest of the word from this child\"}\n S8 -- yes --> S9([\"return True\"])\n S8 -- no --> S7\n S7 -- no --> S10([\"return False — no child matched the wildcard\"])\n S6 -- no --> S11{\"c not in cur.children?\"}\n S11 -- yes --> S12([\"return False\"])\n S11 -- no --> S13[\"cur = cur.children[c]\"]\n S13 --> S3\n end\n state --> addWord\n state --> search\n```\n\n## Solution\n\n```py\nclass TrieNode:\n def __init__(self):\n self.children = {}\n self.endOfWord = False\n\n\nclass WordDictionary:\n def __init__(self):\n self.root = TrieNode()\n\n def addWord(self, word: str) -> None:\n cur = self.root\n for c in word:\n if c not in cur.children:\n cur.children[c] = TrieNode()\n cur = cur.children[c]\n cur.endOfWord = True\n\n # Leverage Recursion\n def search(self, word: str) -> bool:\n def dfs(j, root):\n cur = root\n for i in range(j, len(word)):\n c = word[i]\n\n if c == \".\":\n for child in cur.children.values():\n if dfs(i + 1, child):\n return True\n return False\n else:\n if c not in cur.children:\n return False\n cur = cur.children[c]\n return cur.endOfWord\n\n return dfs(0, self.root)\n\n\n# Your WordDictionary object will be instantiated and called as such:\n# obj = WordDictionary()\n# obj.addWord(word)\n# param_3 = obj.search(word)\n```\n"},"/trie/implement-trie-prefix-tree":{"mdx":"---\ntitle: '208. Implement Trie (Prefix Tree)'\ndescription: A trie (pronounced as \"try\") or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker\nicon: dot\ntopics:\n - { name: \"Hash Table\", slug: \"hash-table\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Design\", slug: \"design\" }\n - { name: \"Trie\", slug: \"trie\" }\nvideo: \"oobqoCJlHA0\"\nissue: \"https://github.com/prdlk/leetcode/issues/127\"\ncompanies:\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 48.1 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 37.9 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 34.2 }\nsidebar:\n label: 'Implement Trie (Prefix Tree)'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: ``\n- Output: ``\n- Explanation: Input [\"Trie\", \"insert\", \"search\", \"search\", \"startsWith\", \"insert\", \"search\"] `[[]`, `[\"apple\"]`, `[\"apple\"]`, `[\"app\"]`, `[\"app\"]`, `[\"app\"]`, [\"app\"]] Output [null, null, true, false, true, null, true] Explanation Trie trie = new Trie(); trie.insert(\"apple\"); trie.search(\"apple\"); // return True trie.search(\"app\"); // return False trie.startsWith(\"app\"); // return True trie.insert(\"app\"); trie.search(\"app\"); // return True\n\n### Constraints:\n\n- `1 <= word.length, prefix.length <= 2000`\n- `word` and `prefix` consist only of lowercase English letters.\n- At most 3 * 10^4 calls in total will be made to insert, search, and startsWith.\n\n## Approach\n\n```mermaid\nflowchart TD\n subgraph state[\"state — root TrieNode; every node holds a children dict and an endOfWord flag\"]\n R[\"root\"] --- C[\"... children[c] ...\"] --- L[\"endOfWord = True — a word ends here\"]\n end\n subgraph insert[\"insert(word)\"]\n I1[\"cur = root\"] --> I2{\"more c in word?\"}\n I2 -- yes --> I3{\"c not in cur.children?\"}\n I3 -- yes --> I4[\"cur.children[c] = TrieNode()\"]\n I4 --> I5[\"cur = cur.children[c]\"]\n I3 -- no --> I5\n I5 --> I2\n I2 -- no --> I6[\"cur.endOfWord = True\"]\n I6 --> I7([\"done\"])\n end\n subgraph search[\"search(word)\"]\n S1[\"cur = root\"] --> S2{\"more c in word?\"}\n S2 -- yes --> S3{\"c not in cur.children?\"}\n S3 -- yes --> S4([\"return False\"])\n S3 -- no --> S5[\"cur = cur.children[c]\"]\n S5 --> S2\n S2 -- no --> S6([\"return cur.endOfWord — the path exists, but is it a whole word?\"])\n end\n subgraph startsWith[\"startsWith(prefix)\"]\n P1[\"cur = root\"] --> P2{\"more c in prefix?\"}\n P2 -- yes --> P3{\"c not in cur.children?\"}\n P3 -- yes --> P4([\"return False\"])\n P3 -- no --> P5[\"cur = cur.children[c]\"]\n P5 --> P2\n P2 -- no --> P6([\"return True — every prefix char had a path\"])\n end\n state --> insert\n state --> search\n state --> startsWith\n```\n\n## Solution\n\n```py\nclass TrieNode:\n def __init__(self):\n self.children = {}\n self.endOfWord = False\n\n\nclass Trie:\n def __init__(self):\n self.root = TrieNode()\n\n def insert(self, word: str) -> None:\n cur = self.root\n\n for c in word:\n if c not in cur.children:\n cur.children[c] = TrieNode()\n cur = cur.children[c]\n cur.endOfWord = True\n\n def search(self, word: str) -> bool:\n cur = self.root\n\n for c in word:\n if c not in cur.children:\n return False\n cur = cur.children[c]\n\n return cur.endOfWord\n\n def startsWith(self, prefix: str) -> bool:\n cur = self.root\n\n for c in prefix:\n if c not in cur.children:\n return False\n cur = cur.children[c]\n\n return True\n\n\n# Your Trie object will be instantiated and called as such:\n# obj = Trie()\n# obj.insert(word)\n# param_2 = obj.search(word)\n# param_3 = obj.startsWith(prefix)\n```\n"},"/two-pointers":{"mdx":"---\ntitle: Two Pointers\ndescription: 'Two indices move through the data from different positions and meet at the answer.'\nhidden: true\n---\n\nMost interview problems in this section fall into one of four families:\n\n- **Same direction pointers**: one pointer reads, one pointer writes, or one pointer stays behind another while scanning left to right.\n- **Opposite direction pointers**: one pointer starts on the left, one on the right, and each move eliminates impossible answers.\n- **Sliding window**: the two pointers define a contiguous interval, and you maintain some property of that interval as the window expands and shrinks.\n- **Fast and slow pointers**: both pointers move through a linked structure, but at different speeds or with a fixed gap.\n\n\n\n## Same Direction\n\nSame-direction pointer problems usually scan from left to right, but the two pointers do different jobs.\n\nUsually:\n\n- one pointer reads the next value from the original input\n- one pointer marks where the next kept value should go\n\nSometimes both pointers move forward together, but one pointer stays behind the other to preserve a gap or a relationship.\n\n### When this family applies\n\n\nReach for same-direction pointers when the problem asks you to:\n\n- rewrite an array in-place\n- remove or compress elements without extra memory\n- keep only the values that satisfy some condition\n- maintain a fixed gap between two forward-moving pointers\n\n### Core Invariant\n\nThe invariant in this family is usually about the prefix you have already processed.\n\nTypical invariant:\n\n> \"Everything before the write pointer is already in the correct final form.\"\n\nThat is what makes these problems feel different from opposite-direction scans. You are not searching from both sides. You are building the answer progressively as you sweep through the input.\n\n### Subtypes in this section\n\n#### 1. Compaction / Overwrite\n\nThe slow pointer marks the next output position. The fast pointer scans the input. When the current value should be kept, copy it forward and advance the slow pointer.\n\n\n\n#### 2. Relative Speed\n\nBoth pointers move forward, but one moves twice as fast. The invariant is about their distance and how much of the structure each pointer has consumed.\n\n\n\n#### 3. Fixed Gap\n\nBoth pointers move forward while preserving a gap. The invariant is not about a rewritten prefix. It is about the distance between the pointers.\n\n\n\n### What changes across problems\n\nThe family stays the same, but the invariant changes slightly:\n\n- in array compaction, the invariant is about the prefix being correct\n- in fast/slow midpoint problems, the invariant is about relative speed\n- in fixed-gap problems, the invariant is about distance\n\nSo the unifying idea is not \"both pointers move right.\" The unifying idea is:\n\n**\"the structure to the left of the pointers already has a known meaning\"**\n\n### What to watch out for\n\nCommon mistakes:\n\n- Updating the write pointer before copying the current value.\n- Forgetting exactly what region is already valid.\n- Losing track of whether the invariant is about a prefix, a gap, or relative speed.\n\nAs you go through the following problems, pay attention to one question:\n\n**What does the region before the slow pointer mean right now?**\n\n## Opposite Direction\n\nOpposite-direction pointer problems place one pointer on the left and one on the right, then move inward.\n\nThe hard part is never the loop itself. **The hard part is justifying which pointer is safe to move.**\n\n### When this family applies\n\nReach for opposite-direction pointers when the problem asks you to:\n\n- the input is sorted, or can be made monotonic by sorting\n- you are comparing a left choice and a right choice\n- the problem has symmetry\n- moving one side lets you eliminate a set of impossible answers\n\n### Core Invariant\n\nThe invariant in this family is usually:\n\n> \"All candidate answers outside the current `[left, right]` range have already been ruled out.\"\n\nThat means each move must come with a proof. If you move a pointer without knowing why the discarded cases cannot contain the optimum, the algorithm is just guessing.\n\n### Subtypes in this section\n\n#### 1. Monotonic sum elimination\n\n\nBecause the array is sorted:\n\n- if the sum is too small, moving the left pointer right is the only useful move\n- if the sum is too large, moving the right pointer left is the only useful move\n\nSorted order gives you a monotonic rule.\n\n\n\n#### 2. Symmetry checking\n\nHere the pointers compare mirrored positions. The movement rule is mostly \"move both,\" except when you must skip punctuation or spaces.\n\n\n\n#### 3. Bottleneck elimination\n\nThis one is important because it looks different from the other two. The key idea is that the shorter wall limits the area. If you keep that shorter wall and decrease the width, you cannot improve the answer. So it is safe to discard that wall.\n\n\n\n### Why this is not a sliding window\n\nOpposite-direction scans do not maintain an interval property like \"this window is valid.\"\n\nInstead, each step does one of these:\n\n- rules out sums that are too small or too large\n- checks mirrored characters\n- discards a bottleneck boundary\n\nThe interval itself is just the remaining search space.\n\n### What to watch out for\n\nCommon mistakes:\n\n- Using two pointers on an unsorted pair problem without first creating monotonicity.\n- Moving the taller wall in Container With Most Water without an elimination proof.\n- Calling the method sliding window just because two boundaries exist.\n\nAs you read the problems in this family, keep asking:\n\n**What exact set of candidate answers did this pointer move eliminate?**\n"},"/two-pointers/3sum":{"mdx":"---\ntitle: '15. 3Sum'\ndescription: Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Sorting\", slug: \"sorting\" }\nvideo: \"jzZsG8n2R9A\"\nissue: \"https://github.com/prdlk/leetcode/issues/43\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 69.6 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 66.8 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 63.8 }\n - { name: \"Apple\", period: \"Three Months\", frequency: 80.4 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Cisco\", period: \"Six Months\", frequency: 100 }\n - { name: \"Wissen Technology\", period: \"Six Months\", frequency: 100 }\n - { name: \"eBay\", period: \"Six Months\", frequency: 75.2 }\n - { name: \"Accenture\", period: \"Six Months\", frequency: 75 }\n - { name: \"Visa\", period: \"Six Months\", frequency: 69.7 }\n - { name: \"Goldman Sachs\", period: \"Six Months\", frequency: 53.1 }\nsidebar:\n label: '3Sum'\n badge: 'Medium'\n---\n\n::::warning\nNotice that the solution set must not contain duplicate triplets.\n::::\n\n### Example 1:\n- Input: `nums = [-1,0,1,2,-1,-4]`\n- Output: `[[-1,-1,2],[-1,0,1]]`\n- Explanation: `nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0`. `nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0`. `nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0`. The distinct triplets are `[-1,0,1]` and `[-1,-1,2]`. Notice that the order of the output and the order of the triplets does not matter.\n\n### Example 2:\n- Input: `nums = [0,1,1]`\n- Output: `[]`\n- Explanation: The only possible triplet does not sum up to `0`.\n\n### Example 3:\n- Input: `nums = [0,0,0]`\n- Output: `[[0,0,0]]`\n- Explanation: The only possible triplet sums up to `0`.\n\n### Constraints:\n\n- `3 <= nums.length <= 3000`\n- `-10^5 <= nums[i] <= 10^5`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"threeSum(nums)\"]) --> O[\"nums.sort() — duplicates become adjacent\"]\n O --> F{\"more i in 0..n-1?\"}\n F -- no --> E([\"return result\"])\n F -- yes --> D{\"nums[i] == nums[i-1]?\"}\n D -- yes --> F\n D -- no --> P[\"left = i+1, right = n-1, target = -nums[i]\"]\n P --> W{\"left < right?\"}\n W -- no --> F\n W -- yes --> C[\"current = nums[left] + nums[right]\"]\n C --> Q{\"current vs target\"}\n Q -- equal --> A[\"append triplet, skip equal neighbours, left += 1, right -= 1\"]\n A --> W\n Q -- \"current < target\" --> L[\"left += 1 — need a bigger sum\"]\n L --> W\n Q -- \"current > target\" --> R[\"right -= 1 — need a smaller sum\"]\n R --> W\n```\n\n## Solution\n\n```py\nclass Solution:\n def threeSum(self, nums: list[int]) -> list[list[int]]:\n nums.sort()\n result = []\n n = len(nums)\n\n for i in range(n):\n # skip all zero\n if i > 0 and nums[i] == nums[i - 1]:\n continue\n\n # two pointers\n left = i + 1\n right = n - 1\n target = -nums[i]\n\n while left < right:\n current = nums[left] + nums[right]\n\n if current == target:\n result.append([nums[i], nums[left], nums[right]])\n\n # skip duplicates\n while left < right and nums[left] == nums[left + 1]:\n left += 1\n while left < right and nums[right] == nums[right - 1]:\n right -= 1\n\n # shift pointers\n left += 1\n right -= 1\n\n # since sorted, if current < target, then move left\n elif current < target:\n left += 1\n # since sorted, if current > target, then move right\n else:\n right -= 1\n\n return result\n```\n"},"/two-pointers/container-with-most-water":{"mdx":"---\ntitle: '11. Container With Most Water'\ndescription: You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the i^th line are (i, 0) and (i, height[i])\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Greedy\", slug: \"greedy\" }\nvideo: \"UuiTKBwPgAo\"\nissue: \"https://github.com/prdlk/leetcode/issues/44\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 83.1 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 75.8 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 68.6 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 67.6 }\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 65.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 62 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Goldman Sachs\", period: \"Three Months\", frequency: 57 }\n - { name: \"Walmart Labs\", period: \"Six Months\", frequency: 70.5 }\n - { name: \"IBM\", period: \"Six Months\", frequency: 60.1 }\nsidebar:\n label: 'Container With Most Water'\n badge: 'Medium'\n---\n\n::::warning\nNotice that you may not slant the container.\n::::\n\n### Example 1:\n- Input: `height = [1,8,6,2,5,4,8,3,7]`\n- Output: `49`\n- Explanation: The above vertical lines are represented by array `[1,8,6,2,5,4,8,3,7]`. In this case, the max area of water (blue section) the container can contain is `49`.\n\n### Example 2:\n- Input: `height = [1,1]`\n- Output: `1`\n\n### Constraints:\n\n- `n == height.length`\n- `2 <= n <= 10^5`\n- `0 <= height[i] <= 10^4`\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"maxArea(height)\"]) --> I[\"res = 0, left = 0, right = len - 1\"]\n I --> W{\"left < right?\"}\n W -- no --> E([\"return res\"])\n W -- yes --> A[\"area = (right - left) * min(height[left], height[right])\"]\n A --> M[\"res = max(res, area)\"]\n M --> C{\"height[left] < height[right]?\"}\n C -- yes --> L[\"left += 1 — drop the shorter wall\"]\n C -- no --> R[\"right -= 1 — drop the shorter wall\"]\n L --> W\n R --> W\n```\n\n## Solution\n\n```py\nclass Solution:\n def maxArea(self, height: List[int]) -> int: # noqa: F821\n res = 0\n left = 0\n right = len(height) - 1\n\n while left < right:\n area = (right - left) * min(height[left], height[right])\n res = max(res, area)\n if height[left] < height[right]:\n left += 1\n else:\n right -= 1\n\n return res\n```\n"},"/two-pointers/is-subsequence":{"mdx":"---\ntitle: '392. Is Subsequence'\ndescription: Given two strings s and t, return true if s is a subsequence of t, or false otherwise\nicon: dot\ntopics:\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"String\", slug: \"string\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\nvideo: \"99RVfqklbCE\"\nissue: \"https://github.com/prdlk/leetcode/issues/45\"\ncompanies:\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\n - { name: \"Google\", period: \"Six Months\", frequency: 25.4 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 24.5 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Is Subsequence'\n badge: 'Easy'\n---\n\n::::warning\nSuppose there are lots of incoming s, say s1, s2, ..., sk where k >= 10^9, and you want to check one by one to see if t has its subsequence. In this scenario, how would you change your code?\n::::\n\n### Example 1:\n- Input: `s = \"abc\", t = \"ahbgdc\"`\n- Output: `true`\n\n### Example 2:\n- Input: `s = \"axc\", t = \"ahbgdc\"`\n- Output: `false`\n\n### Constraints:\n\n- `0 <= s.length <= 100`\n- `0 <= t.length <= 10^4`\n- `s` and `t` consist only of lowercase English letters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"isSubsequence(s, t)\"]) --> G{\"len(s) > len(t)?\"}\n G -- yes --> X([\"return False\"])\n G -- no --> I[\"i = 0 into s, j = 0 into t\"]\n I --> W{\"i < len(s) and j < len(t)?\"}\n W -- no --> E([\"return i == len(s) — every char of s was matched\"])\n W -- yes --> Q{\"s[i] == t[j]?\"}\n Q -- yes --> A[\"i += 1 — consume the match\"]\n Q -- no --> B[\"j += 1 — always advance t\"]\n A --> B\n B --> W\n```\n\n## Solution\n\n```py\nclass Solution:\n def isSubsequence(self, s: str, t: str) -> bool:\n if len(s) > len(t):\n return False\n\n i, j = 0, 0\n while i < len(s) and j < len(t):\n if s[i] == t[j]:\n i += 1\n j += 1\n\n return i == len(s)\n```\n"},"/two-pointers/remove-duplicates-from-sorted-array-ii":{"mdx":"---\ntitle: '80. Remove Duplicates from Sorted Array II'\ndescription: Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\nissue: \"https://github.com/prdlk/leetcode/issues/48\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 34.6 }\n - { name: \"Meta\", period: \"Six Months\", frequency: 32.7 }\nsidebar:\n label: 'Remove Duplicates from Sorted Array II'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,1,1,2,2,3]`\n- Output: `5, nums = [1,1,2,2,3,_]`\n- Explanation: Your function should return `k = 5`, with the first five elements of `nums` being `1`, `1`, `2`, `2` and `3` respectively. It does not matter what you leave beyond the returned `k` (hence they are underscores).\n\n### Example 2:\n- Input: `nums = [0,0,1,1,1,1,2,3,3]`\n- Output: `7, nums = [0,0,1,1,2,3,3,_,_]`\n- Explanation: Your function should return `k = 7`, with the first seven elements of `nums` being `0`, `0`, `1`, `1`, `2`, `3` and `3` respectively. It does not matter what you leave beyond the returned `k` (hence they are underscores).\n\n### Constraints:\n\n- `1 <= nums.length <= 3 * 10^4`\n- `-10^4 <= nums[i] <= 10^4`\n- `nums` is sorted in non-decreasing order.\n\n## Solution\n\n```py\nclass Solution:\n def removeDuplicates(self, nums: list[int]) -> int:\n slow = 0\n for fast in range(len(nums)):\n if slow < 2 or nums[fast] != nums[slow - 2]:\n nums[slow] = nums[fast]\n slow += 1\n return slow\n```\n"},"/two-pointers/reverse-string":{"mdx":"---\ntitle: '344. Reverse String'\ndescription: Write a function that reverses a string. The input string is given as an array of characters s\nicon: dot\ntopics:\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"String\", slug: \"string\" }\nvideo: \"_d0T_2Lk2qA\"\ncompanies:\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 58.2 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 50.2 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 48.3 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 46.8 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 34.5 }\n - { name: \"Qualcomm\", period: \"Six Months\", frequency: 80.7 }\nsidebar:\n label: 'Reverse String'\n badge: 'Easy'\n---\n\n:::warning\nYou must do this by modifying the input array in-place with O(1) extra memory.\n:::\n\n### Example 1:\n- Input: `s = [\"h\",\"e\",\"l\",\"l\",\"o\"]`\n- Output: `[\"o\",\"l\",\"l\",\"e\",\"h\"]`\n\n### Example 2:\n- Input: `s = [\"H\",\"a\",\"n\",\"n\",\"a\",\"h\"]`\n- Output: `[\"h\",\"a\",\"n\",\"n\",\"a\",\"H\"]`\n\n### Constraints:\n\n- `1 <= s.length <= 10^5`\n- `s[i]` is a printable ascii character.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"reverseString(s)\"]) --> I[\"i = 0, j = s.length - 1\"]\n I --> W{\"i < j?\"}\n W -- no --> E([\"done — s was reversed in place, nothing returned\"])\n W -- yes --> A[\"swap s[i] and s[j]\"]\n A --> B[\"i++; j--\"]\n B --> W\n```\n\n## Solution\n\n```js\n/**\n * @param {character[]} s\n * @return {void} Do not return anything, modify s in-place instead.\n */\nvar reverseString = function(s) {\n let i = 0;\n let j = s.length - 1;\n \n while (i < j) {\n [s[i], s[j]] = [s[j], s[i]];\n j--;\n i++;\n } \n};\n```\n"},"/two-pointers/rotate-array":{"mdx":"---\ntitle: '189. Rotate Array'\ndescription: Given an integer array nums, rotate the array to the right by k steps, where k is non-negative\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Math\", slug: \"math\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\nissue: \"https://github.com/prdlk/leetcode/issues/47\"\ncompanies:\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Microsoft\", period: \"Thirty Days\", frequency: 67.9 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 48.9 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 46.6 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 54.8 }\n - { name: \"Box\", period: \"Six Months\", frequency: 100 }\n - { name: \"TikTok\", period: \"Six Months\", frequency: 55.2 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 48.1 }\nsidebar:\n label: 'Rotate Array'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `nums = [1,2,3,4,5,6,7], k = 3`\n- Output: `[5,6,7,1,2,3,4]`\n- Explanation: rotate `1` steps to the right: `[7,1,2,3,4,5,6]` rotate `2` steps to the right: `[6,7,1,2,3,4,5]` rotate `3` steps to the right: `[5,6,7,1,2,3,4]`\n\n### Example 2:\n- Input: `nums = [-1,-100,3,99], k = 2`\n- Output: `[3,99,-1,-100]`\n- Explanation: rotate `1` steps to the right: `[99,-1,-100,3]` rotate `2` steps to the right: `[3,99,-1,-100]`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^5`\n- `-2^31 <= nums[i] <= 2^31 - 1`\n- `0 <= k <= 10^5`\n- Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.\n- Could you do it in-place with O(1) extra space?\n\n## Solution\n\n```py\nclass Solution:\n def rotate(self, nums: list[int], k: int) -> None:\n N = len(nums) - 1\n cut = k % len(nums)\n\n def reverse(l, r):\n while l <= r:\n nums[l], nums[r] = nums[r], nums[l]\n l += 1\n r -= 1\n\n reverse(0, N)\n reverse(0, cut - 1)\n reverse(cut, N)\n```\n"},"/two-pointers/squares-of-a-sorted-array":{"mdx":"---\ntitle: '977. Squares of a Sorted Array'\ndescription: Given an integer array nums sorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Sorting\", slug: \"sorting\" }\nvideo: \"FPCZsG_AkUg\"\nissue: \"https://github.com/prdlk/leetcode/issues/46\"\ncompanies:\n - { name: \"Google\", period: \"Thirty Days\", frequency: 42.3 }\n - { name: \"Instacart\", period: \"Three Months\", frequency: 100 }\n - { name: \"Uber\", period: \"Three Months\", frequency: 80 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 54 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 49.8 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 46 }\n - { name: \"tcs\", period: \"Six Months\", frequency: 60 }\n - { name: \"Yandex\", period: \"Six Months\", frequency: 59.6 }\nsidebar:\n label: 'Squares of a Sorted Array'\n badge: 'Easy'\n---\n\n::::warning\nSquaring each element and sorting the new array is very trivial, could you find an O(n) solution using a different approach?\n::::\n\n### Example 1:\n- Input: `nums = [-4,-1,0,3,10]`\n- Output: `[0,1,9,16,100]`\n- Explanation: After squaring, the array becomes `[16,1,0,9,100]`. After sorting, it becomes `[0,1,9,16,100]`.\n\n### Example 2:\n- Input: `nums = [-7,-3,2,3,11]`\n- Output: `[4,9,9,49,121]`\n\n### Constraints:\n\n- `1 <= nums.length <= 10^4`\n- `-10^4 <= nums[i] <= 10^4`\n- `nums` is sorted in non-decreasing order.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"sortedSquares(nums)\"]) --> I[\"ans = Array(n), left = 0, right = n - 1\"]\n I --> L{\"more i from n-1 down to 0?\"}\n L -- no --> E([\"return ans\"])\n L -- yes --> C{\"abs(nums[left]) < abs(nums[right])?\"}\n C -- yes --> R[\"square = nums[right]; right--\"]\n C -- no --> F[\"square = nums[left]; left++\"]\n R --> W[\"ans[i] = square * square — fill from the back, largest first\"]\n F --> W\n W --> L\n```\n\n## Solution\n\n```js\n/**\n * @param {number[]} nums\n * @return {number[]}\n */\nvar sortedSquares = function(nums) {\n let n = nums.length;\n let ans = new Array(nums.length);\n let left = 0, right = nums.length - 1;\n\n for (let i = n -1; i >= 0; i--){\n let square;\n if(Math.abs(nums[left]) < Math.abs(nums[right])){\n square = nums[right];\n right--;\n }else{\n square = nums[left];\n left++;\n }\n ans[i] = square*square;\n }\n return ans;\n};\n```\n"},"/two-pointers/trapping-rain-water":{"mdx":"---\ntitle: '42. Trapping Rain Water'\ndescription: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Dynamic Programming\", slug: \"dynamic-programming\" }\n - { name: \"Stack\", slug: \"stack\" }\n - { name: \"Monotonic Stack\", slug: \"monotonic-stack\" }\nissue: \"https://github.com/prdlk/leetcode/issues/211\"\ncompanies:\n - { name: \"Ola Cabs\", period: \"Thirty Days\", frequency: 90.7 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 80.7 }\n - { name: \"Goldman Sachs\", period: \"Thirty Days\", frequency: 71.7 }\n - { name: \"Bloomberg\", period: \"Thirty Days\", frequency: 69.8 }\n - { name: \"Infosys\", period: \"Thirty Days\", frequency: 68.6 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 63.7 }\n - { name: \"Snowflake\", period: \"Three Months\", frequency: 90.3 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 58.9 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 47.7 }\n - { name: \"Docusign\", period: \"Six Months\", frequency: 100 }\n - { name: \"Qualcomm\", period: \"Six Months\", frequency: 80.7 }\n - { name: \"Nvidia\", period: \"Six Months\", frequency: 78.7 }\nsidebar:\n label: 'Trapping Rain Water'\n badge: 'Hard'\n---\n\n### Example 1:\n- Input: `height = [0,1,0,2,1,0,1,3,2,1,2,1]`\n- Output: `6`\n- Explanation: The above elevation map (black section) is represented by array `[0,1,0,2,1,0,1,3,2,1,2,1]`. In this case, `6` units of rain water (blue section) are being trapped.\n\n### Example 2:\n- Input: `height = [4,2,0,3,2,5]`\n- Output: `9`\n\n### Constraints:\n\n- `n == height.length`\n- `1 <= n <= 2 * 10^4`\n- `0 <= height[i] <= 10^5`\n\n## Solution\n\n```py\nclass Solution:\n def trap(self, height: list[int]) -> int:\n left, right = 0, len(height) - 1\n leftMax, rightMax = 0, 0\n total = 0\n\n while left < right:\n leftMax = max(leftMax, height[left])\n rightMax = max(rightMax, height[right])\n\n if height[left] < height[right]:\n total += leftMax - height[left]\n left += 1\n else:\n total += rightMax - height[right]\n right -= 1\n\n return total\n```\n"},"/two-pointers/two-sum-ii-input-array-is-sorted":{"mdx":"---\ntitle: '167. Two Sum II - Input Array Is Sorted'\ndescription: Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 <= numbers.length\nicon: dot\ntopics:\n - { name: \"Array\", slug: \"array\" }\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"Binary Search\", slug: \"binary-search\" }\nvideo: \"cQ1Oz4ckceM\"\nissue: \"https://github.com/prdlk/leetcode/issues/42\"\ncompanies:\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 65.8 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 46.6 }\n - { name: \"tcs\", period: \"Three Months\", frequency: 57.2 }\n - { name: \"Meta\", period: \"Three Months\", frequency: 54.8 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 33.4 }\n - { name: \"Oracle\", period: \"Six Months\", frequency: 78.7 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 40.6 }\nsidebar:\n label: 'Two Sum II - Input Array Is Sorted'\n badge: 'Medium'\n---\n\n::::warning\nYour solution must use only constant extra space.\n::::\n\n### Example 1:\n- Input: `numbers = [2,7,11,15], target = 9`\n- Output: `[1,2]`\n- Explanation: The sum of `2` and `7` is `9`. Therefore, `index1 = 1`, `index2 = 2`. We return `[1, 2]`.\n\n### Example 2:\n- Input: `numbers = [2,3,4], target = 6`\n- Output: `[1,3]`\n- Explanation: The sum of `2` and `4` is `6`. Therefore `index1 = 1`, `index2 = 3`. We return `[1, 3]`.\n\n### Example 3:\n- Input: `numbers = [-1,0], target = -1`\n- Output: `[1,2]`\n- Explanation: The sum of `-1` and `0` is `-1`. Therefore `index1 = 1`, `index2 = 2`. We return `[1, 2]`.\n\n### Constraints:\n\n- `2 <= numbers.length <= 3 * 10^4`\n- `-1000 <= numbers[i] <= 1000`\n- `numbers` is sorted in non-decreasing order.\n- `-1000 <= target <= 1000`\n- The tests are generated such that there is exactly one solution.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"twoSum(numbers, target)\"]) --> I[\"i = 0, j = len - 1\"]\n I --> W{\"i < j?\"}\n W -- no --> E([\"return []\"])\n W -- yes --> C[\"c = numbers[i] + numbers[j]\"]\n C --> Q{\"c vs target\"}\n Q -- equal --> R([\"return [i+1, j+1] — 1-indexed\"])\n Q -- \"c < target\" --> L[\"i += 1 — grow the sum\"]\n L --> W\n Q -- \"c > target\" --> H[\"j -= 1 — shrink the sum\"]\n H --> W\n```\n\n## Solution\n\n```py\nclass Solution:\n def twoSum(self, numbers: List[int], target: int) -> List[int]:\n i = 0\n j = len(numbers) - 1\n\n while i < j:\n c = numbers[i] + numbers[j]\n if c == target:\n return [i + 1, j + 1]\n elif c < target:\n i+=1\n else:\n j-=1\n return []\n```\n"},"/two-pointers/valid-palindrome":{"mdx":"---\ntitle: '125. Valid Palindrome'\ndescription: A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers\nicon: dot\ntopics:\n - { name: \"Two Pointers\", slug: \"two-pointers\" }\n - { name: \"String\", slug: \"string\" }\nvideo: \"jJXJ16kPFWg\"\nissue: \"https://github.com/prdlk/leetcode/issues/41\"\ncompanies:\n - { name: \"tcs\", period: \"Thirty Days\", frequency: 58.2 }\n - { name: \"Meta\", period: \"Thirty Days\", frequency: 53.8 }\n - { name: \"Amazon\", period: \"Thirty Days\", frequency: 39.1 }\n - { name: \"Google\", period: \"Thirty Days\", frequency: 29 }\n - { name: \"Bloomberg\", period: \"Three Months\", frequency: 79.9 }\n - { name: \"Infosys\", period: \"Three Months\", frequency: 66 }\n - { name: \"Microsoft\", period: \"Three Months\", frequency: 42.1 }\n - { name: \"Deloitte\", period: \"Six Months\", frequency: 81 }\n - { name: \"Cognizant\", period: \"Six Months\", frequency: 76.3 }\n - { name: \"Axon\", period: \"Six Months\", frequency: 75.4 }\n - { name: \"Apple\", period: \"Six Months\", frequency: 64.8 }\nsidebar:\n label: 'Valid Palindrome'\n badge: 'Easy'\n---\n\n### Example 1:\n- Input: `s = \"A man, a plan, a canal: Panama\"`\n- Output: `true`\n- Explanation: `\"amanaplanacanalpanama\"` is a palindrome.\n\n### Example 2:\n- Input: `s = \"race a car\"`\n- Output: `false`\n- Explanation: `\"raceacar\"` is not a palindrome.\n\n### Example 3:\n- Input: `s = \" \"`\n- Output: `true`\n- Explanation: `s` is an empty string `\"\"` after removing non-alphanumeric characters. Since an empty string reads the same forward and backward, it is a palindrome.\n\n### Constraints:\n\n- `1 <= s.length <= 2 * 10^5`\n- `s` consists only of printable ASCII characters.\n\n## Approach\n\n```mermaid\nflowchart TD\n S([\"isPalindrome(s)\"]) --> N[\"normal = s stripped of non-alphanumerics, lowercased\"]\n N --> I[\"i = 0, j = normal.length - 1\"]\n I --> W{\"i < j?\"}\n W -- no --> E([\"return true — the pointers met in the middle\"])\n W -- yes --> Q{\"normal[i] != normal[j]?\"}\n Q -- yes --> F([\"return false\"])\n Q -- no --> A[\"i++; j-- — step both inward\"]\n A --> W\n```\n\n## Solution\n\n```js\n/**\n * @param {string} s\n * @return {boolean}\n */\nvar isPalindrome = function(s) {\n let normal = s.replace(/[^a-zA-Z0-9]/g, \"\").toLowerCase() \n let i = 0, j = normal.length - 1;\n\n while (i < j) {\n if(normal[i] !== normal[j]) {\n return false;\n }\n i++;\n j--;\n }\n return true;\n};\n```\n"},"/union-find":{"mdx":"---\ntitle: Union Find\ndescription: 'Union-Find (Disjoint Set Union) is a data structure that maintains a collection of disjoint sets and supports efficiently finding which set an element belongs to and merging two sets.'\nhidden: true\n---\n\n\n\n\n"},"/union-find/number-of-connected-components-in-an-undirected-graph":{"mdx":"---\ntitle: '323. Number of Connected Components in an Undirected Graph'\ndescription: You have a graph of n nodes. You are given an integer n and an array edges where edges[i] = [ai, bi] indicates that there is an edge between ai and bi in the graph\nicon: dot\ntopics:\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Union-Find\", slug: \"union-find\" }\n - { name: \"Graph Theory\", slug: \"graph\" }\nissue: \"https://github.com/prdlk/leetcode/issues/147\"\nsidebar:\n label: 'Number of Connected Components in an Undirected Graph'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `n = 5, edges = [[0,1],[1,2],[3,4]]`\n- Output: `2`\n\n### Example 2:\n- Input: `n = 5, edges = [[0,1],[1,2],[2,3],[3,4]]`\n- Output: `1`\n\n### Constraints:\n\n- `1 <= n <= 2000`\n- `1 <= edges.length <= 5000`\n- `edges[i]` = [ai, bi]\n- `ai != bi`\n- There are no repeated edges.\n\n## Solution\n\n```py\nclass Solution:\n def countComponents(self, n: int, edges: list[list[int]]) -> int:\n par = [i for i in range(n + 1)]\n rank = [1] * (n + 1)\n\n def find(n):\n res = n\n while res != par[res]:\n par[res] = par[par[res]]\n res = par[res]\n return res\n\n def union(n1, n2):\n p1, p2 = find(n1), find(n2)\n if p1 == p2:\n return 0\n if rank[p1] > rank[p2]:\n par[p2] = p1\n rank[p1] += rank[p2]\n else:\n par[p1] = p2\n rank[p2] += rank[p1]\n return 1\n\n res = n\n for n1, n2 in edges:\n res -= union(n1, n2)\n return res\n```\n"},"/union-find/redundant-connection":{"mdx":"---\ntitle: '684. Redundant Connection'\ndescription: In this problem, a tree is an undirected graph that is connected and has no cycles\nicon: dot\ntopics:\n - { name: \"Depth-First Search\", slug: \"depth-first-search\" }\n - { name: \"Breadth-First Search\", slug: \"breadth-first-search\" }\n - { name: \"Union-Find\", slug: \"union-find\" }\n - { name: \"Graph Theory\", slug: \"graph\" }\nissue: \"https://github.com/prdlk/leetcode/issues/146\"\ncompanies:\n - { name: \"Box\", period: \"Three Months\", frequency: 100 }\n - { name: \"Amazon\", period: \"Three Months\", frequency: 21.2 }\n - { name: \"Bloomberg\", period: \"Six Months\", frequency: 25.5 }\n - { name: \"Microsoft\", period: \"Six Months\", frequency: 24.1 }\nsidebar:\n label: 'Redundant Connection'\n badge: 'Medium'\n---\n\n### Example 1:\n- Input: `edges = [[1,2],[1,3],[2,3]]`\n- Output: `[2,3]`\n\n### Example 2:\n- Input: `edges = [[1,2],[2,3],[3,4],[1,4],[1,5]]`\n- Output: `[1,4]`\n\n### Constraints:\n\n- `n == edges.length`\n- `3 <= n <= 1000`\n- `edges[i].length == 2`\n- `1 <= ai < bi <= edges.length`\n- `ai != bi`\n- There are no repeated edges.\n- The given graph is connected.\n\n## Solution\n\n```py\nclass Solution:\n def findRedundantConnection(self, edges: list[list[int]]) -> list[int]:\n N = len(edges)\n par = [i for i in range(N + 1)]\n rank = [1] * (N + 1)\n\n def find(n):\n if n != par[n]:\n par[n] = find(par[n])\n return par[n]\n\n def union(n1, n2):\n p1, p2 = find(n1), find(n2)\n if p1 == p2:\n return False\n\n if rank[p1] > rank[p2]:\n par[p2] = p1\n rank[p1] += rank[p2]\n else:\n par[p1] = p2\n rank[p2] += rank[p1]\n\n return True\n\n for n1, n2 in edges:\n if not union(n1, n2):\n return [n1, n2]\n```\n"}}