> ## Agent Instructions > leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform. > Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package. > Examples are backed by tests; copy them verbatim. # AlgoMaster 75 in Python with Tested Solutions Source: https://leetcode-py.wisl.dev/catalog/algo-master-75 All 75 problems in the AlgoMaster 75 list: each generates a tested Python practice environment with a pytest suite and reference solutions. AlgoMaster 75 holds 75 problems (7 Easy, 53 Medium, 15 Hard). AlgoMaster 75 is this repository's own curated 75, built for algorithmic mastery across the core interview patterns. Every problem generates a Python practice environment with a parametrized pytest suite and a tested reference solution. Generate the whole collection into the current directory: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -t algo-master-75 ```
A valid \additive sequence\ should contain \at least\ three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.\
\Given a string containing only digits, return \true\ if it is an \additive number\ or \false\ otherwise.\
\Note:\ Numbers in the additive sequence \cannot\ have leading zeros, so sequence \1, 2, 03\ or \1, 02, 3\ is invalid.\
n\, return \a list of all possible \full binary trees\ with\ \n\ \nodes\. Each node of each tree in the answer must have \Node.val == 0\.\
\Each element of the answer is the root node of one possible tree. You may return the final list of trees in \any order\.\
\A \full binary tree\ is a binary tree where each node has exactly \0\ or \2\ children.\
colors\ and an integer \k\. The color of tile \i\ is represented by \colors\[i]\:
\colors\[i] == 0\ means that tile \i\ is \red\.\colors\[i] == 1\ means that tile \i\ is \blue\.\An \alternating\ group is every \k\ contiguous tiles in the circle with \alternating\ colors (each tile in the group except the first and last one has a different color from its \left\ and \right\ tiles).\
Return the number of \alternating\ groups.\
\\Note\ that since \colors\ represents a \circle\, the \first\ and the \last\ tiles are considered to be next to each other.\
You are given an array \nums\ of \n\ positive integers and an integer \k\.\
Initially, you start with a score of \1\. You have to maximize your score by applying the following operation at most \k\ times:\
nums\[l, ..., r]\ that you haven't chosen previously.\x\ of \nums\[l, ..., r]\ with the highest \prime score\. If multiple such elements exist, choose the one with the smallest index.\x\.\Here, \nums\[l, ..., r]\ denotes the subarray of \nums\ starting at index \l\ and ending at the index \r\, both ends being inclusive.\
The \prime score\ of an integer \x\ is equal to the number of distinct prime factors of \x\. For example, the prime score of \300\ is \3\ since \300 = 2 \* 2 \* 3 \* 5 \* 5\.\
Return \the \maximum possible score\ after applying at most \\k\\ operations\.\
Since the answer may be large, return it modulo \10\9 \+ 7\.\
10\-5\\ of the actual answer will be accepted.
### Examples

```
Input: root = [3,9,20,null,null,15,7]
Output: [3.00000,14.50000,11.00000]
Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11.
Hence return [3, 14.5, 11].
```

```
Input: root = [3,9,20,15,7]
Output: [3.00000,14.50000,11.00000]
```
### Constraints
* The number of nodes in the tree is in the range \[1, 10\4\]
* -2\31\ \<= Node.val \<= 2\31\ - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/average_of_levels_in_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/average_of_levels_in_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(w) where w is the maximum width of the tree
def average_of_levels(self, root: TreeNode[int] | None) -> list[float]:
if root is None:
return []
result: list[float] = []
queue = deque([root])
while queue:
level_size = len(queue)
level_sum = 0
for _ in range(level_size):
node = queue.popleft()
level_sum += node.val
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
result.append(level_sum / level_size)
return result
```
## Complexity
| Time | Space |
| ---- | --------------------------------------------- |
| O(n) | O(w) where w is the maximum width of the tree |
## Tags
# Average Waiting Time Python Solution
Source: https://leetcode-py.wisl.dev/problems/average-waiting-time
Tested Python solution for LeetCode 1701 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 1701, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/average-waiting-time/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1701 # by problem number
lcpy gen -s average_waiting_time # by problem name
```
## Problem
There is a restaurant with a single chef. You are given an array `customers`, where `customers[i] = [arrivali, timei]`:
* `arrivali` is the arrival time of the `ith` customer. The arrival times are sorted in non-decreasing order.
* `timei` is the time needed to prepare the order of the `ith` customer.
When a customer arrives, he gives the chef his order, and the chef starts preparing it once he is idle. The customer waits till the chef finishes preparing his order. The chef does not prepare food for more than one customer at a time. The chef prepares food for customers in the order they were given in the input.
Return *the average waiting time of all customers*. Solutions within `10-5` from the actual answer are considered accepted.
### Examples
```
Input: customers = [[1,2],[2,5],[4,3]]
Output: 5.00000
Explanation:
1) The first customer arrives at time 1, the chef takes his order and starts preparing it immediately at time 1, and finishes at time 3, so the waiting time of the first customer is 3 - 1 = 2.
2) The second customer arrives at time 2, the chef takes his order and starts preparing it at time 3, and finishes at time 8, so the waiting time of the second customer is 8 - 2 = 6.
3) The third customer arrives at time 4, the chef takes his order and starts preparing it at time 8, and finishes at time 11, so the waiting time of the third customer is 11 - 4 = 7.
So the average waiting time = (2 + 6 + 7) / 3 = 5.
```
```
Input: customers = [[5,2],[5,4],[10,3],[20,1]]
Output: 3.25000
Explanation:
1) The first customer arrives at time 5, the chef takes his order and starts preparing it immediately at time 5, and finishes at time 7, so the waiting time of the first customer is 7 - 5 = 2.
2) The second customer arrives at time 5, the chef takes his order and starts preparing it at time 7, and finishes at time 11, so the waiting time of the second customer is 11 - 5 = 6.
3) The third customer arrives at time 10, the chef takes his order and starts preparing it at time 11, and finishes at time 14, so the waiting time of the third customer is 14 - 10 = 4.
4) The fourth customer arrives at time 20, the chef takes his order and starts preparing it immediately at time 20, and finishes at time 21, so the waiting time of the fourth customer is 21 - 20 = 1.
So the average waiting time = (2 + 6 + 4 + 1) / 4 = 3.25.
```
### Constraints
* 1 \<= customers.length \<= 10^5
* 1 \<= arrival\i\, time\i\ \<= 10^4
* arrival\i\ \<= arrival\i+1\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/average_waiting_time/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/average_waiting_time/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def average_waiting_time(self, customers: list[list[int]]) -> float:
now = 0
total_wait = 0
for arrival, time in customers:
now = max(now, arrival) + time
total_wait += now - arrival
return total_wait / len(customers)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Backspace String Compare Python Solution
Source: https://leetcode-py.wisl.dev/problems/backspace-string-compare
Tested Python solution for LeetCode 844 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 844, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/backspace-string-compare/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 844 # by problem number
lcpy gen -s backspace_string_compare # by problem name
```
## Problem
Given two strings `s` and `t`, return `true` if they are equal when both are typed into empty text editors. `'#'` means a backspace character.
Note that after backspacing an empty text, the text will continue empty.
### Examples
```
Input: s = "ab#c", t = "ad#c"
Output: true
Explanation: Both s and t become "ac".
```
```
Input: s = "ab##", t = "c#d#"
Output: true
Explanation: Both s and t become "".
```
```
Input: s = "a#c", t = "b"
Output: false
Explanation: s becomes "c" while t becomes "b".
```
### Constraints
* 1 \<= s.length, t.length \<= 200
* `s` and `t` only contain lowercase letters and `'#'` characters.
**Follow up:** Can you solve it in `O(n)` time and `O(1)` space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/backspace_string_compare/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/backspace_string_compare/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Walk both strings right-to-left, skipping chars consumed by backspace.
# Compare next surviving char of each; mismatch or early exhaustion => false.
# Time: O(n + m)
# Space: O(1)
def backspace_compare(self, s: str, t: str) -> bool:
i, j = len(s) - 1, len(t) - 1
while i >= 0 or j >= 0:
i = self._next_valid(s, i)
j = self._next_valid(t, j)
s_char = s[i] if i >= 0 else ""
t_char = t[j] if j >= 0 else ""
if s_char != t_char:
return False
i -= 1
j -= 1
return True
def _next_valid(self, text: str, index: int) -> int:
skip = 0
while index >= 0:
if text[index] == "#":
skip += 1
index -= 1
elif skip > 0:
skip -= 1
index -= 1
else:
break
return index
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + m) | O(1) |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Bag of Tokens Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/bag-of-tokens
Tested Python solution for LeetCode 948 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 948, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/bag-of-tokens/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 948 # by problem number
lcpy gen -s bag_of_tokens # by problem name
```
## Problem
\You start with an initial power of \power\, an initial score of \0\, and a bag of tokens given as an integer array \tokens\, where each \tokens\[i]\ denotes the value of token\i\.\
Your goal is to maximize the total \score\ by strategically playing these tokens. In one move, you can play an \unplayed\ token in one of the two ways (but not both for the same token):\
\tokens\[i]\, you may play token\i\, losing \tokens\[i]\ power and gaining \1\ score.\1\, you may play token\i\, gaining \tokens\[i]\ power and losing \1\ score.\Return \the maximum possible \score\ you can achieve after playing any number of tokens\.\
### Examples ``` Input: tokens = [100], power = 50 Output: 0 Explanation: Since your score is 0 initially, you cannot play the token face-down. You also cannot play it face-up since your power (50) is less than tokens[0] (100). ``` ``` Input: tokens = [200,100], power = 150 Output: 1 Explanation: Play token1 (100) face-up, reducing your power to 50 and increasing your score to 1. ``` ``` Input: tokens = [100,200,300,400], power = 200 Output: 2 Explanation: Play the tokens in this order to get a score of 2: Play token0 (100) face-up, reducing power to 100 and increasing score to 1. Play token3 (400) face-down, increasing power to 500 and reducing score to 0. Play token1 (200) face-up, reducing power to 300 and increasing score to 1. Play token2 (300) face-up, reducing power to 0 and increasing score to 2. ``` ### Constraints * 0 \<= tokens.length \<= 1000 * 0 \<= tokens\[i], power \< 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bag_of_tokens/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bag_of_tokens/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) for the sorted copy def bag_of_tokens_score(self, tokens: list[int], power: int) -> int: tokens = sorted(tokens) left, right = 0, len(tokens) - 1 score = 0 best = 0 while left <= right: if power >= tokens[left]: # Cheapest token face-up for score power -= tokens[left] left += 1 score += 1 best = max(best, score) elif score >= 1: # Most expensive token face-down for power power += tokens[right] right -= 1 score -= 1 else: break return best ``` ## Complexity | Time | Space | | ---------- | ------------------------ | | O(n log n) | O(n) for the sorted copy | ## Tags [NeetCode All](/catalog/neetcode). # Balanced Binary Tree Python Solution Source: https://leetcode-py.wisl.dev/problems/balanced-binary-tree Tested Python solution for LeetCode 110 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 110, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/balanced-binary-tree/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 110 # by problem number lcpy gen -s balanced_binary_tree # by problem name ``` ## Problem Given a binary tree, determine if it is **height-balanced**. A height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one. ### Examples  ``` Input: root = [3,9,20,null,null,15,7] Output: true ```  ``` Input: root = [1,2,2,3,3,null,null,4,4] Output: false ``` ``` Input: root = [] Output: true ``` ### Constraints * The number of nodes in the tree is in the range `[0, 5000]`. * `-10^4 <= Node.val <= 10^4` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/balanced_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/balanced_binary_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) def is_balanced(self, root: TreeNode[int] | None) -> bool: def height(node: TreeNode[int] | None) -> int: if not node: return 0 left = height(node.left) right = height(node.right) if left == -1 or right == -1 or abs(left - right) > 1: return -1 return max(left, right) + 1 return height(root) != -1 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(h) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Base 7 Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/base-7 Tested Python solution for LeetCode 504 with 25 pytest cases. Generate a practice environment with lcpy. LeetCode 504, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/base-7/description/). Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 504 # by problem number lcpy gen -s base_7 # by problem name ``` ## Problem Given an integer `num`, return a string of its base 7 representation. ### Examples ``` Input: num = 100 Output: "202" ``` ``` Input: num = -7 Output: "-10" ``` ### Constraints * -10^7 \<= num \<= 10^7 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/base_7/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/base_7/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log_7 |num|) # Space: O(log_7 |num|) def convert_to_base_7(self, num: int) -> str: if num == 0: return "0" negative = num < 0 digits = "" value = abs(num) while value: digits = str(value % 7) + digits value //= 7 return f"-{digits}" if negative else digits ``` ## Complexity | Time | Space | | | | | | -------- | ----- | - | -------- | --- | - | | O(log\_7 | num | ) | O(log\_7 | num | ) | ## Tags # Baseball Game Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/baseball-game Tested Python solution for LeetCode 682 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 682, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/baseball-game/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 682 # by problem number lcpy gen -s baseball_game # by problem name ``` ## Problem You are keeping the scores for a baseball game with strange rules. At the beginning of the game, you start with an empty record. You are given a list of strings `operations`, where `operations[i]` is the `ith` operation you must apply to the record and is one of the following: * An integer `x`. * Record a new score of `x`. * `'+'`. * Record a new score that is the sum of the previous two scores. * `'D'`. * Record a new score that is the double of the previous score. * `'C'`. * Invalidate the previous score, removing it from the record. Return the sum of all the scores on the record after applying all the operations. The test cases are generated such that the answer and all intermediate calculations fit in a **32-bit** integer and that all operations are valid. ### Examples ``` Input: ops = ["5","2","C","D","+"] Output: 30 Explanation: "5" - Add 5 to the record, record is now [5]. "2" - Add 2 to the record, record is now [5, 2]. "C" - Invalidate and remove the previous score, record is now [5]. "D" - Add 2 * 5 = 10 to the record, record is now [5, 10]. "+" - Add 5 + 10 = 15 to the record, record is now [5, 10, 15]. The total sum is 5 + 10 + 15 = 30. ``` ``` Input: ops = ["5","-2","4","C","D","9","+","+"] Output: 27 ``` ``` Input: ops = ["1","C"] Output: 0 ``` ### Constraints * 1 \<= operations.length \<= 1000 * `operations[i]` is `"C"`, `"D"`, `"+"`, or a string representing an integer in the range \[-3 \* 10^4, 3 \* 10^4]. * For operation `"+"`, there will always be at least two previous scores on the record. * For operations `"C"` and `"D"`, there will always be at least one previous score on the record. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/baseball_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/baseball_game/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def cal_points(self, operations: list[str]) -> int: record: list[int] = [] for op in operations: if op == "+": record.append(record[-1] + record[-2]) elif op == "D": record.append(2 * record[-1]) elif op == "C": record.pop() else: record.append(int(op)) return sum(record) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Basic Calculator Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/basic-calculator Tested Python solution for LeetCode 224 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 224, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/basic-calculator/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 224 # by problem number lcpy gen -s basic_calculator # by problem name ``` ## Problem Given a string `s` representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation. **Note:** You are **not** allowed to use any built-in function which evaluates strings as mathematical expressions, such as `eval()`. ### Examples ``` Input: s = "1 + 1" Output: 2 ``` ``` Input: s = " 2-1 + 2 " Output: 3 ``` ``` Input: s = "(1+(4+5+2)-3)+(6+8)" Output: 23 ``` ### Constraints * `1 <= s.length <= 3 * 10^5` * `s` consists of digits, `'+'`, `'-'`, `'('`, `')'`, and `' '`. * `s` represents a valid expression. * `'+'` is **not** used as a unary operation (i.e., `"+1"` and `"+(2 + 3)"` is invalid). * `'-'` could be used as a unary operation (i.e., `"-1"` and `"-(2 + 3)"` is valid). * There will be no two consecutive operators in the input. * Every number and running calculation will fit in a signed 32-bit integer. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def calculate(self, s: str) -> int: stack = [] num = 0 sign = 1 result = 0 for char in s: if char.isdigit(): num = num * 10 + int(char) elif char in "+-": result += sign * num num = 0 sign = 1 if char == "+" else -1 elif char == "(": stack.append(result) stack.append(sign) result = 0 sign = 1 elif char == ")": if len(stack) < 2: raise ValueError("Mismatched parentheses") result += sign * num num = 0 result *= stack.pop() result += stack.pop() elif char != " ": raise ValueError(f"Invalid character: '{char}'") if stack: raise ValueError("Mismatched parentheses") return result + sign * num # Example walkthrough: "(1+(4+5+2)-3)+(6+8)" = 23 # # char | num | sign | result | stack | action # -----|-----|------|--------|------------|------------------ # '(' | 0 | 1 | 0 | [0, 1] | push result=0, sign=1 # '1' | 1 | 1 | 0 | [0, 1] | build num=1 # '+' | 0 | 1 | 1 | [0, 1] | result += 1*1 = 1 # '(' | 0 | 1 | 0 | [0,1,1,1] | push result=1, sign=1 # '4' | 4 | 1 | 0 | [0,1,1,1] | build num=4 # '+' | 0 | 1 | 4 | [0,1,1,1] | result += 1*4 = 4 # '5' | 5 | 1 | 4 | [0,1,1,1] | build num=5 # '+' | 0 | 1 | 9 | [0,1,1,1] | result += 1*5 = 9 # '2' | 2 | 1 | 9 | [0,1,1,1] | build num=2 # ')' | 0 | 1 | 11 | [0, 1] | result=11*1+1 = 12 # '-' | 0 | -1 | 12 | [0, 1] | sign = -1 # '3' | 3 | -1 | 12 | [0, 1] | build num=3 # ')' | 0 | 1 | 9 | [] | result=9*1+0 = 9 # '+' | 0 | 1 | 9 | [] | sign = 1 # '(' | 0 | 1 | 0 | [9, 1] | push result=9, sign=1 # '6' | 6 | 1 | 0 | [9, 1] | build num=6 # '+' | 0 | 1 | 6 | [9, 1] | result += 1*6 = 6 # '8' | 8 | 1 | 6 | [9, 1] | build num=8 # ')' | 0 | 1 | 14 | [] | result=14*1+9 = 23 # end | 0 | 1 | 14 | [] | return 14+1*0 = 23 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind). # Basic Calculator II Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/basic-calculator-ii Tested Python solution for LeetCode 227 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 227, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/basic-calculator-ii/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 227 # by problem number lcpy gen -s basic_calculator_ii # by problem name ``` ## Problem Given a string `s` which represents an expression, evaluate this expression and return its value. The integer division should truncate toward zero. You may assume that the given expression is always valid. All intermediate results will be in the range of \[-2^31, 2^31 - 1]. **Note:** You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as `eval()`. ### Examples ``` Input: s = "3+2*2" Output: 7 ``` ``` Input: s = " 3/2 " Output: 1 ``` ``` Input: s = " 3+5 / 2 " Output: 5 ``` ### Constraints * 1 \<= s.length \<= 3 \* 10^5 * s consists of integers and operators ('+', '-', '\*', '/') separated by some number of spaces. * s represents a valid expression. * All the integers in the expression are non-negative integers in the range \[0, 2^31 - 1]. * The answer is guaranteed to fit in a 32-bit integer. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) — single pass # Space: O(n) — stack of operands def calculate(self, s: str) -> int: stack: list[int] = [] current = 0 op = "+" def apply(value: int) -> None: nonlocal stack if op == "+": stack.append(value) elif op == "-": stack.append(-value) elif op == "*": stack.append(stack.pop() * value) else: # "/" prev = stack.pop() # Truncate toward zero stack.append(int(prev / value)) for ch in s: if ch.isdigit(): current = current * 10 + int(ch) elif ch in "+-*/": apply(current) op = ch current = 0 apply(current) # last operand return sum(stack) ``` ## Complexity | Time | Space | | ------------------ | ------------------------ | | O(n) — single pass | O(n) — stack of operands | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Basic Calculator III Python Solution Source: https://leetcode-py.wisl.dev/problems/basic-calculator-iii Tested Python solution for LeetCode 772 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 772, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/basic-calculator-iii/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 772 # by problem number lcpy gen -s basic_calculator_iii # by problem name ``` ## Problem Implement a basic calculator to evaluate a simple expression string. The expression string contains only non-negative integers, `'+'`, `'-'`, `'*'`, `'/'` operators, and open `'('` and closing parentheses `')'`. The integer division should **truncate toward zero**. You may assume that the given expression is always valid. All intermediate results will be in the range of `[-2^31, 2^31 - 1]`. **Note:** You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as `eval()`. ### Examples ``` Input: s = "1+1" Output: 2 ``` ``` Input: s = "6-4/2" Output: 4 ``` ``` Input: s = "2*(5+5*2)/3+(6/2+8)" Output: 21 ``` ### Constraints * 1 \<= s.length \<= 10^4 * s consists of digits, '+', '-', '\*', '/', '(', and ')'. * s is a valid expression. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def calculate(self, s: str) -> int: def dfs(i: int) -> tuple[int, int]: stk: list[int] = [] num = 0 sign = "+" while i < len(s): c = s[i] if c.isdigit(): num = num * 10 + int(c) elif c == "(": num, i = dfs(i + 1) if c in "+-*/)" or i == len(s) - 1: if sign == "+": stk.append(num) elif sign == "-": stk.append(-num) elif sign == "*": stk.append(stk.pop() * num) else: stk.append(int(stk.pop() / num)) num = 0 sign = c if c == ")": return sum(stk), i i += 1 return sum(stk), i return dfs(0)[0] ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Basic Calculator IV Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/basic-calculator-iv Tested Python solution for LeetCode 770 with 21 pytest cases. Generate a practice environment with lcpy. LeetCode 770, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/basic-calculator-iv/description/). Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 770 # by problem number lcpy gen -s basic_calculator_iv # by problem name ``` ## Problem Given an expression such as `expression = "e + 8 - a + 5"` and an evaluation map such as `{"e": 1}` (given in terms of `evalvars = ["e"]` and `evalints = [1]`), return a list of tokens representing the simplified expression, such as `["-1*a","14"]` * An expression alternates chunks and symbols, with a space separating each chunk and symbol. * A chunk is either an expression in parentheses, a variable, or a non-negative integer. * A variable is a string of lowercase letters (not including digits.) Note that variables can be multiple letters, and note that variables never have a leading coefficient or unary operator like `"2x"` or `"-x"`. Expressions are evaluated in the usual order: brackets first, then multiplication, then addition and subtraction. * For example, `expression = "1 + 2 * 3"` has an answer of `["7"]`. The format of the output is as follows: * For each term of free variables with a non-zero coefficient, we write the free variables within a term in sorted order lexicographically. * For example, we would never write a term like `"b*a*c"`, only `"a*b*c"`. * Terms have degrees equal to the number of free variables being multiplied, counting multiplicity. We write the largest degree terms of our answer first, breaking ties by lexicographic order ignoring the leading coefficient of the term. * For example, `"a*a*b*c"` has degree `4`. * The leading coefficient of the term is placed directly to the left with an asterisk separating it from the variables (if they exist.) A leading coefficient of 1 is still printed. * An example of a well-formatted answer is `["-2*a*a*a", "3*a*a*b", "3*b*b", "4*a", "5*c", "-6"]`. * Terms (including constant terms) with coefficient `0` are not included. * For example, an expression of `"0"` has an output of `[]`. **Note:** You may assume that the given expression is always valid. All intermediate results will be in the range of `[-2^31, 2^31 - 1]`. ### Examples ``` Input: expression = "e + 8 - a + 5", evalvars = ["e"], evalints = [1] Output: ["-1*a","14"] ``` ``` Input: expression = "e - 8 + temperature - pressure", evalvars = ["e", "temperature"], evalints = [1, 12] Output: ["-1*pressure","5"] ``` ``` Input: expression = "(e + 8) * (e - 8)", evalvars = [], evalints = [] Output: ["1*e*e","-64"] ``` ### Constraints * 1 \<= expression.length \<= 250 * expression consists of lowercase English letters, digits, '+', '-', '\*', '(', ')', and ' '. * expression does not contain any leading or trailing spaces. * All the tokens in expression are separated by a single space. * 0 \<= evalvars.length \<= 100 * 1 \<= evalvars\[i].length \<= 20 * evalvars\[i] consists of lowercase English letters. * evalints.length == evalvars.length * -100 \<= evalints\[i] \<= 100 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator_iv/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/basic_calculator_iv/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque Poly = dict[tuple[str, ...], int] class Solution: # Time: O(n * m) where n is the expression length and m the term count # Space: O(n + m) def basic_calculator_iv( self, expression: str, evalvars: list[str], evalints: list[int] ) -> list[str]: sub = dict(zip(evalvars, evalints, strict=True)) tokens = deque(self._tokenize(expression)) poly = self._expression(tokens, sub) return self._format(poly) @staticmethod def _tokenize(expression: str) -> list[str]: tokens: list[str] = [] for chunk in expression.split(" "): opens = 0 while chunk.startswith("("): opens += 1 chunk = chunk[1:] closes = 0 while chunk.endswith(")"): closes += 1 chunk = chunk[:-1] tokens.extend(["("] * opens) if chunk: tokens.append(chunk) tokens.extend([")"] * closes) return tokens @staticmethod def _add(left: Poly, right: Poly, sign: int) -> Poly: result = dict(left) for term, coeff in right.items(): updated = result.get(term, 0) + sign * coeff if updated: result[term] = updated else: result.pop(term, None) return result @staticmethod def _mul(left: Poly, right: Poly) -> Poly: result: Poly = {} for left_term, left_coeff in left.items(): for right_term, right_coeff in right.items(): term = tuple(sorted(left_term + right_term)) result[term] = result.get(term, 0) + left_coeff * right_coeff return {term: coeff for term, coeff in result.items() if coeff} def _expression(self, tokens: deque[str], sub: dict[str, int]) -> Poly: poly = self._term(tokens, sub) while tokens and tokens[0] in ("+", "-"): sign = 1 if tokens.popleft() == "+" else -1 poly = self._add(poly, self._term(tokens, sub), sign) return poly def _term(self, tokens: deque[str], sub: dict[str, int]) -> Poly: poly = self._factor(tokens, sub) while tokens and tokens[0] == "*": tokens.popleft() poly = self._mul(poly, self._factor(tokens, sub)) return poly def _factor(self, tokens: deque[str], sub: dict[str, int]) -> Poly: token = tokens.popleft() if token == "(": poly = self._expression(tokens, sub) tokens.popleft() # matching closing paren return poly if token.isdigit(): return {(): int(token)} if int(token) else {} if token in sub: return {(): sub[token]} if sub[token] else {} return {(token,): 1} @staticmethod def _format(poly: Poly) -> list[str]: ordered = sorted(poly.items(), key=lambda item: (-len(item[0]), item[0])) return [str(coeff) + ("*" + "*".join(term) if term else "") for term, coeff in ordered] ``` ## Complexity | Time | Space | | --------------------------------------------------------------- | -------- | | O(n \* m) where n is the expression length and m the term count | O(n + m) | ## Tags # Battleships in a Board Python Solution Source: https://leetcode-py.wisl.dev/problems/battleships-in-a-board Tested Python solution for LeetCode 419 with 34 pytest cases. Generate a practice environment with lcpy. LeetCode 419, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/battleships-in-a-board/description/). Generate this problem as a practice environment: tested reference solution, 34 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 419 # by problem number lcpy gen -s battleships_in_a_board # by problem name ``` ## Problem Given an `m x n` matrix `board` where each cell is a battleship `'X'` or empty `'.'`, return the number of the battleships on `board`. Battleships can only be placed horizontally or vertically on `board`. In other words, they can only be made of the shape `1 x k` (`1` row, `k` columns) or `k x 1` (`k` rows, `1` column), where `k` can be of any size. At least one horizontal or vertical cell separates between two battleships (i.e., there are no adjacent battleships). ### Examples  ``` Input: board = [["X",".",".","X"],[".",".",".","X"],[".",".",".","X"]] Output: 2 ``` ``` Input: board = [["."]] Output: 0 ``` ### Constraints * m == board.length * n == board\[i].length * 1 \<= m, n \<= 200 * board\[i]\[j] is either '.' or 'X'. Follow up: Could you do it in one-pass, using only O(1) extra memory and without modifying the values of board? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/battleships_in_a_board/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/battleships_in_a_board/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(1) def count_battleships(self, board: list[list[str]]) -> int: count = 0 for r, row in enumerate(board): for c, cell in enumerate(row): if cell != "X": continue if r > 0 and board[r - 1][c] == "X": continue if c > 0 and row[c - 1] == "X": continue count += 1 return count ``` ## Complexity | Time | Space | | --------- | ----- | | O(m \* n) | O(1) | ## Tags # Beautiful Arrangement Python Solution Source: https://leetcode-py.wisl.dev/problems/beautiful-arrangement Tested Python solution for LeetCode 526 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 526, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/beautiful-arrangement/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 526 # by problem number lcpy gen -s beautiful_arrangement # by problem name ``` ## Problem Suppose you have `n` integers labeled `1` through `n`. A permutation of those `n` integers `perm` (**1-indexed**) is considered a **beautiful arrangement** if for every `i` (`1 <= i <= n`), **either** of the following is true: * `perm[i]` is divisible by `i`. * `i` is divisible by `perm[i]`. Given an integer `n`, return *the **number** of the **beautiful arrangements** that you can construct*. ### Examples ``` Input: n = 2 Output: 2 Explanation: The first beautiful arrangement is [1,2]: - perm[1] = 1 is divisible by i = 1 - perm[2] = 2 is divisible by i = 2 The second beautiful arrangement is [2,1]: - perm[1] = 2 is divisible by i = 1 - i = 2 is divisible by perm[2] = 1 ``` ``` Input: n = 1 Output: 1 ``` ### Constraints * `1 <= n <= 15` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/beautiful_arrangement/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/beautiful_arrangement/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n * 2^n) # Space: O(2^n) def count_arrangement(self, n: int) -> int: full = (1 << n) - 1 memo: dict[int, int] = {} def count(mask: int) -> int: if mask == full: return 1 if mask in memo: return memo[mask] pos = mask.bit_count() + 1 total = 0 for value in range(1, n + 1): bit = 1 << (value - 1) if not mask & bit and (value % pos == 0 or pos % value == 0): total += count(mask | bit) memo[mask] = total return total return count(0) ``` ## Complexity | Time | Space | | ----------- | ------ | | O(n \* 2^n) | O(2^n) | ## Tags # Beautiful Arrangement II Python Solution Source: https://leetcode-py.wisl.dev/problems/beautiful-arrangement-ii Tested Python solution for LeetCode 667 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 667, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/beautiful-arrangement-ii/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 667 # by problem number lcpy gen -s beautiful_arrangement_ii # by problem name ``` ## Problem Given two integers `n` and `k`, construct a list `answer` that contains `n` different positive integers ranging from `1` to `n` and obeys the following requirement: * Suppose this list is `answer = [a1, a2, a3, ..., an]`, then the list `[|a1 - a2|, |a2 - a3|, |a3 - a4|, ..., |an-1 - an|]` has exactly `k` distinct integers. Return *the list* `answer`. If there are multiple valid answers, return **any of them**. ### Examples ``` Input: n = 3, k = 1 Output: [1,2,3] Explanation: The [1,2,3] has three different positive integers ranging from 1 to 3, and the [1,1] has exactly 1 distinct integer: 1. ``` ``` Input: n = 3, k = 2 Output: [1,3,2] Explanation: The [1,3,2] has three different positive integers ranging from 1 to 3, and the [2,1] has exactly 2 distinct integers: 1 and 2. ``` ### Constraints * `1 <= k < n <= 10^4` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/beautiful_arrangement_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/beautiful_arrangement_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Zig-zag the first k+1 values between the low and high ends: the k gaps of that # prefix are exactly k, k-1, ..., 1, then a plain ascending run keeps only 1. # Time: O(n) # Space: O(1) extra besides the output list def construct_array(self, n: int, k: int) -> list[int]: result: list[int] = [] low, high = 1, k + 1 while low < high: result.extend([low, high]) low += 1 high -= 1 if low == high: result.append(low) result.extend(range(k + 2, n + 1)) return result ``` ## Complexity | Time | Space | | ---- | ---------------------------------- | | O(n) | O(1) extra besides the output list | ## Tags # Beautiful Array Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/beautiful-array Tested Python solution for LeetCode 932 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 932, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Divide and Conquer](/catalog/topics/divide-and-conquer). [View on LeetCode](https://leetcode.com/problems/beautiful-array/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 932 # by problem number lcpy gen -s beautiful_array # by problem name ``` ## Problem An array `nums` of length `n` is **beautiful** if: * `nums` is a permutation of the integers in the range `[1, n]`. * For every `0 <= i < j < n`, there is no index `k` with `i < k < j` where `2 * nums[k] == nums[i] + nums[j]`. Given the integer `n`, return any **beautiful** array `nums` of length `n`. There will be at least one valid answer for the given `n`. ### Examples ``` Input: n = 4 Output: [2,1,4,3] ``` ``` Input: n = 5 Output: [3,1,2,5,4] ``` ### Constraints * `1 <= n <= 1000` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/beautiful_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/beautiful_array/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def beautiful_array(self, n: int) -> list[int]: # Divide and conquer: odds and evens of a beautiful array are each # beautiful, and concatenating two beautiful halves never creates a # bad triple since 2 * nums[k] == nums[i] + nums[j] requires nums[i] # and nums[j] of the same parity while k sits in the other half. res = [1] while len(res) < n: res = [2 * x - 1 for x in res] + [2 * x for x in res] return [x for x in res if x <= n] ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Best Meeting Point Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/best-meeting-point Tested Python solution for LeetCode 296 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 296, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Matrix](/catalog/topics/matrix), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/best-meeting-point/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 296 # by problem number lcpy gen -s best_meeting_point # by problem name ``` ## Problem Given an `m x n` binary `grid` where each `1` marks the home of one friend, return *the minimal **total travel distance***. The **total travel distance** is the sum of the distances between the houses of the friends and the meeting point. The distance is calculated using Manhattan Distance, where `distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|`. ### Examples  ``` Input: grid = [[1,0,0,0,1],[0,0,0,0,0],[0,0,1,0,0]] Output: 6 Explanation: Given three friends living at (0,0), (0,4), and (2,2). The point (0,2) is an ideal meeting point, as the total travel distance of 2 + 2 + 2 = 6 is minimal. So return 6. ``` ``` Input: grid = [[1,1]] Output: 1 ``` ### Constraints * `m == grid.length` * `n == grid[i].length` * `1 <= m, n <= 200` * `grid[i][j]` is either `0` or `1`. * There will be **at least two** friends in the `grid`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_meeting_point/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_meeting_point/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m*n + f log f) where f is the friend count # Space: O(f) def min_total_distance(self, grid: list[list[int]]) -> int: rows: list[int] = [] cols: list[int] = [] for r in range(len(grid)): for c in range(len(grid[0])): if grid[r][c] == 1: rows.append(r) cols.append(c) cols.sort() median_row = rows[len(rows) // 2] median_col = cols[len(cols) // 2] return sum(abs(r - median_row) for r in rows) + sum(abs(c - median_col) for c in cols) ``` ## Complexity | Time | Space | | --------------------------------------------- | ----- | | O(m\*n + f log f) where f is the friend count | O(f) | ## Tags [NeetCode All](/catalog/neetcode). # Best Sightseeing Pair Python Solution Source: https://leetcode-py.wisl.dev/problems/best-sightseeing-pair Tested Python solution for LeetCode 1014 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 1014, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/best-sightseeing-pair/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1014 # by problem number lcpy gen -s best_sightseeing_pair # by problem name ``` ## Problem You are given an integer array `values` where `values[i]` represents the value of the `ith` sightseeing spot. Two sightseeing spots `i` and `j` have a distance `j - i` between them. The score of a pair (`i < j`) of sightseeing spots is `values[i] + values[j] + i - j`: the sum of the values of the sightseeing spots, minus the distance between them. Return *the maximum score of a pair of sightseeing spots*. ### Examples ``` Input: values = [8,1,5,2,6] Output: 11 Explanation: i = 0, j = 2, values[i] + values[j] + i - j = 8 + 5 + 0 - 2 = 11 ``` ``` Input: values = [1,2] Output: 2 ``` ### Constraints * `2 <= values.length <= 5 * 10^4` * `1 <= values[i] <= 1000` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_sightseeing_pair/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_sightseeing_pair/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_score_sightseeing_pair(self, values: list[int]) -> int: best = 0 best_left = values[0] for j in range(1, len(values)): best = max(best, best_left + values[j] - j) best_left = max(best_left, values[j] + j) return best ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Best Team With No Conflicts Python Solution Source: https://leetcode-py.wisl.dev/problems/best-team-with-no-conflicts Tested Python solution for LeetCode 1626 with 27 pytest cases. Generate a practice environment with lcpy. LeetCode 1626, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/best-team-with-no-conflicts/description/). Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1626 # by problem number lcpy gen -s best_team_with_no_conflicts # by problem name ``` ## Problem You are the manager of a basketball team. For the upcoming tournament, you want to choose the team with the highest overall score. The score of the team is the **sum** of scores of all the players in the team. However, the basketball team is not allowed to have **conflicts**. A **conflict** exists if a younger player has a **strictly higher** score than an older player. A conflict does **not** occur between players of the same age. Given two lists, `scores` and `ages`, where each `scores[i]` and `ages[i]` represents the score and age of the `i`th player, respectively, return *the highest overall score of all possible basketball teams*. ### Examples ``` Input: scores = [1,3,5,10,15], ages = [1,2,3,4,5] Output: 34 Explanation: You can choose all the players. ``` ``` Input: scores = [4,5,6,5], ages = [2,1,2,1] Output: 16 Explanation: It is best to choose the last 3 players. Notice that you are allowed to choose multiple people of the same age. ``` ``` Input: scores = [1,2,3,5], ages = [8,9,10,1] Output: 6 Explanation: It is best to choose the first 3 players. ``` ### Constraints * 1 \<= scores.length, ages.length \<= 1000 * scores.length == ages.length * 1 \<= scores\[i] \<= 10^6 * 1 \<= ages\[i] \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_team_with_no_conflicts/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_team_with_no_conflicts/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) def best_team_score(self, scores: list[int], ages: list[int]) -> int: pairs = sorted(zip(scores, ages, strict=True), key=lambda p: (p[1], p[0])) ranks = {score: i for i, score in enumerate(sorted(set(scores)))} size = len(ranks) tree: list[int] = [0] * (size + 1) def update(index: int, value: int) -> None: index += 1 while index <= size: tree[index] = max(tree[index], value) index += index & (-index) def query(index: int) -> int: index += 1 best = 0 while index > 0: best = max(best, tree[index]) index -= index & (-index) return best result = 0 for score, _age in pairs: current = query(ranks[score]) + score result = max(result, current) update(ranks[score], current) return result ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Best Time to Buy and Sell Stock Source: https://leetcode-py.wisl.dev/problems/best-time-to-buy-and-sell-stock Tested Python solution for LeetCode 121 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 121, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 121 # by problem number lcpy gen -s best_time_to_buy_and_sell_stock # by problem name ``` ## Problem You are given an array `prices` where `prices[i]` is the price of a given stock on the ith day. You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock. Return *the maximum profit you can achieve from this transaction*. If you cannot achieve any profit, return `0`. ### Examples ``` Input: prices = [7,1,5,3,6,4] Output: 5 ``` **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. ``` Input: prices = [7,6,4,3,1] Output: 0 ``` **Explanation:** In this case, no transactions are done and the max profit = 0. ### Constraints * 1 \<= prices.length \<= 10^5 * 0 \<= prices\[i] \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_profit(self, prices: list[int]) -> int: min_price = prices[0] max_profit = 0 for price in prices[1:]: max_profit = max(max_profit, price - min_price) min_price = min(min_price, price) return max_profit ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Best Time to Buy and Sell Stock II Source: https://leetcode-py.wisl.dev/problems/best-time-to-buy-and-sell-stock-ii Tested Python solution for LeetCode 122 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 122, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 122 # by problem number lcpy gen -s best_time_to_buy_and_sell_stock_ii # by problem name ``` ## Problem You are given an integer array `prices` where `prices[i]` is the price of a given stock on the `i^th` day. On each day, you may decide to buy and/or sell the stock. You can only hold **at most one** share of the stock at any time. However, you can sell and buy the stock multiple times on the **same day**, ensuring you never hold more than one share of the stock. Find and return *the **maximum** profit you can achieve*. ### Examples ``` Input: prices = [7,1,5,3,6,4] Output: 7 ``` **Explanation:** Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. Total profit is 4 + 3 = 7. ``` Input: prices = [1,2,3,4,5] Output: 4 ``` **Explanation:** Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Total profit is 4. ``` Input: prices = [7,6,4,3,1] Output: 0 ``` **Explanation:** There is no way to make a positive profit, so we never buy the stock to achieve the maximum profit of 0. ### Constraints * 1 \<= prices.length \<= 3 \* 10^4 * 0 \<= prices\[i] \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_profit(self, prices: list[int]) -> int: profit = 0 for day in range(1, len(prices)): # Capture every positive upswing; sum equals any multi-day strategy if prices[day] > prices[day - 1]: profit += prices[day] - prices[day - 1] return profit ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Best Time to Buy and Sell Stock III Source: https://leetcode-py.wisl.dev/problems/best-time-to-buy-and-sell-stock-iii Tested Python solution for LeetCode 123 with 23 pytest cases. Generate a practice environment with lcpy. LeetCode 123, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/). Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 123 # by problem number lcpy gen -s best_time_to_buy_and_sell_stock_iii # by problem name ``` ## Problem You are given an array `prices` where `prices[i]` is the price of a given stock on the `i^th` day. Find the maximum profit you can achieve. You may complete at most **two transactions**. **Note:** You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again). ### Examples ``` Input: prices = [3,3,5,0,0,3,1,4] Output: 6 ``` **Explanation:** Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3. Total profit is 3 + 3 = 6. ``` Input: prices = [1,2,3,4,5] Output: 4 ``` **Explanation:** Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Total profit is 4. ``` Input: prices = [7,6,4,3,1] Output: 0 ``` **Explanation:** In this case, no transaction is done, i.e. max profit = 0. ### Constraints * 1 \<= prices.length \<= 10^5 * 0 \<= prices\[i] \<= 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_profit(self, prices: list[int]) -> int: buy1 = buy2 = -(10**18) sell1 = sell2 = 0 for price in prices: buy1 = max(buy1, -price) sell1 = max(sell1, buy1 + price) buy2 = max(buy2, sell1 - price) sell2 = max(sell2, buy2 + price) return sell2 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Best Time to Buy and Sell Stock IV Source: https://leetcode-py.wisl.dev/problems/best-time-to-buy-and-sell-stock-iv Tested Python solution for LeetCode 188 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 188, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 188 # by problem number lcpy gen -s best_time_to_buy_and_sell_stock_iv # by problem name ``` ## Problem You are given an integer array `prices` where `prices[i]` is the price of a given stock on the `i^th` day, and an integer `k`. Find the maximum profit you can achieve. You may complete at most `k` transactions: i.e. you may buy at most `k` times and sell at most `k` times. **Note:** You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again). ### Examples ``` Input: k = 2, prices = [2,4,1] Output: 2 ``` **Explanation:** Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2. ``` Input: k = 2, prices = [3,2,6,5,0,3] Output: 7 ``` **Explanation:** Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4. Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. Total profit is 4 + 3 = 7. ### Constraints * 1 \<= k \<= 100 * 1 \<= prices.length \<= 1000 * 0 \<= prices\[i] \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_iv/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_iv/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n * min(k, n // 2)) # Space: O(min(k, n // 2)) def max_profit(self, k: int, prices: list[int]) -> int: n = len(prices) if n == 0: return 0 # Each transaction uses at least two days, so more trades than n // 2 # degenerate into the unlimited-transaction case. limit = min(k, n // 2) buy = [-(10**9)] * (limit + 1) sell = [0] * (limit + 1) for price in prices: for j in range(1, limit + 1): buy[j] = max(buy[j], sell[j - 1] - price) sell[j] = max(sell[j], buy[j] + price) return sell[limit] ``` ## Complexity | Time | Space | | ---------------------- | ----------------- | | O(n \* min(k, n // 2)) | O(min(k, n // 2)) | ## Tags # Best Time to Buy and Sell Stock with Cooldown Source: https://leetcode-py.wisl.dev/problems/best-time-to-buy-and-sell-stock-with-cooldown Tested Python solution for LeetCode 309 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 309, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 309 # by problem number lcpy gen -s best_time_to_buy_and_sell_stock_with_cooldown # by problem name ``` ## Problem You are given an array `prices` where `prices[i]` is the price of a given stock on the `ith` day. Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times) with the following restrictions: * After you sell your stock, you cannot buy stock on the next day (i.e., cooldown one day). **Note:** You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again). ### Examples ``` Input: prices = [1,2,3,0,2] Output: 3 ``` **Explanation:** transactions = \[buy, sell, cooldown, buy, sell] ``` Input: prices = [1] Output: 0 ``` ### Constraints * 1 \<= prices.length \<= 5000 * 0 \<= prices\[i] \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_with_cooldown/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_with_cooldown/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_profit(self, prices: list[int]) -> int: # State machine: held (own stock), sold (just sold -> cooldown), reset (no stock) held = float("-inf") sold = float("-inf") reset = 0 for price in prices: prev_held, prev_sold, prev_reset = held, sold, reset held = max(prev_held, prev_reset - price) reset = max(prev_reset, prev_sold) sold = prev_held + price return int(max(sold, reset)) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Best Time to Buy and Sell Stock with Source: https://leetcode-py.wisl.dev/problems/best-time-to-buy-and-sell-stock-with-transaction-fee Tested Python solution for LeetCode 714 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 714, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 714 # by problem number lcpy gen -s best_time_to_buy_and_sell_stock_with_transaction_fee # by problem name ``` ## Problem You are given an array `prices` where `prices[i]` is the price of a given stock on the `i^th` day, and an integer `fee` representing a transaction fee. Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. **Note:** * You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again). * The transaction fee is only charged once for each stock purchase and sale. ### Examples ``` Input: prices = [1,3,2,8,4,9], fee = 2 Output: 8 ``` **Explanation:** The maximum profit can be achieved by: * Buying at prices\[0] = 1 * Selling at prices\[3] = 8 * Buying at prices\[4] = 4 * Selling at prices\[5] = 9 The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. ``` Input: prices = [1,3,7,5,10,3], fee = 3 Output: 6 ``` ### Constraints * 1 \<= prices.length \<= 5 \* 10^4 * 1 \<= prices\[i] \< 5 \* 10^4 * 0 \<= fee \< 5 \* 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_with_transaction_fee/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/best_time_to_buy_and_sell_stock_with_transaction_fee/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_profit(self, prices: list[int], fee: int) -> int: cash = 0 hold = -prices[0] for price in prices[1:]: cash = max(cash, hold + price - fee) hold = max(hold, cash - price) return cash ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Binary Gap Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-gap Tested Python solution for LeetCode 868 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 868, [Easy](/catalog/easy). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/binary-gap/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 868 # by problem number lcpy gen -s binary_gap # by problem name ``` ## Problem Given a positive integer `n`, find and return *the **longest distance** between any two **adjacent*** `1`*'s in the binary representation of* `n`. If there are no two adjacent `1`'s, return `0`. Two `1`'s are **adjacent** if there are only `0`'s separating them (possibly no `0`'s). The **distance** between two `1`'s is the absolute difference between their bit positions. For example, the two `1`'s in `"1001"` have a distance of 3. ### Examples ``` Input: n = 22 Output: 2 ``` **Explanation:** 22 in binary is `"10110"`. The first adjacent pair of 1's is `"10110"` with a distance of 2. The second adjacent pair of 1's is `"10110"` with a distance of 1. The answer is the largest of these two distances, which is 2. Note that `"10110"` is not a valid pair since there is a 1 separating the two 1's underlined. ``` Input: n = 8 Output: 0 ``` **Explanation:** 8 in binary is `"1000"`. There are not any adjacent pairs of 1's in the binary representation of 8, so we return 0. ``` Input: n = 5 Output: 2 ``` **Explanation:** 5 in binary is `"101"`. ### Constraints * 1 \<= n \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_gap/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_gap/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log n) # Space: O(1) def binary_gap(self, n: int) -> int: best = 0 prev = -1 i = 0 while n: if n & 1: if prev >= 0: best = max(best, i - prev) prev = i n >>= 1 i += 1 return best ``` ## Complexity | Time | Space | | -------- | ----- | | O(log n) | O(1) | ## Tags # Binary Number with Alternating Bits Source: https://leetcode-py.wisl.dev/problems/binary-number-with-alternating-bits Tested Python solution for LeetCode 693 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 693, [Easy](/catalog/easy). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/binary-number-with-alternating-bits/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 693 # by problem number lcpy gen -s binary_number_with_alternating_bits # by problem name ``` ## Problem Given a positive integer, check whether it has alternating bits: namely, if two adjacent bits will always have different values. ### Examples ``` Input: n = 5 Output: true Explanation: The binary representation of 5 is: 101 ``` ``` Input: n = 7 Output: false Explanation: The binary representation of 7 is: 111. ``` ``` Input: n = 11 Output: false Explanation: The binary representation of 11 is: 1011. ``` ### Constraints * 1 \<= n \<= 2^31 - 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_number_with_alternating_bits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_number_with_alternating_bits/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(1) (at most 31 iterations for the 32-bit constraint) # Space: O(1) def has_alternating_bits(self, n: int) -> bool: # x = n ^ (n >> 1) has every bit set iff adjacent bits all differ; # adding the carry back onto x must produce the next power of two. x = n ^ (n >> 1) return x & (x + 1) == 0 ``` ## Complexity | Time | Space | | ------------------------------------------------------ | ----- | | O(1) (at most 31 iterations for the 32-bit constraint) | O(1) | ## Tags # Binary Search Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-search Tested Python solution for LeetCode 704 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 704, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/binary-search/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 704 # by problem number lcpy gen -s binary_search # by problem name ``` ## Problem 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`. You must write an algorithm with `O(log n)` runtime complexity. ### Examples ``` Input: nums = [-1,0,3,5,9,12], target = 9 Output: 4 ``` **Explanation:** 9 exists in nums and its index is 4 ``` Input: nums = [-1,0,3,5,9,12], target = 2 Output: -1 ``` **Explanation:** 2 does not exist in nums so return -1 ### Constraints * `1 <= nums.length <= 10^4` * `-10^4 < nums[i], target < 10^4` * All the integers in `nums` are **unique**. * `nums` is sorted in ascending order. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_search/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_search/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log n) # Space: O(1) def search(self, nums: list[int], target: int) -> int: left, right = 0, len(nums) - 1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: return mid elif nums[mid] < target: left = mid + 1 else: right = mid - 1 return -1 ``` ## Complexity | Time | Space | | -------- | ----- | | O(log n) | O(1) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Binary Search Tree Iterator Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-search-tree-iterator Tested Python solution for LeetCode 173 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 173, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Design](/catalog/topics/design), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree), Iterator. [View on LeetCode](https://leetcode.com/problems/binary-search-tree-iterator/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 173 # by problem number lcpy gen -s binary_search_tree_iterator # by problem name ``` ## Problem Implement the `BSTIterator` class that represents an iterator over the **in-order traversal** of a binary search tree (BST): * `BSTIterator(TreeNode root)` Initializes an object of the `BSTIterator` class. The root of the BST is given as part of the constructor. The pointer should be initialized to a non-existent number smaller than any element in the BST. * `boolean hasNext()` Returns `true` if there exists a number in the traversal to the right of the pointer, otherwise returns `false`. * `int next()` Moves the pointer to the right, then returns the number at the pointer. Notice that by initializing the pointer to a non-existent smallest number, the first call to `next()` will return the smallest element in the BST. You may assume that `next()` calls will always be valid. That is, there will be at least a next number in the in-order traversal when `next()` is called. ### Examples  ``` Input ["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"] [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []] Output [null, 3, 7, true, 9, true, 15, true, 20, false] Explanation BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]); bSTIterator.next(); // return 3 bSTIterator.next(); // return 7 bSTIterator.hasNext(); // return True bSTIterator.next(); // return 9 bSTIterator.hasNext(); // return True bSTIterator.next(); // return 15 bSTIterator.hasNext(); // return True bSTIterator.next(); // return 20 bSTIterator.hasNext(); // return False ``` ### Constraints * The number of nodes in the tree is in the range \[1, 10\5\] * 0 \<= Node.val \<= 10\6\ * At most 10\5\ calls will be made to hasNext, and next. **Follow up:** * Could you implement `next()` and `hasNext()` to run in average `O(1)` time and use `O(h)` memory, where `h` is the height of the tree? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_search_tree_iterator/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_search_tree_iterator/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class BSTIterator: # Time: O(1) average per operation # Space: O(h) def __init__(self, root: TreeNode[int] | None) -> None: self._stack: list[TreeNode[int]] = [] self._push_left(root) def _push_left(self, node: TreeNode[int] | None) -> None: while node is not None: self._stack.append(node) node = node.left # Time: O(1) average # Space: O(1) def next(self) -> int: node = self._stack.pop() self._push_left(node.right) return node.val # Time: O(1) # Space: O(1) def has_next(self) -> bool: return len(self._stack) > 0 ``` ## Complexity | Time | Space | | -------------------------- | ----- | | O(1) average per operation | O(h) | ## Tags [NeetCode All](/catalog/neetcode). # Binary Searchable Numbers in an Unsorted Array Source: https://leetcode-py.wisl.dev/problems/binary-searchable-numbers-in-an-unsorted-array Tested Python solution for LeetCode 1966 with 27 pytest cases. Generate a practice environment with lcpy. LeetCode 1966, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/binary-searchable-numbers-in-an-unsorted-array/description/). Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1966 # by problem number lcpy gen -s binary_searchable_numbers_in_an_unsorted_array # by problem name ``` ## Problem \Consider a function that implements an algorithm \similar\ to \Binary Search\. The function has two input parameters: \sequence\ is a sequence of integers, and \target\ is an integer value. The purpose of the function is to find if the \target\ exists in the \sequence\.\
The pseudocode of the function is as follows:\
\func(sequence, target) while sequence is not empty \randomly\ choose an element from sequence as the pivot if pivot = target, return \true\ else if pivot \< target, remove pivot and all elements to its left from the sequence else, remove pivot and all elements to its right from the sequence end while return \false\ \\
When the \sequence\ is sorted, the function works correctly for \all\ values. When the \sequence\ is not sorted, the function does not work for all values, but may still work for \some\ values.\
Given an integer array \nums\, representing the \sequence\, that contains \unique\ numbers and \may or may not be sorted\, return \the number of values that are \guaranteed\ to be found using the function, for \every possible\ pivot selection\.\
nums\ are \unique\.
\\Follow-up:\ If \nums\ has \duplicates\, would you modify your algorithm? If so, how?\
Given a binary array \nums\ and an integer \goal\, return \the number of non-empty \subarrays\ with a sum\ \goal\.\
A \subarray\ is a contiguous part of the array.\
### Examples ``` Input: nums = [1,0,1,0,1], goal = 2 Output: 4 Explanation: The 4 subarrays are bolded and underlined below: [1,0,1,0,1] [1,0,1,0,1] [1,0,1,0,1] [1,0,1,0,1] ``` ``` Input: nums = [0,0,0,0,0], goal = 0 Output: 15 ``` ### Constraints * 1 \<= nums.length \<= 3 \* 10^4 * nums\[i] is either 0 or 1. * 0 \<= goal \<= nums.length ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_subarrays_with_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_subarrays_with_sum/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def num_subarrays_with_sum(self, nums: list[int], goal: int) -> int: # Prefix sum counts: sum -> number of prefixes with that sum prefix_counts: dict[int, int] = {0: 1} total = 0 count = 0 for num in nums: total += num count += prefix_counts.get(total - goal, 0) prefix_counts[total] = prefix_counts.get(total, 0) + 1 return count ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Binary Tree Cameras Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-tree-cameras Tested Python solution for LeetCode 968 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 968, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree), DP on Trees. [View on LeetCode](https://leetcode.com/problems/binary-tree-cameras/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 968 # by problem number lcpy gen -s binary_tree_cameras # by problem name ``` ## Problem You are given the `root` of a binary tree. We install cameras on the tree nodes where each camera at a node can monitor its parent, itself, and its immediate children. Return the minimum number of cameras needed to monitor all nodes of the tree. ### Examples  ``` Input: root = [0,0,null,0,0] Output: 1 Explanation: One camera is enough to monitor all nodes if placed as shown. ```  ``` Input: root = [0,0,null,0,null,0,null,null,0] Output: 2 Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement. ``` ### Constraints * The number of nodes in the tree is in the range \[1, 1000] * Node.val == 0 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_cameras/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_cameras/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) for the recursion stack def min_camera_cover(self, root: TreeNode[int] | None) -> int: cameras = 0 # Post-order status per subtree: 0 needs a camera, 1 covered, 2 holds a camera def dfs(node: TreeNode[int] | None) -> int: nonlocal cameras if node is None: return 1 left = dfs(node.left) right = dfs(node.right) if left == 0 or right == 0: cameras += 1 return 2 if left == 2 or right == 2: return 1 return 0 if dfs(root) == 0: cameras += 1 return cameras ``` ## Complexity | Time | Space | | ---- | ---------------------------- | | O(n) | O(h) for the recursion stack | ## Tags # Binary Tree Inorder Traversal Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-tree-inorder-traversal Tested Python solution for LeetCode 94 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 94, [Easy](/catalog/easy). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-inorder-traversal/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 94 # by problem number lcpy gen -s binary_tree_inorder_traversal # by problem name ``` ## Problem Given the `root` of a binary tree, return the inorder traversal of its nodes' values. ### Examples  ``` Input: root = [1,null,2,3] Output: [1,3,2] ```  ``` Input: root = [1,2,3,4,5,null,8,null,null,6,7,9] Output: [4,2,6,5,7,1,3,9,8] ``` ``` Input: root = [] Output: [] ``` ``` Input: root = [1] Output: [1] ``` ### Constraints * The number of nodes in the tree is in the range `[0, 100]` * `-100 <= Node.val <= 100` **Follow up:** Recursive solution is trivial, could you do it iteratively? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_inorder_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_inorder_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) where h is the height of the tree def inorder_traversal(self, root: TreeNode[int] | None) -> list[int]: result: list[int] = [] stack: list[TreeNode[int]] = [] current: TreeNode[int] | None = root while current or stack: while current: stack.append(current) current = current.left current = stack.pop() result.append(current.val) current = current.right return result ``` ## Complexity | Time | Space | | ---- | -------------------------------------- | | O(n) | O(h) where h is the height of the tree | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Binary Tree Level Order Traversal Source: https://leetcode-py.wisl.dev/problems/binary-tree-level-order-traversal Tested Python solution for LeetCode 102 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 102, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-level-order-traversal/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 102 # by problem number lcpy gen -s binary_tree_level_order_traversal # by problem name ``` ## Problem 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). ### Examples  ``` Input: root = [3,9,20,null,null,15,7] Output: [[3],[9,20],[15,7]] ``` ``` Input: root = [1] Output: [[1]] ``` ``` Input: root = [] Output: [] ``` ### Constraints * The number of nodes in the tree is in the range \[0, 2000] * -1000 \<= Node.val \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_level_order_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_level_order_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(w) where w is max width of tree def level_order(self, root: TreeNode[int] | None) -> list[list[int]]: if not root: return [] result = [] queue = deque([root]) while queue: level_size = len(queue) level = [] for _ in range(level_size): node = queue.popleft() level.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) result.append(level) return result ``` ## Complexity | Time | Space | | ---- | --------------------------------- | | O(n) | O(w) where w is max width of tree | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Binary Tree Level Order Traversal II Source: https://leetcode-py.wisl.dev/problems/binary-tree-level-order-traversal-ii Tested Python solution for LeetCode 107 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 107, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-level-order-traversal-ii/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 107 # by problem number lcpy gen -s binary_tree_level_order_traversal_ii # by problem name ``` ## Problem Given the `root` of a binary tree, return the bottom-up level order traversal of its nodes' values. (i.e., from left to right, level by level from leaf to root). ### Examples  ``` Input: root = [3,9,20,null,null,15,7] Output: [[15,7],[9,20],[3]] ``` ``` Input: root = [1] Output: [[1]] ``` ``` Input: root = [] Output: [] ``` ### Constraints * The number of nodes in the tree is in the range \[0, 2000] * -1000 \<= Node.val \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_level_order_traversal_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_level_order_traversal_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(n) def level_order_bottom(self, root: TreeNode[int] | None) -> list[list[int]]: levels: list[list[int]] = [] frontier = [root] if root is not None else [] while frontier: levels.append([node.val for node in frontier]) frontier = [ child for node in frontier for child in (node.left, node.right) if child is not None ] levels.reverse() return levels ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Binary Tree Longest Consecutive Sequence Source: https://leetcode-py.wisl.dev/problems/binary-tree-longest-consecutive-sequence Tested Python solution for LeetCode 298 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 298, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 298 # by problem number lcpy gen -s binary_tree_longest_consecutive_sequence # by problem name ``` ## Problem Given the `root` of a binary tree, return *the length of the longest **consecutive sequence path***. A **consecutive sequence path** is a path where the values **increase by one** along the path. Note that the path can start **at any node** in the tree, and you cannot go from a node to its parent in the path. ### Examples  ``` Input: root = [1,null,3,2,4,null,null,null,5] Output: 3 Explanation: Longest consecutive sequence path is 3-4-5, so return 3. ```  ``` Input: root = [2,null,3,2,null,1] Output: 2 Explanation: Longest consecutive sequence path is 2-3, not 3-2-1, so return 2. ``` ### Constraints * The number of nodes in the tree is in the range `[1, 3 * 10^4]`. * `-3 * 10^4 <= Node.val <= 3 * 10^4` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_longest_consecutive_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_longest_consecutive_sequence/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) — each node visited once # Space: O(h) — recursion depth equals tree height def longest_consecutive(self, root: TreeNode[int] | None) -> int: def dfs(node: TreeNode[int] | None, parent_val: int | None, length: int) -> int: if node is None: return length length = length + 1 if parent_val is not None and node.val - parent_val == 1 else 1 return max( length, dfs(node.left, node.val, length), dfs(node.right, node.val, length), ) return dfs(root, None, 0) ``` ## Complexity | Time | Space | | ----------------------------- | ----------------------------------------- | | O(n) — each node visited once | O(h) — recursion depth equals tree height | ## Tags [NeetCode All](/catalog/neetcode). # Binary Tree Longest Consecutive Sequence II Source: https://leetcode-py.wisl.dev/problems/binary-tree-longest-consecutive-sequence-ii Tested Python solution for LeetCode 549 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 549, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree), Tree DP. [View on LeetCode](https://leetcode.com/problems/binary-tree-longest-consecutive-sequence-ii/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 549 # by problem number lcpy gen -s binary_tree_longest_consecutive_sequence_ii # by problem name ``` ## Problem Given the `root` of a binary tree, return the length of the longest consecutive path in the tree. A consecutive path is a path where the values of the consecutive nodes in the path differ by one. This path can be either increasing or decreasing. * For example, `[1,2,3,4]` and `[4,3,2,1]` are both considered valid, but the path `[1,2,4,3]` is not valid. On the other hand, the path can be in the child-Parent-child order, where not necessarily be parent-child order. ### Examples  ``` Input: root = [1,2,3] Output: 2 Explanation: The longest consecutive path is [1, 2] or [2, 1]. ```  ``` Input: root = [2,1,3] Output: 3 Explanation: The longest consecutive path is [1, 2, 3] or [3, 2, 1]. ``` ### Constraints * The number of nodes in the tree is in the range `[1, 3 * 10^4]`. * `-3 * 10^4 <= Node.val <= 3 * 10^4` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_longest_consecutive_sequence_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_longest_consecutive_sequence_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) def longest_consecutive(self, root: TreeNode[int] | None) -> int: best = 0 def dfs(node: TreeNode[int] | None) -> tuple[int, int]: nonlocal best if node is None: return (0, 0) inc = dec = 1 for child in (node.left, node.right): if child is None: continue child_inc, child_dec = dfs(child) if child.val == node.val + 1: inc = max(inc, child_inc + 1) if child.val == node.val - 1: dec = max(dec, child_dec + 1) best = max(best, inc + dec - 1) return (inc, dec) dfs(root) return best ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(h) | ## Tags [NeetCode All](/catalog/neetcode). # Binary Tree Maximum Path Sum Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-tree-maximum-path-sum Tested Python solution for LeetCode 124 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 124, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-maximum-path-sum/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 124 # by problem number lcpy gen -s binary_tree_maximum_path_sum # by problem name ``` ## Problem A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root. The **path sum** of a path is the sum of the node's values in the path. Given the `root` of a binary tree, return *the maximum **path sum** of any **non-empty** path*. ### Examples  ``` Input: root = [1,2,3] Output: 6 Explanation: The optimal path is 2 -> 1 -> 3 with a path sum of 2 + 1 + 3 = 6. ```  ``` Input: root = [-10,9,20,null,null,15,7] Output: 42 Explanation: The optimal path is 15 -> 20 -> 7 with a path sum of 15 + 20 + 7 = 42. ``` ### Constraints * The number of nodes in the tree is in the range \[1, 3 \* 10^4]. * -1000 \<= Node.val \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_maximum_path_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_maximum_path_sum/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) where n is the number of nodes # Space: O(h) where h is the height of the tree (recursion stack) def max_path_sum(self, root: TreeNode[int] | None) -> int: """ Find the maximum path sum in a binary tree. A path is a sequence of nodes where each pair of adjacent nodes has an edge connecting them. A node can only appear once in the path. The path doesn't need to pass through the root. Uses DFS with post-order traversal to calculate: 1. Maximum path sum that can be extended upward from current node 2. Maximum path sum that includes current node as the highest point """ if not root: return 0 max_sum = float("-inf") def dfs(node: TreeNode[int] | None) -> int: nonlocal max_sum if not node: return 0 # Get maximum path sum from left and right subtrees # If negative, we don't include them (take 0 instead) left_max = max(0, dfs(node.left)) right_max = max(0, dfs(node.right)) # Current path sum if this node is the highest point # (left path + current node + right path) current_path_sum = node.val + left_max + right_max # Update global maximum max_sum = max(max_sum, current_path_sum) # Return maximum path sum that can be extended upward # (either left or right path + current node) return node.val + max(left_max, right_max) dfs(root) return int(max_sum) ``` ## Complexity | Time | Space | | ----------------------------------- | -------------------------------------------------------- | | O(n) where n is the number of nodes | O(h) where h is the height of the tree (recursion stack) | ## Tags [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Binary Tree Paths Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-tree-paths Tested Python solution for LeetCode 257 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 257, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-paths/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 257 # by problem number lcpy gen -s binary_tree_paths # by problem name ``` ## Problem Given the `root` of a binary tree, return all root-to-leaf paths in any order. A **leaf** is a node with no children. ### Examples  ``` Input: root = [1,2,3,null,5] Output: ["1->2->5","1->3"] ``` ``` Input: root = [1] Output: ["1"] ``` ### Constraints * The number of nodes in the tree is in the range `[1, 100]`. * `-100 <= Node.val <= 100` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_paths/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_paths/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n * d) where d is the average path length # Space: O(h) for the recursion stack, excluding the output def binary_tree_paths(self, root: TreeNode[int] | None) -> list[str]: paths: list[str] = [] def dfs(node: TreeNode[int] | None, path: list[str]) -> None: if node is None: return path.append(str(node.val)) if node.left is None and node.right is None: paths.append("->".join(path)) else: dfs(node.left, path) dfs(node.right, path) path.pop() dfs(root, []) return paths ``` ## Complexity | Time | Space | | -------------------------------------------- | -------------------------------------------------- | | O(n \* d) where d is the average path length | O(h) for the recursion stack, excluding the output | ## Tags # Binary Tree Postorder Traversal Source: https://leetcode-py.wisl.dev/problems/binary-tree-postorder-traversal Tested Python solution for LeetCode 145 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 145, [Easy](/catalog/easy). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-postorder-traversal/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 145 # by problem number lcpy gen -s binary_tree_postorder_traversal # by problem name ``` ## Problem Given the `root` of a binary tree, return the postorder traversal of its nodes' values. ### Examples  ``` Input: root = [1,null,2,3] Output: [3,2,1] ```  ``` Input: root = [1,2,3,4,5,null,8,null,null,6,7,9] Output: [4,6,7,5,2,9,8,3,1] ``` ``` Input: root = [] Output: [] ``` ``` Input: root = [1] Output: [1] ``` ### Constraints * The number of nodes in the tree is in the range \[0, 100]. * -100 \<= Node.val \<= 100 **Follow up:** Recursive solution is trivial, could you do it iteratively? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_postorder_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_postorder_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) where h is the height of the tree def postorder_traversal(self, root: TreeNode[int] | None) -> list[int]: if not root: return [] result: list[int] = [] stack: list[TreeNode[int]] = [root] while stack: node = stack.pop() result.append(node.val) # Push left first, then right (so right is processed first) if node.left: stack.append(node.left) if node.right: stack.append(node.right) # Reverse to get postorder (left, right, root) return result[::-1] ``` ## Complexity | Time | Space | | ---- | -------------------------------------- | | O(n) | O(h) where h is the height of the tree | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Binary Tree Preorder Traversal Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-tree-preorder-traversal Tested Python solution for LeetCode 144 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 144, [Easy](/catalog/easy). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-preorder-traversal/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 144 # by problem number lcpy gen -s binary_tree_preorder_traversal # by problem name ``` ## Problem Given the `root` of a binary tree, return the preorder traversal of its nodes' values. ### Examples  ``` Input: root = [1,null,2,3] Output: [1,2,3] ```  ``` Input: root = [1,2,3,4,5,null,8,null,null,6,7,9] Output: [1,2,4,5,6,7,3,8,9] ``` ``` Input: root = [] Output: [] ``` ``` Input: root = [1] Output: [1] ``` ### Constraints * The number of nodes in the tree is in the range \[0, 100]. * -100 \<= Node.val \<= 100 **Follow up:** Recursive solution is trivial, could you do it iteratively? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_preorder_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_preorder_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) where h is the height of the tree def preorder_traversal(self, root: TreeNode[int] | None) -> list[int]: if not root: return [] result: list[int] = [] stack: list[TreeNode[int]] = [root] while stack: node = stack.pop() result.append(node.val) # Push right first, then left (so left is processed first) if node.right: stack.append(node.right) if node.left: stack.append(node.left) return result ``` ## Complexity | Time | Space | | ---- | -------------------------------------- | | O(n) | O(h) where h is the height of the tree | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Binary Tree Pruning Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-tree-pruning Tested Python solution for LeetCode 814 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 814, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-pruning/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 814 # by problem number lcpy gen -s binary_tree_pruning # by problem name ``` ## Problem Given the `root` of a binary tree, return the same tree where every subtree (of the given tree) not containing a `1` has been removed. A subtree of a node `node` is `node` plus every node that is a descendant of `node`. ### Examples  ``` Input: root = [1,null,0,0,1] Output: [1,null,0,null,1] Explanation: Only the red nodes satisfy the property "every subtree not containing a 1". The diagram on the right represents the answer. ```  ``` Input: root = [1,0,1,0,0,0,1] Output: [1,null,1,null,1] ```  ``` Input: root = [1,1,0,1,1,0,1,0] Output: [1,1,0,1,1,null,1] ``` ### Constraints * The number of nodes in the tree is in the range \[1, 200] * Node.val is either 0 or 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_pruning/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_pruning/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) def prune_tree(self, root: TreeNode[int] | None) -> TreeNode[int] | None: if root is None: return None root.left = self.prune_tree(root.left) root.right = self.prune_tree(root.right) if root.val == 0 and root.left is None and root.right is None: return None return root ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(h) | ## Tags # Binary Tree Right Side View Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-tree-right-side-view Tested Python solution for LeetCode 199 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 199, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-right-side-view/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 199 # by problem number lcpy gen -s binary_tree_right_side_view # by problem name ``` ## Problem 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*. ### Examples  ``` Input: root = [1,2,3,null,5,null,4] Output: [1,3,4] ```  ``` Input: root = [1,2,3,4,null,null,null,5] Output: [1,3,4,5] ``` ``` Input: root = [1,null,3] Output: [1,3] ``` ``` Input: root = [] Output: [] ``` ### Constraints * The number of nodes in the tree is in the range `[0, 100]`. * `-100 <= Node.val <= 100` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_right_side_view/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_right_side_view/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) def right_side_view(self, root: TreeNode[int] | None) -> list[int]: result: list[int] = [] def dfs(node: TreeNode[int] | None, level: int) -> None: if not node: return if level == len(result): result.append(node.val) dfs(node.right, level + 1) dfs(node.left, level + 1) dfs(root, 0) return result class SolutionDFS: # Time: O(n) # Space: O(h) def right_side_view(self, root: TreeNode[int] | None) -> list[int]: if not root: return [] result: list[int] = [] stack = [(root, 0)] while stack: node, level = stack.pop() if level == len(result): result.append(node.val) if node.left: stack.append((node.left, level + 1)) if node.right: stack.append((node.right, level + 1)) return result class SolutionBFS: # Time: O(n) # Space: O(w) def right_side_view(self, root: TreeNode[int] | None) -> list[int]: if not root: return [] result: list[int] = [] queue = deque([root]) while queue: level_size = len(queue) for i in range(level_size): node = queue.popleft() if i == level_size - 1: # rightmost node result.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return result ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(h) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Binary Tree Tilt Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-tree-tilt Tested Python solution for LeetCode 563 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 563, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree), DP on Trees. [View on LeetCode](https://leetcode.com/problems/binary-tree-tilt/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 563 # by problem number lcpy gen -s binary_tree_tilt # by problem name ``` ## Problem Given the `root` of a binary tree, return *the sum of every tree node's **tilt***. The **tilt** of a tree node is the **absolute difference** between the sum of all left subtree node **values** and all right subtree node **values**. If a node does not have a left child, then the sum of the left subtree node **values** is treated as `0`. The rule is similar if the node does not have a right child. ### Examples  ``` Input: root = [1,2,3] Output: 1 Explanation: Tilt of node 2 : |0-0| = 0 (no children) Tilt of node 3 : |0-0| = 0 (no children) Tilt of node 1 : |2-3| = 1 (left subtree is just left child, so sum is 2; right subtree is just right child, so sum is 3) Sum of every tilt : 0 + 0 + 1 = 1 ```  ``` Input: root = [4,2,9,3,5,null,7] Output: 15 Explanation: Tilt of node 3 : |0-0| = 0 (no children) Tilt of node 5 : |0-0| = 0 (no children) Tilt of node 7 : |0-0| = 0 (no children) Tilt of node 2 : |3-5| = 2 (left subtree is just left child, so sum is 3; right subtree is just right child, so sum is 5) Tilt of node 9 : |0-7| = 7 (no left child, so sum is 0; right subtree is just right child, so sum is 7) Tilt of node 4 : |(3+5+2)-(9+7)| = |10-16| = 6 (left subtree values are 3, 5, and 2, which sums to 10; right subtree values are 9 and 7, which sums to 16) Sum of every tilt : 0 + 0 + 0 + 2 + 7 + 6 = 15 ```  ``` Input: root = [21,7,14,1,1,2,2,3,3] Output: 9 ``` ### Constraints * The number of nodes in the tree is in the range `[0, 10^4]`. * `-1000 <= Node.val <= 1000` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_tilt/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_tilt/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) for the recursion stack def find_tilt(self, root: TreeNode[int] | None) -> int: total = 0 def dfs(node: TreeNode[int] | None) -> int: nonlocal total if node is None: return 0 left_sum = dfs(node.left) right_sum = dfs(node.right) total += abs(left_sum - right_sum) return left_sum + right_sum + node.val dfs(root) return total ``` ## Complexity | Time | Space | | ---- | ---------------------------- | | O(n) | O(h) for the recursion stack | ## Tags # Binary Tree Upside Down Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-tree-upside-down Tested Python solution for LeetCode 156 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 156, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-upside-down/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 156 # by problem number lcpy gen -s binary_tree_upside_down # by problem name ``` ## Problem Given the `root` of a binary tree, turn the tree upside down and return the new root. You can turn a binary tree upside down with the following steps: 1. The original left child becomes the new root. 2. The original root becomes the new right child. 3. The original right child becomes the new left child. The mentioned steps are done level by level. It is guaranteed that every right node has a sibling (a left node that shares the same parent) and has no children. ### Examples ``` Input: root = [1,2,3,4,5] Output: [4,5,2,null,null,3,1] ``` ``` Input: root = [] Output: [] ``` ``` Input: root = [1] Output: [1] ``` ### Constraints * The number of nodes in the tree is in the range \[0, 10] * 1 \<= Node.val \<= 10 * Every right node in the tree has a sibling (a left node that shares the same parent) * Every right node in the tree has no children ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_upside_down/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_upside_down/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(1) def upside_down_binary_tree(self, root: TreeNode[int] | None) -> TreeNode[int] | None: curr = root prev: TreeNode[int] | None = None prev_right: TreeNode[int] | None = None while curr is not None: next_curr = curr.left orig_right = curr.right curr.left = prev_right curr.right = prev prev_right = orig_right prev = curr curr = next_curr return prev ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Binary Tree Vertical Order Traversal Source: https://leetcode-py.wisl.dev/problems/binary-tree-vertical-order-traversal Tested Python solution for LeetCode 314 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 314, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Hash Table](/catalog/topics/hash-table), [Binary Tree](/catalog/topics/binary-tree), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/binary-tree-vertical-order-traversal/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 314 # by problem number lcpy gen -s binary_tree_vertical_order_traversal # by problem name ``` ## Problem Given the `root` of a binary tree, return **the vertical order traversal** of its nodes' values. (i.e., from top to bottom, column by column). If two nodes are in the same row and column, the order should be from **left to right**. ### Examples  ``` Input: root = [3,9,20,null,null,15,7] Output: [[9],[3,15],[20],[7]] ```  ``` Input: root = [3,9,8,4,0,1,7] Output: [[4],[9],[3,0,1],[8],[7]] ```  ``` Input: root = [1,2,3,4,10,9,11,null,5,null,null,null,null,null,null,null,6] Output: [[4],[2,5],[1,10,9,6],[3],[11]] ``` ### Constraints * The number of nodes in the tree is in the range `[0, 100]`. * `-100 <= Node.val <= 100` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_vertical_order_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_vertical_order_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque from leetcode_py import TreeNode class Solution: # Time: O(n) — BFS visit plus one pass over the column span # Space: O(n) — queue and column buckets def vertical_order(self, root: TreeNode[int] | None) -> list[list[int]]: if root is None: return [] columns: dict[int, list[int]] = {} queue: deque[tuple[TreeNode[int], int]] = deque([(root, 0)]) min_col = max_col = 0 while queue: node, col = queue.popleft() columns.setdefault(col, []).append(node.val) min_col = min(min_col, col) max_col = max(max_col, col) if node.left is not None: queue.append((node.left, col - 1)) if node.right is not None: queue.append((node.right, col + 1)) return [columns[col] for col in range(min_col, max_col + 1)] ``` ## Complexity | Time | Space | | --------------------------------------------------- | ------------------------------- | | O(n) — BFS visit plus one pass over the column span | O(n) — queue and column buckets | ## Tags [NeetCode All](/catalog/neetcode). # Binary Tree Zigzag Level Order Traversal Source: https://leetcode-py.wisl.dev/problems/binary-tree-zigzag-level-order-traversal Tested Python solution for LeetCode 103 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 103, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 103 # by problem number lcpy gen -s binary_tree_zigzag_level_order_traversal # by problem name ``` ## Problem Given the `root` of a binary tree, return *the zigzag level order traversal of its nodes' values*. (i.e., from left to right, then right to left for the next level and alternate between). ### Examples  ``` Input: root = [3,9,20,null,null,15,7] Output: [[3],[20,9],[15,7]] ``` ``` Input: root = [1] Output: [[1]] ``` ``` Input: root = [] Output: [] ``` ### Constraints * The number of nodes in the tree is in the range \[0, 2000]. * -100 \<= Node.val \<= 100 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_zigzag_level_order_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_tree_zigzag_level_order_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque from leetcode_py import TreeNode class Solution: # Time: O(n) — each node processed once # Space: O(n) — queue holds widest level def zigzag_level_order(self, root: TreeNode[int] | None) -> list[list[int]]: if not root: return [] result: list[list[int]] = [] queue: deque[TreeNode[int]] = deque([root]) left_to_right = True while queue: level: deque[int] = deque() for _ in range(len(queue)): node = queue.popleft() if left_to_right: level.append(node.val) else: level.appendleft(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) result.append(list(level)) left_to_right = not left_to_right return result ``` ## Complexity | Time | Space | | ------------------------------- | ------------------------------- | | O(n) — each node processed once | O(n) — queue holds widest level | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Binary Trees With Factors Python Solution Source: https://leetcode-py.wisl.dev/problems/binary-trees-with-factors Tested Python solution for LeetCode 823 with 23 pytest cases. Generate a practice environment with lcpy. LeetCode 823, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/binary-trees-with-factors/description/). Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 823 # by problem number lcpy gen -s binary_trees_with_factors # by problem name ``` ## Problem Given an array of unique integers, `arr`, where each integer `arr[i]` is strictly greater than `1`. We make a binary tree using these integers, and each number may be used for any number of times. Each non-leaf node's value should be equal to the product of the values of its children. Return *the number of binary trees we can make*. The answer may be too large so return the answer **modulo** `10^9 + 7`. ### Examples ``` Input: arr = [2,4] Output: 3 Explanation: We can make these trees: [2], [4], [4, 2, 2] ``` ``` Input: arr = [2,4,5,10] Output: 7 Explanation: We can make these trees: [2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2]. ``` ### Constraints * `1 <= arr.length <= 1000` * `2 <= arr[i] <= 10^9` * All the values of `arr` are **unique**. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_trees_with_factors/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_trees_with_factors/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n) def num_factored_binary_trees(self, arr: list[int]) -> int: mod = 10**9 + 7 vals = sorted(arr) index = {v: i for i, v in enumerate(vals)} count_for: dict[int, int] = {} total = 0 for i, v in enumerate(vals): ways = 1 for j in range(i): if v % vals[j]: continue complement = v // vals[j] if complement in index and index[complement] < i: ways += count_for[vals[j]] * count_for[complement] count_for[v] = ways total += ways return total % mod ``` ## Complexity | Time | Space | | ------ | ----- | | O(n^2) | O(n) | ## Tags # Binary Watch Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/binary-watch Tested Python solution for LeetCode 401 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 401, [Easy](/catalog/easy). Topics: [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/binary-watch/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 401 # by problem number lcpy gen -s binary_watch # by problem name ``` ## Problem A binary watch has 4 LEDs on the top to represent the hours (0-11), and 6 LEDs on the bottom to represent the minutes (0-59). Each LED represents a zero or one, with the least significant bit on the right. For example, the below binary watch reads `"4:51"`. Given an integer `turnedOn` which represents the number of LEDs that are currently on (ignoring the PM), return *all possible times the watch could represent*. You may return the answer in **any order**. The hour must not contain a leading zero. * For example, `"01:00"` is not valid. It should be `"1:00"`. The minute must consist of two digits and may contain a leading zero. * For example, `"10:2"` is not valid. It should be `"10:02"`. ### Examples  ``` Input: turnedOn = 1 Output: ["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"] ``` ``` Input: turnedOn = 9 Output: [] ``` ### Constraints * 0 \<= turnedOn \<= 10 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_watch/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/binary_watch/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(12 * 60) # Space: O(1) excluding the output def read_binary_watch(self, turned_on: int) -> list[str]: if turned_on > 9: return [] result: list[str] = [] for hour in range(12): for minute in range(60): if hour.bit_count() + minute.bit_count() == turned_on: result.append(f"{hour}:{minute:02d}") return result ``` ## Complexity | Time | Space | | ----------- | ------------------------- | | O(12 \* 60) | O(1) excluding the output | ## Tags # Bitwise AND of Numbers Range Python Solution Source: https://leetcode-py.wisl.dev/problems/bitwise-and-of-numbers-range Tested Python solution for LeetCode 201 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 201, [Medium](/catalog/medium). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/bitwise-and-of-numbers-range/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 201 # by problem number lcpy gen -s bitwise_and_of_numbers_range # by problem name ``` ## Problem Given two integers `left` and `right` that represent the range `[left, right]`, return *the bitwise AND of all numbers in this range, inclusive*. ### Examples ``` Input: left = 5, right = 7 Output: 4 ``` ``` Input: left = 0, right = 0 Output: 0 ``` ``` Input: left = 1, right = 2147483647 Output: 0 ``` ### Constraints * 0 \<= left \<= right \<= 2^31 - 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bitwise_and_of_numbers_range/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bitwise_and_of_numbers_range/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log n) where n is the value of right (number of bits) # Space: O(1) def range_bitwise_and(self, left: int, right: int) -> int: # The AND of the range equals the common most-significant bit prefix shift = 0 while left < right: left >>= 1 right >>= 1 shift += 1 return left << shift ``` ## Complexity | Time | Space | | ------------------------------------------------------- | ----- | | O(log n) where n is the value of right (number of bits) | O(1) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Bitwise ORs of Subarrays Python Solution Source: https://leetcode-py.wisl.dev/problems/bitwise-ors-of-subarrays Tested Python solution for LeetCode 898 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 898, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/bitwise-ors-of-subarrays/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 898 # by problem number lcpy gen -s bitwise_ors_of_subarrays # by problem name ``` ## Problem Given an integer array `arr`, return *the number of distinct bitwise ORs of all the non-empty subarrays of* `arr`. The bitwise OR of a subarray is the bitwise OR of each integer in the subarray. The bitwise OR of a subarray of one integer is that integer. A **subarray** is a contiguous non-empty sequence of elements within an array. ### Examples ``` Input: arr = [0] Output: 1 Explanation: There is only one possible result: 0. ``` ``` Input: arr = [1,1,2] Output: 3 Explanation: The possible subarrays are [1], [1], [2], [1, 1], [1, 2], [1, 1, 2]. These yield the results 1, 1, 2, 1, 3, 3. There are 3 unique values, so the answer is 3. ``` ``` Input: arr = [1,2,4] Output: 6 Explanation: The possible results are 1, 2, 3, 4, 6, and 7. ``` ### Constraints * `1 <= arr.length <= 5 * 10^4` * `0 <= arr[i] <= 10^9` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bitwise_ors_of_subarrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bitwise_ors_of_subarrays/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n * 30) - each OR set only holds distinct prefix-OR values, at most 30 bits # Space: O(30 * n) worst case across the rolling and global sets def subarray_bitwise_ors(self, arr: list[int]) -> int: seen: set[int] = set() current: set[int] = set() for num in arr: current = {num | prev for prev in current} | {num} seen |= current return len(seen) ``` ## Complexity | Time | Space | | ------------------------------------------------------------------------------ | -------------------------------------------------------- | | O(n \* 30) - each OR set only holds distinct prefix-OR values, at most 30 bits | O(30 \* n) worst case across the rolling and global sets | ## Tags # Bitwise XOR of All Pairings Python Solution Source: https://leetcode-py.wisl.dev/problems/bitwise-xor-of-all-pairings Tested Python solution for LeetCode 2425 with 21 pytest cases. Generate a practice environment with lcpy. LeetCode 2425, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), Brainteaser. [View on LeetCode](https://leetcode.com/problems/bitwise-xor-of-all-pairings/description/). Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2425 # by problem number lcpy gen -s bitwise_xor_of_all_pairings # by problem name ``` ## Problem You are given two **0-indexed** arrays, `nums1` and `nums2`, consisting of non-negative integers. Let there be another array, `nums3`, which contains the bitwise XOR of **all pairings** of integers between `nums1` and `nums2` (every integer in `nums1` is paired with every integer in `nums2` **exactly once**). Return the bitwise XOR of all integers in `nums3`. ### Examples ``` Input: nums1 = [2,1,3], nums2 = [10,2,5,0] Output: 13 Explanation: A possible nums3 array is [8,0,7,2,11,3,4,1,9,1,6,3]. The bitwise XOR of all these numbers is 13, so we return 13. ``` ``` Input: nums1 = [1,2], nums2 = [3,4] Output: 0 Explanation: All possible pairs of bitwise XORs are nums1[0] ^ nums2[0], nums1[0] ^ nums2[1], nums1[1] ^ nums2[0], and nums1[1] ^ nums2[1]. Thus, one possible nums3 array is [2,5,1,6]. 2 ^ 5 ^ 1 ^ 6 = 0, so we return 0. ``` ### Constraints * 1 \<= nums1.length, nums2.length \<= 10^5 * 0 \<= nums1\[i], nums2\[j] \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bitwise_xor_of_all_pairings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bitwise_xor_of_all_pairings/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n + m) # Space: O(1) def xor_all_nums(self, nums1: list[int], nums2: list[int]) -> int: # Each nums1[i] appears in len(nums2) pairings, each nums2[j] in len(nums1); # a value XORed an even number of times cancels out. result = 0 if len(nums2) % 2: for num in nums1: result ^= num if len(nums1) % 2: for num in nums2: result ^= num return result ``` ## Complexity | Time | Space | | -------- | ----- | | O(n + m) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Boats to Save People Python Solution Source: https://leetcode-py.wisl.dev/problems/boats-to-save-people Tested Python solution for LeetCode 881 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 881, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/boats-to-save-people/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 881 # by problem number lcpy gen -s boats_to_save_people # by problem name ``` ## Problem You are given an array `people` where `people[i]` is the weight of the `i^th` person, and an **infinite number of boats** where each boat can carry a maximum weight of `limit`. Each boat carries at most two people at the same time, provided the sum of the weight of those people is at most `limit`. Return *the minimum number of boats to carry every given person*. ### Examples ``` Input: people = [1,2], limit = 3 Output: 1 Explanation: 1 boat (1, 2) ``` ``` Input: people = [3,2,2,1], limit = 3 Output: 3 Explanation: 3 boats (1, 2), (2) and (3) ``` ``` Input: people = [3,5,3,4], limit = 5 Output: 4 Explanation: 4 boats (3), (3), (4), (5) ``` ### Constraints * 1 \<= people.length \<= 5 \* 10^4 * 1 \<= people\[i] \<= limit \<= 3 \* 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/boats_to_save_people/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/boats_to_save_people/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) for sorting def num_rescue_boats(self, people: list[int], limit: int) -> int: people.sort() boats = 0 left, right = 0, len(people) - 1 while left <= right: if people[left] + people[right] <= limit: left += 1 right -= 1 boats += 1 return boats ``` ## Complexity | Time | Space | | ---------- | ---------------- | | O(n log n) | O(n) for sorting | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Bold Words in String Python Solution Source: https://leetcode-py.wisl.dev/problems/bold-words-in-string Tested Python solution for LeetCode 758 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 758, [Medium](/catalog/medium). Topics: [Trie](/catalog/topics/trie), [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching). [View on LeetCode](https://leetcode.com/problems/bold-words-in-string/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 758 # by problem number lcpy gen -s bold_words_in_string # by problem name ``` ## Problem Given an array of keywords `words` and a string `s`, make all appearances of all keywords `words[i]` in `s` bold. Any letters between `` and `` tags become bold. Return `s` *after adding the bold tags*. The returned string should use the least number of tags possible, and the tags should form a valid combination. ### Examples ``` Input: words = ["ab","bc"], s = "aabcd" Output: "aabcd" Explanation: Note that returning "aabcd" would use more tags, so it is incorrect. ``` ``` Input: words = ["ab","cb"], s = "aabcd" Output: "aabcd" ``` ### Constraints * `1 <= s.length <= 500` * `0 <= words.length <= 50` * `1 <= words[i].length <= 10` * `s` and `words[i]` consist of lowercase English letters. **Note:** This question is the same as [616: Add Bold Tag in String](https://leetcode.com/problems/add-bold-tag-in-string/description/). ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bold_words_in_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bold_words_in_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Trie: def __init__(self) -> None: self.children: dict[str, Trie] = {} self.is_end = False def insert(self, word: str) -> None: node = self for ch in word: if ch not in node.children: node.children[ch] = Trie() node = node.children[ch] node.is_end = True class Solution: # Time: O(total keyword chars + n * max keyword length + n) # Space: O(total keyword chars + n) def bold_words(self, words: list[str], s: str) -> str: trie = Trie() for word in words: trie.insert(word) n = len(s) intervals: list[list[int]] = [] for i in range(n): node = trie for j in range(i, n): nxt = node.children.get(s[j]) if nxt is None: break node = nxt if node.is_end: if intervals and intervals[-1][1] + 1 >= i: intervals[-1][1] = max(intervals[-1][1], j) else: intervals.append([i, j]) parts: list[str] = [] prev = 0 for start, end in intervals: parts.append(s[prev:start]) parts.append("") parts.append(s[start : end + 1]) parts.append("") prev = end + 1 parts.append(s[prev:]) return "".join(parts) ``` ## Complexity | Time | Space | | ---------------------------------------------------- | -------------------------- | | O(total keyword chars + n \* max keyword length + n) | O(total keyword chars + n) | ## Tags # Bomb Enemy Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/bomb-enemy Tested Python solution for LeetCode 361 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 361, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/bomb-enemy/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 361 # by problem number lcpy gen -s bomb_enemy # by problem name ``` ## Problem Given an `m x n` matrix `grid` where each cell is either a wall `'W'`, an enemy `'E'` or empty `'0'`, return *the maximum enemies you can kill using one bomb*. You can only place the bomb in an empty cell. The bomb kills all the enemies in the same row and column from the planted point until it hits the wall since it is too strong to be destroyed. ### Examples  ``` Input: grid = [["0","E","0","0"],["E","0","W","E"],["0","E","0","0"]] Output: 3 ```  ``` Input: grid = [["W","W","W"],["0","0","0"],["E","E","E"]] Output: 1 ``` ### Constraints * `m == grid.length` * `n == grid[i].length` * `1 <= m, n <= 500` * `grid[i][j]` is either `'W'`, `'E'`, or `'0'`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bomb_enemy/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bomb_enemy/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(n) def max_killed_enemies(self, grid: list[list[str]]) -> int: if not grid or not grid[0]: return 0 m, n = len(grid), len(grid[0]) result = 0 row_hits = 0 col_hits = [0] * n for i in range(m): for j in range(n): if j == 0 or grid[i][j - 1] == "W": row_hits = 0 k = j while k < n and grid[i][k] != "W": row_hits += grid[i][k] == "E" k += 1 if i == 0 or grid[i - 1][j] == "W": col_hits[j] = 0 k = i while k < m and grid[k][j] != "W": col_hits[j] += grid[k][j] == "E" k += 1 if grid[i][j] == "0": result = max(result, row_hits + col_hits[j]) return result ``` ## Complexity | Time | Space | | --------- | ----- | | O(m \* n) | O(n) | ## Tags # Boundary of Binary Tree Python Solution Source: https://leetcode-py.wisl.dev/problems/boundary-of-binary-tree Tested Python solution for LeetCode 545 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 545, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/boundary-of-binary-tree/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 545 # by problem number lcpy gen -s boundary_of_binary_tree # by problem name ``` ## Problem The **boundary** of a binary tree is the concatenation of the **root**, the **left boundary**, the **leaves** ordered from left-to-right, and the **reverse order** of the **right boundary**. The **left boundary** is the set of nodes defined by the following: * The root node's left child is in the left boundary. If the root does not have a left child, then the left boundary is **empty**. * If a node is in the left boundary and has a left child, then the left child is in the left boundary. * If a node is in the left boundary, has **no** left child, but has a right child, then the right child is in the left boundary. * The leftmost leaf is **not** in the left boundary. The **right boundary** is similar to the left boundary, except it is the right side of the root's right subtree. Again, the leaf is **not** part of the **right boundary**, and the **right boundary** is empty if the root does not have a right child. The **leaves** are nodes that do not have any children. For this problem, the root is **not** a leaf. Given the `root` of a binary tree, return the values of its **boundary**. ### Examples  ``` Input: root = [1,null,2,3,4] Output: [1,3,4,2] Explanation: - The left boundary is empty because the root does not have a left child. - The right boundary follows the path starting from the root's right child 2 -> 4. 4 is a leaf, so the right boundary is [2]. - The leaves from left to right are [3,4]. Concatenating everything results in [1] + [] + [3,4] + [2] = [1,3,4,2]. ```  ``` Input: root = [1,2,3,4,5,6,null,null,null,7,8,9,10] Output: [1,2,4,7,8,9,10,6,3] Explanation: - The left boundary follows the path starting from the root's left child 2 -> 4. 4 is a leaf, so the left boundary is [2]. - The right boundary follows the path down the rightmost path 3 -> 6 -> 10. 10 is a leaf, so the right boundary is [3,6]. - The leaves from left to right are [4,7,8,9,10]. Concatenating everything results in [1] + [2] + [4,7,8,9,10] + [6,3] = [1,2,4,7,8,9,10,6,3]. ``` ### Constraints * The number of nodes in the tree is in the range `[1, 10^4]`. * `-1000 <= Node.val <= 1000` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/boundary_of_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/boundary_of_binary_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(n) def boundary_of_binary_tree(self, root: TreeNode[int] | None) -> list[int]: if root is None: return [] def is_leaf(node: TreeNode[int] | None) -> bool: return node is not None and node.left is None and node.right is None vals = [root.val] cur = root.left while cur is not None and not is_leaf(cur): vals.append(cur.val) cur = cur.left if cur.left is not None else cur.right leaves: list[int] = [] stack = [root] while stack: node = stack.pop() if is_leaf(node) and node is not root: leaves.append(node.val) if node.right is not None: stack.append(node.right) if node.left is not None: stack.append(node.left) vals.extend(leaves) right: list[int] = [] cur = root.right while cur is not None and not is_leaf(cur): right.append(cur.val) cur = cur.right if cur.right is not None else cur.left vals.extend(reversed(right)) return vals ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Brace Expansion Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/brace-expansion Tested Python solution for LeetCode 1087 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 1087, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/brace-expansion/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1087 # by problem number lcpy gen -s brace_expansion # by problem name ``` ## Problem You are given a string `s` representing a list of words. Each letter in the word has one or more options. * If there is one option, the letter is represented as is. * If there is more than one option, then curly braces delimit the options. For example, `"{a,b,c}"` represents options `["a", "b", "c"]`. For example, if `s = "a{b,c}"`, the first character is always `'a'`, but the second character can be `'b'` or `'c'`. The original list is `["ab", "ac"]`. Return all words that can be formed in this manner, sorted in **lexicographical order**. ### Examples ``` Input: s = "{a,b}c{d,e}f" Output: ["acdf","acef","bcdf","bcef"] ``` ``` Input: s = "abcd" Output: ["abcd"] ``` ### Constraints * 1 \<= s.length \<= 50 * s consists of curly brackets '\{}', commas ',', and lowercase English letters. * s is guaranteed to be a valid input. * There are no nested curly brackets. * All characters inside a pair of consecutive opening and ending curly brackets are different. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/brace_expansion/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/brace_expansion/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from itertools import product class Solution: # Time: O(n * k) expansions where k is average option count # Space: O(result) def expand(self, s: str) -> list[str]: blocks: list[list[str]] = [] i = 0 while i < len(s): if s[i] == "{": j = s.index("}", i) blocks.append(sorted(s[i + 1 : j].split(","))) i = j + 1 else: j = s.find("{", i) if j == -1: blocks.append([s[i:]]) i = len(s) else: blocks.append([s[i:j]]) i = j return sorted("".join(word) for word in product(*blocks)) ``` ## Complexity | Time | Space | | ---------------------------------------------------- | --------- | | O(n \* k) expansions where k is average option count | O(result) | ## Tags [NeetCode All](/catalog/neetcode). # Brick Wall Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/brick-wall Tested Python solution for LeetCode 554 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 554, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/brick-wall/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 554 # by problem number lcpy gen -s brick_wall # by problem name ``` ## Problem There is a rectangular brick wall in front of you with `n` rows of bricks. The i\th\ row has some number of bricks each of the same height (i.e., one unit) but they can be of different widths. The total width of each row is the same. Draw a vertical line from the top to the bottom and cross the least bricks. If your line goes through the edge of a brick, then the brick is not considered as crossed. You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks. Given the 2D integer array `wall` that contains the information about the wall, return *the minimum number of crossed bricks after drawing such a vertical line*. ### Examples  ``` Input: wall = [[1,2,2,1],[3,1,2],[1,3,2],[2,4],[3,1,2],[1,3,1,1]] Output: 2 ``` ``` Input: wall = [[1],[1],[1]] Output: 3 ``` ### Constraints * n == wall.length * 1 \<= n \<= 10^4 * 1 \<= wall\[i].length \<= 10^4 * 1 \<= sum(wall\[i].length) \<= 2 \* 10^4 * sum(wall\[i]) is the same for each row i. * 1 \<= wall\[i]\[j] \<= 2^31 - 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/brick_wall/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/brick_wall/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n * m) where m is the max bricks per row # Space: O(n * m) def least_bricks(self, wall: list[list[int]]) -> int: edge_counts: Counter[int] = Counter() for row in wall: position = 0 for width in row[:-1]: position += width edge_counts[position] += 1 crossings = max(edge_counts.values(), default=0) return len(wall) - crossings ``` ## Complexity | Time | Space | | ------------------------------------------- | --------- | | O(n \* m) where m is the max bricks per row | O(n \* m) | ## Tags [NeetCode All](/catalog/neetcode). # Bricks Falling When Hit Python Solution Source: https://leetcode-py.wisl.dev/problems/bricks-falling-when-hit Tested Python solution for LeetCode 803 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 803, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Union-Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/bricks-falling-when-hit/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 803 # by problem number lcpy gen -s bricks_falling_when_hit # by problem name ``` ## Problem You are given an `m x n` binary grid, where each `1` represents a brick and `0` represents an empty space. A brick is **stable** if: * It is directly connected to the top of the grid, or * At least one other brick in its four adjacent cells is **stable**. You are also given an array `hits`, which is a sequence of erasures we want to apply. Each time we want to erase the brick at the location `hits[i] = (rowi, coli)`. The brick on that location (if it exists) will disappear. Some other bricks may no longer be stable because of that erasure and will **fall**. Once a brick falls, it is immediately erased from the grid (i.e., it does not land on other stable bricks). Return an array `result`, where each `result[i]` is the number of bricks that will fall after the `ith` erasure is applied. **Note** that an erasure may refer to a location with no brick, and if it does, no bricks drop. ### Examples ``` Input: grid = [[1,0,0,0],[1,1,1,0]], hits = [[1,0]] Output: [2] Explanation: Starting with the grid: [[1,0,0,0], [1,1,1,0]] We erase the brick at (1,0), resulting in the grid: [[1,0,0,0], [0,1,1,0]] The two bricks are no longer stable as they are no longer connected to the top nor adjacent to another stable brick, so they will fall. The resulting grid is: [[1,0,0,0], [0,0,0,0]] Hence the result is [2]. ``` ``` Input: grid = [[1,0,0,0],[1,1,0,0]], hits = [[1,1],[1,0]] Output: [0,0] Explanation: Starting with the grid: [[1,0,0,0], [1,1,0,0]] We erase the brick at (1,1), resulting in the grid: [[1,0,0,0], [1,0,0,0]] All remaining bricks are still stable, so no bricks fall. Next, we erase the brick at (1,0), resulting in the grid: [[1,0,0,0], [0,0,0,0]] Once again, all remaining bricks are still stable, so no bricks fall. Hence the result is [0,0]. ``` ### Constraints * `m == grid.length` * `n == grid[i].length` * `1 <= m, n <= 200` * `grid[i][j]` is `0` or `1`. * `1 <= hits.length <= 4 * 10^4` * `hits[i].length == 2` * `0 <= x_i <= m - 1` * `0 <= y_i <= n - 1` * All `(x_i, y_i)` are unique. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bricks_falling_when_hit/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bricks_falling_when_hit/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(rows * cols + len(hits) * alpha(rows * cols)) # Space: O(rows * cols) def hit_bricks(self, grid: list[list[int]], hits: list[list[int]]) -> list[int]: rows, cols = len(grid), len(grid[0]) # Work on a grid with every hit brick already erased, then re-add them in # reverse: erasures are hard to undo, additions are just unions. remaining = [row[:] for row in grid] for row, col in hits: remaining[row][col] = 0 top = rows * cols parent = list(range(top + 1)) size = [1] * (top + 1) def find(node: int) -> int: while parent[node] != node: parent[node] = parent[parent[node]] node = parent[node] return node def union(left: int, right: int) -> None: root_left, root_right = find(left), find(right) if root_left == root_right: return if size[root_left] < size[root_right]: root_left, root_right = root_right, root_left parent[root_right] = root_left size[root_left] += size[root_right] def stable_bricks() -> int: # Bricks attached to the virtual top node (the node itself adds 1). return size[find(top)] - 1 def add_brick(row: int, col: int) -> None: node = row * cols + col if row == 0: union(node, top) for d_row, d_col in ((1, 0), (-1, 0), (0, 1), (0, -1)): n_row, n_col = row + d_row, col + d_col if 0 <= n_row < rows and 0 <= n_col < cols and remaining[n_row][n_col]: union(node, n_row * cols + n_col) for row in range(rows): for col in range(cols): if remaining[row][col]: add_brick(row, col) results: list[int] = [] for row, col in reversed(hits): if grid[row][col] == 0: results.append(0) # erasure on an empty cell, nothing drops continue before = stable_bricks() add_brick(row, col) remaining[row][col] = 1 after = stable_bricks() # Re-adding the hit brick itself accounts for one of the newcomers. results.append(max(0, after - before - 1)) results.reverse() return results ``` ## Complexity | Time | Space | | -------------------------------------------------- | --------------- | | O(rows \* cols + len(hits) \* alpha(rows \* cols)) | O(rows \* cols) | ## Tags # Brightest Position on Street Python Solution Source: https://leetcode-py.wisl.dev/problems/brightest-position-on-street Tested Python solution for LeetCode 2021 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 2021, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Ordered Set](/catalog/topics/ordered-set), [Prefix Sum](/catalog/topics/prefix-sum), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/brightest-position-on-street/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2021 # by problem number lcpy gen -s brightest_position_on_street # by problem name ``` ## Problem A perfectly straight street is represented by a number line. The street has `street lamp(s)` on it and is represented by a 2D integer array `lights`. Each `lights[i] = [position_i, range_i]` indicates that there is a street lamp at position `position_i` that lights up the area from `[position_i - range_i, position_i + range_i]` (**inclusive**). The **brightness** of a position `p` is defined as the number of street lamps that light up the position `p`. Given `lights`, return *the **brightest** position on the street*. If there are multiple brightest positions, return the **smallest** one. ### Examples  ``` Input: lights = [[-3,2],[1,2],[3,3]] Output: -1 Explanation: The first street lamp lights up the area from [(-3) - 2, (-3) + 2] = [-5, -1]. The second street lamp lights up the area from [1 - 2, 1 + 2] = [-1, 3]. The third street lamp lights up the area from [3 - 3, 3 + 3] = [0, 6]. Position -1 has a brightness of 2, illuminated by the first and second street light. Positions 0, 1, 2, and 3 have a brightness of 2, illuminated by the second and third street light. Out of all these positions, -1 is the smallest, so return it. ``` ``` Input: lights = [[1,0],[0,1]] Output: 1 Explanation: The first street lamp lights up the area from [1 - 0, 1 + 0] = [1, 1]. The second street lamp lights up the area from [0 - 1, 0 + 1] = [-1, 1]. Position 1 has a brightness of 2, illuminated by the first and second street light. Return 1 because it is the brightest position on the street. ``` ``` Input: lights = [[1,2]] Output: -1 Explanation: The first street lamp lights up the area from [1 - 2, 1 + 2] = [-1, 3]. Positions -1, 0, 1, 2, and 3 have a brightness of 1, illuminated by the first street light. Out of all these positions, -1 is the smallest, so return it. ``` ### Constraints * 1 \<= lights.length \<= 10^5 * lights\[i].length == 2 * -10^8 \<= position\_i \<= 10^8 * 0 \<= range\_i \<= 10^8 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/brightest_position_on_street/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/brightest_position_on_street/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) def brightest_position(self, lights: list[list[int]]) -> int: diff: dict[int, int] = {} for pos, rng in lights: diff[pos - rng] = diff.get(pos - rng, 0) + 1 diff[pos + rng + 1] = diff.get(pos + rng + 1, 0) - 1 best = 0 brightness = 0 best_pos = 0 for point in sorted(diff): brightness += diff[point] if brightness > best: best = brightness best_pos = point return best_pos ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Broken Calculator Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/broken-calculator Tested Python solution for LeetCode 991 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 991, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/broken-calculator/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 991 # by problem number lcpy gen -s broken_calculator # by problem name ``` ## Problem There is a broken calculator that has the integer `startValue` on its display initially. In one operation, you can: * multiply the number on display by `2`, or * subtract `1` from the number on display. Given two integers `startValue` and `target`, return the minimum number of operations needed to display `target` on the calculator. ### Examples ``` Input: startValue = 2, target = 3 Output: 2 Explanation: Use double operation and then decrement operation {2 -> 4 -> 3}. ``` ``` Input: startValue = 5, target = 8 Output: 2 Explanation: Use decrement and then double {5 -> 4 -> 8}. ``` ``` Input: startValue = 3, target = 10 Output: 3 Explanation: Use double, decrement and double {3 -> 6 -> 5 -> 10}. ``` ### Constraints * 1 \<= startValue, target \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/broken_calculator/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/broken_calculator/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log(target)) # Space: O(1) def broken_calc(self, start_value: int, target: int) -> int: ops = 0 while target > start_value: if target % 2: target += 1 else: target //= 2 ops += 1 return ops + start_value - target ``` ## Complexity | Time | Space | | -------------- | ----- | | O(log(target)) | O(1) | ## Tags # Buddy Strings Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/buddy-strings Tested Python solution for LeetCode 859 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 859, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/buddy-strings/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 859 # by problem number lcpy gen -s buddy_strings # by problem name ``` ## Problem Given two strings `s` and `goal`, return `true` if you can swap two letters in `s` so the result is equal to `goal`, otherwise, return `false`. Swapping letters is defined as taking two indices `i` and `j` (0-indexed) such that `i != j` and swapping the characters at `s[i]` and `s[j]`. * For example, swapping at indices `0` and `2` in `"abcd"` results in `"cbad"`. ### Examples ``` Input: s = "ab", goal = "ba" Output: true Explanation: You can swap s[0] = 'a' and s[1] = 'b' to get "ba", which is equal to goal. ``` ``` Input: s = "ab", goal = "ab" Output: false Explanation: The only letters you can swap are s[0] = 'a' and s[1] = 'b', which results in "ba" != goal. ``` ``` Input: s = "aa", goal = "aa" Output: true Explanation: You can swap s[0] = 'a' and s[1] = 'a' to get "aa", which is equal to goal. ``` ### Constraints * 1 \<= s.length, goal.length \<= 2 \* 10^4 * s and goal consist of lowercase letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/buddy_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/buddy_strings/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def buddy_strings(self, s: str, goal: str) -> bool: if len(s) != len(goal): return False if s == goal: return len(set(s)) < len(s) diffs = [i for i, (a, b) in enumerate(zip(s, goal, strict=True)) if a != b] if len(diffs) != 2: return False i, j = diffs return s[i] == goal[j] and s[j] == goal[i] ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Build a Matrix With Conditions Python Solution Source: https://leetcode-py.wisl.dev/problems/build-a-matrix-with-conditions Tested Python solution for LeetCode 2392 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 2392, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/build-a-matrix-with-conditions/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2392 # by problem number lcpy gen -s build_a_matrix_with_conditions # by problem name ``` ## Problem You are given a **positive** integer `k`. You are also given: * a 2D integer array `rowConditions` of size `n` where `rowConditions[i] = [above_i, below_i]`, and * a 2D integer array `colConditions` of size `m` where `colConditions[i] = [left_i, right_i]`. The two arrays contain integers from `1` to `k`. You have to build a `k x k` matrix that contains each of the numbers from `1` to `k` **exactly once**. The remaining cells should have the value `0`. The matrix should also satisfy the following conditions: * The number `above_i` should appear in a **row** that is strictly **above** the row at which the number `below_i` appears for all `i` from `0` to `n - 1`. * The number `left_i` should appear in a **column** that is strictly **left** of the column at which the number `right_i` appears for all `i` from `0` to `m - 1`. Return ***any** matrix that satisfies the conditions*. If no answer exists, return an empty matrix. ### Examples  ``` Input: k = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]] Output: [[3,0,0],[0,0,1],[0,2,0]] Explanation: The diagram above shows a valid example of a matrix that satisfies all the conditions. The row conditions are the following: - Number 1 is in row 1, and number 2 is in row 2, so 1 is above 2 in the matrix. - Number 3 is in row 0, and number 2 is in row 2, so 3 is above 2 in the matrix. The column conditions are the following: - Number 2 is in column 1, and number 1 is in column 2, so 2 is left of 1 in the matrix. - Number 3 is in column 0, and number 2 is in column 1, so 3 is left of 2 in the matrix. Note that there may be multiple correct answers. ``` ``` Input: k = 3, rowConditions = [[1,2],[2,3],[3,1],[2,3]], colConditions = [[2,1]] Output: [] Explanation: From the first two conditions, 3 has to be below 1 but the third conditions needs 3 to be above 1 to be satisfied. No matrix can satisfy all the conditions, so we return the empty matrix. ``` ### Constraints * 2 \<= k \<= 400 * 1 \<= rowConditions.length, colConditions.length \<= 10^4 * rowConditions\[i].length == colConditions\[i].length == 2 * 1 \<= above\_i, below\_i, left\_i, right\_i \<= k * above\_i != below\_i * left\_i != right\_i ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/build_a_matrix_with_conditions/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/build_a_matrix_with_conditions/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import defaultdict, deque class Solution: # Time: O(k + n + m) # Space: O(k + n + m) def build_matrix( self, k: int, row_conditions: list[list[int]], col_conditions: list[list[int]] ) -> list[list[int]]: def topological_order(conditions: list[list[int]]) -> list[int]: graph: dict[int, list[int]] = defaultdict(list) indegree = [0] * (k + 1) for above, below in conditions: graph[above].append(below) indegree[below] += 1 queue = deque(node for node in range(1, k + 1) if indegree[node] == 0) order: list[int] = [] while queue: node = queue.popleft() order.append(node) for neighbor in graph[node]: indegree[neighbor] -= 1 if indegree[neighbor] == 0: queue.append(neighbor) return order if len(order) == k else [] row_order = topological_order(row_conditions) if not row_order: return [] col_order = topological_order(col_conditions) if not col_order: return [] column_index = {number: idx for idx, number in enumerate(col_order)} matrix = [[0] * k for _ in range(k)] for row, number in enumerate(row_order): matrix[row][column_index[number]] = number return matrix ``` ## Complexity | Time | Space | | ------------ | ------------ | | O(k + n + m) | O(k + n + m) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Buildings With an Ocean View Python Solution Source: https://leetcode-py.wisl.dev/problems/buildings-with-an-ocean-view Tested Python solution for LeetCode 1762 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 1762, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/buildings-with-an-ocean-view/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1762 # by problem number lcpy gen -s buildings_with_an_ocean_view # by problem name ``` ## Problem \There are \n\ buildings in a line. You are given an integer array \heights\ of size \n\ that represents the heights of the buildings in the line.\
The ocean is to the right of the buildings. A building has an ocean view if the building can see the ocean without obstructions. Formally, a building has an ocean view if all the buildings to its right have a \smaller\ height.\
\Return a list of indices \(0-indexed)\ of buildings that have an ocean view, sorted in increasing order.\
### Examples ``` Input: heights = [4,2,3,1] Output: [0,2,3] ``` **Explanation:** Building 1 (0-indexed) does not have an ocean view because building 2 is taller. ``` Input: heights = [4,3,2,1] Output: [0,1,2,3] ``` **Explanation:** All the buildings have an ocean view. ``` Input: heights = [1,3,2,4] Output: [3] ``` **Explanation:** Only building 3 has an ocean view. ### Constraints * 1 \<= heights.length \<= 10^5 * 1 \<= heights\[i] \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/buildings_with_an_ocean_view/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/buildings_with_an_ocean_view/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) excluding the output list def find_buildings(self, heights: list[int]) -> list[int]: result: list[int] = [] max_right = 0 for i in range(len(heights) - 1, -1, -1): if heights[i] > max_right: result.append(i) max_right = heights[i] return result[::-1] ``` ## Complexity | Time | Space | | ---- | ------------------------------ | | O(n) | O(1) excluding the output list | ## Tags [NeetCode All](/catalog/neetcode). # Bulb Switcher Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/bulb-switcher Tested Python solution for LeetCode 319 with 33 pytest cases. Generate a practice environment with lcpy. LeetCode 319, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), Brainteaser. [View on LeetCode](https://leetcode.com/problems/bulb-switcher/description/). Generate this problem as a practice environment: tested reference solution, 33 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 319 # by problem number lcpy gen -s bulb_switcher # by problem name ``` ## Problem \There are \n\ bulbs that are initially off. You first turn on all the bulbs, then you turn off every second bulb.\
On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the \i\th\\ round, you toggle every \i\ bulb. For the \n\th\\ round, you only toggle the last bulb.\
Return \the number of bulbs that are on after \n\ rounds\.\
fronts\ and \backs\ of length \n\, where the \i\th\\ card has the positive integer \fronts\[i]\ printed on the front and \backs\[i]\ printed on the back. Initially, each card is placed on a table such that the front number is facing up and the other is facing down. You may flip over any number of cards (possibly zero).
After flipping the cards, an integer is considered \good\ if it is facing down on some card and \not\ facing up on any card.
Return \the minimum possible good integer after flipping the cards\. If there are no good integers, return \0\.
### Examples
```
Input: fronts = [1,2,4,4,7], backs = [1,3,4,1,3]
Output: 2
Explanation:
If we flip the second card, the face up numbers are [1,3,4,4,7] and the face down are [1,2,4,1,3].
2 is the minimum good integer as it appears facing down but not facing up.
It can be shown that 2 is the minimum possible good integer obtainable after flipping some cards.
```
```
Input: fronts = [1], backs = [1]
Output: 0
Explanation:
There are no good integers no matter how we flip the cards, so we return 0.
```
### Constraints
* n == fronts.length == backs.length
* 1 \<= n \<= 1000
* 1 \<= fronts\[i], backs\[i] \<= 2000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/card_flipping_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/card_flipping_game/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def flipgame(self, fronts: list[int], backs: list[int]) -> int:
stuck = {f for f, b in zip(fronts, backs, strict=True) if f == b}
candidates = [x for x in fronts + backs if x not in stuck]
return min(candidates, default=0)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Cat and Mouse Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/cat-and-mouse
Tested Python solution for LeetCode 913 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 913, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), [Memoization](/catalog/topics/memoization), Minimax, [Game Theory](/catalog/topics/game-theory), Zero-Sum Game. [View on LeetCode](https://leetcode.com/problems/cat-and-mouse/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 913 # by problem number
lcpy gen -s cat_and_mouse # by problem name
```
## Problem
A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns.
The graph is given as follows: `graph[a]` is a list of all nodes `b` such that `ab` is an edge of the graph.
The mouse starts at node `1` and goes first, the cat starts at node `2` and goes second, and there is a hole at node `0`.
During each player's turn, they must travel along one edge of the graph that meets where they are. For example, if the Mouse is at node 1, it must travel to any node in `graph[1]`.
Additionally, it is not allowed for the Cat to travel to the Hole (node `0`).
Then, the game can end in three ways:
* If ever the Cat occupies the same node as the Mouse, the Cat wins.
* If ever the Mouse reaches the Hole, the Mouse wins.
* If ever a position is repeated (i.e., the players are in the same position as a previous turn, and it is the same player's turn to move), the game is a draw.
Given a `graph`, and assuming both players play optimally, return
* `1` if the mouse wins the game,
* `2` if the cat wins the game, or
* `0` if the game is a draw.
### Examples

```
Input: graph = [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
Output: 0
```

```
Input: graph = [[1,3],[0],[3],[0,2]]
Output: 1
```
### Constraints
* 3 \<= graph.length \<= 50
* 1 \<= graph\[i].length \< graph.length
* 0 \<= graph\[i]\[j] \< graph.length
* graph\[i]\[j] != i
* graph\[i] is unique.
* The mouse and the cat can always move.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cat_and_mouse/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cat_and_mouse/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n^3)
# Space: O(n^2)
def cat_mouse_game(self, graph: list[list[int]]) -> int:
n = len(graph)
draw, mouse_win, cat_win = 0, 1, 2
# color[m][c][t]: result of the state with the mouse on m, the cat on c and
# t picking the mover (0 mouse, 1 cat). Unresolved states stay draw.
color = [[[draw] * 2 for _ in range(n)] for _ in range(n)]
# degree[m][c][t]: how many of the mover's options are still undecided.
degree = [[[0] * 2 for _ in range(n)] for _ in range(n)]
for m in range(n):
for c in range(n):
degree[m][c][0] = len(graph[m])
degree[m][c][1] = len(graph[c]) - (0 in graph[c])
queue: deque[tuple[int, int, int]] = deque()
for node in range(n):
for turn in (0, 1):
if node and color[node][node][turn] == draw:
color[node][node][turn] = cat_win
queue.append((node, node, turn))
if color[0][node][turn] == draw:
color[0][node][turn] = mouse_win
queue.append((0, node, turn))
while queue:
m, c, turn = queue.popleft()
outcome = color[m][c][turn]
if turn == 0:
# A resolved mouse-to-move state was reached by the cat moving.
parents = [(m, prev_c, 1) for prev_c in graph[c] if prev_c != 0]
else:
# A resolved cat-to-move state was reached by the mouse moving.
parents = [(prev_m, c, 0) for prev_m in graph[m]]
for prev_m, prev_c, prev_turn in parents:
if color[prev_m][prev_c][prev_turn] != draw:
continue
if outcome == prev_turn + mouse_win:
# The mover can step into a state it already wins.
color[prev_m][prev_c][prev_turn] = outcome
queue.append((prev_m, prev_c, prev_turn))
else:
degree[prev_m][prev_c][prev_turn] -= 1
if degree[prev_m][prev_c][prev_turn] == 0:
# Every option loses, so the state is lost for the mover.
color[prev_m][prev_c][prev_turn] = outcome
queue.append((prev_m, prev_c, prev_turn))
return color[1][2][0]
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^3) | O(n^2) |
## Tags
# Chalkboard XOR Game Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/chalkboard-xor-game
Tested Python solution for LeetCode 810 with 32 pytest cases. Generate a practice environment with lcpy.
LeetCode 810, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation), Brainteaser, [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/chalkboard-xor-game/description/).
Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 810 # by problem number
lcpy gen -s chalkboard_xor_game # by problem name
```
## Problem
You are given an array of integers `nums` represents the numbers written on a chalkboard.
Alice and Bob take turns erasing exactly one number from the chalkboard, with Alice starting first. If erasing a number causes the bitwise XOR of all the elements of the chalkboard to become `0`, then that player loses. The bitwise XOR of one element is that element itself, and the bitwise XOR of no elements is `0`.
Also, if any player starts their turn with the bitwise XOR of all the elements of the chalkboard equal to `0`, then that player wins.
Return `true` if and only if Alice wins the game, assuming both players play optimally.
### Examples
```
Input: nums = [1,1,2]
Output: false
Explanation:
Alice has two choices: erase 1 or erase 2.
If she erases 1, the nums array becomes [1, 2]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 2 = 3. Now Bob can remove any element he wants, because Alice will be the one to erase the last element and she will lose.
If Alice erases 2 first, now nums become [1, 1]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 1 = 0. Alice will lose.
```
```
Input: nums = [0,1]
Output: true
```
```
Input: nums = [1,2,3]
Output: true
```
### Constraints
* 1 \<= nums.length \<= 1000
* 0 \<= nums\[i] \< 2^16
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/chalkboard_xor_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/chalkboard_xor_game/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import reduce
from operator import xor
class Solution:
# Time: O(n)
# Space: O(1)
def xor_game(self, nums: list[int]) -> bool:
# Alice loses only when the count is odd and the total XOR is nonzero:
# with an even count she can always mirror Bob's erasures (two copies of
# every value would XOR to 0), and a zero XOR wins on the spot.
return len(nums) % 2 == 0 or reduce(xor, nums, 0) == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Champagne Tower Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/champagne-tower
Tested Python solution for LeetCode 799 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 799, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/champagne-tower/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 799 # by problem number
lcpy gen -s champagne_tower # by problem name
```
## Problem
We stack glasses in a pyramid, where the first row has `1` glass, the second row has `2` glasses, and so on until the 100th row. Each glass holds one cup of champagne.
Then, some champagne is poured into the first glass at the top. When the topmost glass is full, any excess liquid poured will fall equally to the glass immediately to the left and right of it. When those glasses become full, any excess champagne will fall equally to the left and right of those glasses, and so on. (A glass at the bottom row has its excess champagne fall on the floor.)
For example, after one cup of champagne is poured, the top most glass is full. After two cups of champagne are poured, the two glasses on the second row are half full. After three cups of champagne are poured, those two cups become full - there are 3 full glasses total now. After four cups of champagne are poured, the third row has the middle glass half full, and the two outside glasses are a quarter full, as pictured below.

Now after pouring some non-negative integer cups of champagne, return how full the `jth` glass in the `ith` row is (both `i` and `j` are 0-indexed.)
### Examples
```
Input: poured = 1, query_row = 1, query_glass = 1
Output: 0.00000
Explanation: We poured 1 cup of champange to the top glass of the tower (which is indexed as (0, 0)). There will be no excess liquid so all the glasses under the top glass will remain empty.
```
```
Input: poured = 2, query_row = 1, query_glass = 1
Output: 0.50000
Explanation: We poured 2 cups of champange to the top glass of the tower (which is indexed as (0, 0)). There is one cup of excess liquid. The glass indexed as (1, 0) and the glass indexed as (1, 1) will share the excess liquid equally, and each will get half cup of champange.
```
```
Input: poured = 100000009, query_row = 33, query_glass = 17
Output: 1.00000
```
### Constraints
* 0 \<= poured \<= 10^9
* 0 \<= query\_glass \<= query\_row \< 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/champagne_tower/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/champagne_tower/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(query_row^2)
# Space: O(query_row)
def champagne_tower(self, poured: int, query_row: int, query_glass: int) -> float:
row = [float(poured)]
for _ in range(query_row):
nxt = [0.0] * (len(row) + 1)
for i, amount in enumerate(row):
excess = max(0.0, amount - 1.0) / 2.0
nxt[i] += excess
nxt[i + 1] += excess
row = nxt
return min(1.0, row[query_glass])
```
## Complexity
| Time | Space |
| --------------- | ------------- |
| O(query\_row^2) | O(query\_row) |
## Tags
[NeetCode All](/catalog/neetcode).
# Cheapest Flights Within K Stops
Source: https://leetcode-py.wisl.dev/problems/cheapest-flights-within-k-stops
Tested Python solution for LeetCode 787 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 787, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Shortest Path](/catalog/topics/shortest-path). [View on LeetCode](https://leetcode.com/problems/cheapest-flights-within-k-stops/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 787 # by problem number
lcpy gen -s cheapest_flights_within_k_stops # by problem name
```
## Problem
There are `n` cities connected by some number of flights. You are given an array `flights` where `flights[i] = [fromi, toi, pricei]` indicates that there is a flight from city `fromi` to city `toi` with cost `pricei`.
You are also given three integers `src`, `dst`, and `k`, return **the cheapest price** from `src` to `dst` with at most `k` stops. If there is no such route, return `-1`.
### Examples

```
Input: n = 4, flights = [[0,1,100],[1,2,100],[2,0,100],[1,3,600],[2,3,200]], src = 0, dst = 3, k = 1
Output: 700
Explanation:
The graph is shown above.
The optimal path with at most 1 stop from city 0 to 3 is marked in red and has cost 100 + 600 = 700.
Note that the path through cities [0,1,2,3] is cheaper but is invalid because it uses 2 stops.
```

```
Input: n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, k = 1
Output: 200
Explanation:
The graph is shown above.
The optimal path with at most 1 stop from city 0 to 2 is marked in red and has cost 100 + 100 = 200.
```

```
Input: n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, k = 0
Output: 500
Explanation:
The graph is shown above.
The optimal path with no stops from city 0 to 2 is marked in red and has cost 500.
```
### Constraints
* 2 \<= n \<= 100
* 0 \<= flights.length \<= (n \* (n - 1) / 2)
* flights\[i].length == 3
* 0 \<= fromi, toi \< n
* fromi != toi
* 1 \<= pricei \<= 10^4
* There will not be any multiple flights between two cities.
* 0 \<= src, dst, k \< n
* src != dst
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cheapest_flights_within_k_stops/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cheapest_flights_within_k_stops/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(K * E) where E is number of flights
# Space: O(V) where V is number of cities
def find_cheapest_price(
self, n: int, flights: list[list[int]], src: int, dst: int, k: int
) -> int:
# Build adjacency list
adj = [[] for _ in range(n)]
for from_i, to_i, price_i in flights:
adj[from_i].append((to_i, price_i))
# BFS with stops constraint
prices = [float("inf")] * n
prices[src] = 0
queue = deque([(src, 0, 0)]) # (node, current_price, stops)
while queue:
node, current_price, stops = queue.popleft()
if stops > k:
continue
for neighbor, price in adj[node]:
new_price = current_price + price
if new_price < prices[neighbor]:
prices[neighbor] = new_price
queue.append((neighbor, new_price, stops + 1))
return int(prices[dst]) if prices[dst] != float("inf") else -1
```
## Complexity
| Time | Space |
| -------------------------------------- | -------------------------------- |
| O(K \* E) where E is number of flights | O(V) where V is number of cities |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Check Completeness of a Binary Tree
Source: https://leetcode-py.wisl.dev/problems/check-completeness-of-a-binary-tree
Tested Python solution for LeetCode 958 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 958, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/check-completeness-of-a-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 958 # by problem number
lcpy gen -s check_completeness_of_a_binary_tree # by problem name
```
## Problem
\Given the \root\ of a binary tree, determine if it is a \complete binary tree\.\
In a \\complete binary tree\\, every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between \1\ and \2\h\\ nodes inclusive at the last level \h\.\
n\ representing the dimensions of an \n x n\ grid, with the origin at the bottom-left corner of the grid. You are also given a 2D array of coordinates \rectangles\, where \rectangles\[i]\ is in the form \\[start\x\, start\y\, end\x\, end\y\]\, representing a rectangle on the grid. Each rectangle is defined as follows:
* \(start\x\, start\y\)\: The bottom-left corner of the rectangle.
* \(end\x\, end\y\)\: The top-right corner of the rectangle.
\Note \that the rectangles do not overlap. Your task is to determine if it is possible to make \either two horizontal or two vertical cuts\ on the grid such that:
* Each of the three resulting sections formed by the cuts contains \at least\ one rectangle.
* Every rectangle belongs to \exactly\ one section.
Return \true\ if such cuts can be made; otherwise, return \false\.
### Examples

```
Input: n = 5, rectangles = [[1,0,5,2],[0,2,2,4],[3,2,5,3],[0,4,4,5]]
Output: true
```
**Explanation:** The grid is shown in the diagram. We can make horizontal cuts at \y = 2\ and \y = 4\. Hence, the output is true.

```
Input: n = 4, rectangles = [[0,0,1,1],[2,0,3,4],[0,2,2,3],[3,0,4,3]]
Output: true
```
**Explanation:** We can make vertical cuts at \x = 2\ and \x = 3\. Hence, the output is true.
```
Input: n = 4, rectangles = [[0,2,2,4],[1,0,3,2],[2,2,3,4],[3,0,4,2],[3,2,4,4]]
Output: false
```
**Explanation:** We cannot make two horizontal or two vertical cuts that satisfy the conditions. Hence, the output is false.
### Constraints
* 3 \<= n \<= 10^9
* 3 \<= rectangles.length \<= 10^5
* 0 \<= rectangles\[i]\[0] \< rectangles\[i]\[2] \<= n
* 0 \<= rectangles\[i]\[1] \< rectangles\[i]\[3] \<= n
* No two rectangles overlap.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_grid_can_be_cut_into_sections/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_grid_can_be_cut_into_sections/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m log m)
# Space: O(m)
def check_valid_cuts(self, n: int, rectangles: list[list[int]]) -> bool:
return self._has_two_gaps(rectangles, 0) or self._has_two_gaps(rectangles, 1)
def _has_two_gaps(self, rectangles: list[list[int]], axis: int) -> bool:
rects = sorted(rectangles, key=lambda rect: (rect[axis], rect[axis + 2]))
gaps = 0
end = rects[0][axis + 2]
for rect in rects:
if rect[axis] >= end:
gaps += 1
if gaps >= 2:
return True
end = max(end, rect[axis + 2])
return False
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(m log m) | O(m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Check if Move is Legal Python Solution
Source: https://leetcode-py.wisl.dev/problems/check-if-move-is-legal
Tested Python solution for LeetCode 1958 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1958, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/check-if-move-is-legal/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1958 # by problem number
lcpy gen -s check_if_move_is_legal # by problem name
```
## Problem
You are given a 0-indexed 8 x 8 grid board, where board\[r]\[c] represents the cell (r, c) on a game board. On the board, free cells are represented by '.', white cells are represented by 'W', and black cells are represented by 'B'.
Each move in this game consists of choosing a free cell and changing it to the color you are playing as (either white or black). However, a move is only legal if, after changing it, the cell becomes the endpoint of a good line (horizontal, vertical, or diagonal).
A good line is a line of three or more cells (including the endpoints) where the endpoints of the line are one color, and the remaining cells in the middle are the opposite color (no cells in the line are free). You can find examples for good lines in the figure below:

Given two integers rMove and cMove and a character color representing the color you are playing as (white or black), return true if changing cell (rMove, cMove) to color color is a legal move, or false if it is not legal.
Example 1:
Input: board = \[\[".",".",".","B",".",".",".","."],\[".",".",".","W",".",".",".","."],\[".",".",".","W",".",".",".","."],\[".",".",".","W",".",".",".","."],\["W","B","B",".","W","W","W","B"],\[".",".",".","B",".",".",".","."],\[".",".",".","B",".",".",".","."],\[".",".",".","W",".",".",".","."]], rMove = 4, cMove = 3, color = "B"
Output: true
Explanation: '.', 'W', and 'B' are represented by the colors blue, white, and black respectively, and cell (rMove, cMove) is marked with an 'X'.
The two good lines with the chosen cell as an endpoint are annotated above with the red rectangles.
Example 2:
Input: board = \[\[".",".",".",".",".",".",".","."],\[".","B",".",".","W",".",".","."],\[".",".","W",".",".",".",".","."],\[".",".",".","W","B",".",".","."],\[".",".",".",".",".",".",".","."],\[".",".",".",".","B","W",".","."],\[".",".",".",".",".",".","W","."],\[".",".",".",".",".",".",".","B"]], rMove = 4, cMove = 4, color = "W"
Output: false
Explanation: While there are good lines with the chosen cell as a middle cell, there are no good lines with the chosen cell as an endpoint.
Constraints:
board.length == board\[r].length == 8
0 \<= rMove, cMove \< 8
board\[rMove]\[cMove] == '.'
color is either 'B' or 'W'.
### Examples

```
Input: board = [[".",".",".","B",".",".",".","."],[".",".",".","W",".",".",".","."],[".",".",".","W",".",".",".","."],[".",".",".","W",".",".",".","."],["W","B","B",".","W","W","W","B"],[".",".",".","B",".",".",".","."],[".",".",".","B",".",".",".","."],[".",".",".","W",".",".",".","."]], rMove = 4, cMove = 3, color = "B"
Output: true
Explanation: The two good lines with the chosen cell as an endpoint are annotated above with the red rectangles.
```

```
Input: board = [[".",".",".",".",".",".",".","."],[".","B",".",".","W",".",".","."],[".",".","W",".",".",".",".","."],[".",".",".","W","B",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".","B","W",".","."],[".",".",".",".",".",".","W","."],[".",".",".",".",".",".",".","B"]], rMove = 4, cMove = 4, color = "W"
Output: false
Explanation: While there are good lines with the chosen cell as a middle cell, there are no good lines with the chosen cell as an endpoint.
```
### Constraints
* board.length == board\[r].length == 8
* 0 \<= rMove, cMove \< 8
* board\[rMove]\[cMove] == '.'
* color is either 'B' or 'W'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_move_is_legal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_move_is_legal/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(8 * 8) = O(1)
# Space: O(1)
def check_move(self, board: list[list[str]], r_move: int, c_move: int, color: str) -> bool:
directions = ((1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (1, -1), (-1, 1), (-1, -1))
for dr, dc in directions:
r, c = r_move + dr, c_move + dc
seen = 0
while 0 <= r < 8 and 0 <= c < 8 and board[r][c] != ".":
if board[r][c] == color:
if seen >= 1:
return True
break
seen += 1
r += dr
c += dc
return False
```
## Complexity
| Time | Space |
| ---------------- | ----- |
| O(8 \* 8) = O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Check if Number is a Sum of Powers of Three
Source: https://leetcode-py.wisl.dev/problems/check-if-number-is-a-sum-of-powers-of-three
Tested Python solution for LeetCode 1780 with 48 pytest cases. Generate a practice environment with lcpy.
LeetCode 1780, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Recursion](/catalog/topics/recursion), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/check-if-number-is-a-sum-of-powers-of-three/description/).
Generate this problem as a practice environment: tested reference solution, 48 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1780 # by problem number
lcpy gen -s check_if_number_is_a_sum_of_powers_of_three # by problem name
```
## Problem
Given an integer `n`, return `true` if it is possible to represent `n` as the sum of distinct powers of three. Otherwise, return `false`.
An integer `y` is a power of three if there exists an integer `x` such that `y == 3^x`.
### Examples
```
Input: n = 12
Output: true
Explanation: 12 = 3^1 + 3^2
```
```
Input: n = 91
Output: true
Explanation: 91 = 3^0 + 3^2 + 3^4
```
```
Input: n = 21
Output: false
```
### Constraints
* 1 \<= n \<= 10^7
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_number_is_a_sum_of_powers_of_three/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_number_is_a_sum_of_powers_of_three/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log_3 n)
# Space: O(1)
def check_powers_of_three(self, n: int) -> bool:
while n > 0:
if n % 3 == 2:
return False
n //= 3
return True
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(log\_3 n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Check if One String Swap Can Make Strings
Source: https://leetcode-py.wisl.dev/problems/check-if-one-string-swap-can-make-strings-equal
Tested Python solution for LeetCode 1790 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 1790, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/check-if-one-string-swap-can-make-strings-equal/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1790 # by problem number
lcpy gen -s check_if_one_string_swap_can_make_strings_equal # by problem name
```
## Problem
You are given two strings `s1` and `s2` of equal length. A **string swap** is an operation where you choose two indices in a string (not necessarily different) and swap the characters at these indices.
Return `true` if it is possible to make both strings equal by performing **at most one string swap** on **exactly one** of the strings. Otherwise, return `false`.
### Examples
```
Input: s1 = "bank", s2 = "kanb"
Output: true
Explanation: For example, swap the first character with the last character of s2 to make "bank".
```
```
Input: s1 = "attack", s2 = "defend"
Output: false
Explanation: It is impossible to make them equal with one string swap.
```
```
Input: s1 = "kelb", s2 = "kelb"
Output: true
Explanation: The two strings are already equal, so no string swap operation is required.
```
### Constraints
* 1 \<= s1.length, s2.length \<= 100
* s1.length == s2.length
* s1 and s2 consist of only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_one_string_swap_can_make_strings_equal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_one_string_swap_can_make_strings_equal/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def are_almost_equal(self, s1: str, s2: str) -> bool:
diffs = [i for i, (a, b) in enumerate(zip(s1, s2, strict=True)) if a != b]
if not diffs:
return True
if len(diffs) != 2:
return False
i, j = diffs
return s1[i] == s2[j] and s1[j] == s2[i]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Check if There is a Valid Partition For The
Source: https://leetcode-py.wisl.dev/problems/check-if-there-is-a-valid-partition-for-the-array
Tested Python solution for LeetCode 2369 with 32 pytest cases. Generate a practice environment with lcpy.
LeetCode 2369, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/check-if-there-is-a-valid-partition-for-the-array/description/).
Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2369 # by problem number
lcpy gen -s check_if_there_is_a_valid_partition_for_the_array # by problem name
```
## Problem
You are given a **0-indexed** integer array `nums`. You have to partition the array into one or more **contiguous** subarrays.
We call a partition of the array **valid** if each of the obtained subarrays satisfies **one** of the following conditions:
* The subarray consists of **exactly** 2, equal elements. For example, the subarray `[2,2]` is good.
* The subarray consists of **exactly** 3, equal elements. For example, the subarray `[4,4,4]` is good.
* The subarray consists of **exactly** 3 consecutive increasing elements, that is, the difference between adjacent elements is `1`. For example, the subarray `[3,4,5]` is good, but the subarray `[1,3,5]` is not.
Return `true` *if the array has **at least** one valid partition*. Otherwise, return `false`.
### Examples
```
Input: nums = [4,4,4,5,6]
Output: true
Explanation: The array can be partitioned into the subarrays [4,4] and [4,5,6].
This partition is valid, so we return true.
```
```
Input: nums = [1,1,1,2]
Output: false
Explanation: There is no valid partition for this array.
```
### Constraints
* 2 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_there_is_a_valid_partition_for_the_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/check_if_there_is_a_valid_partition_for_the_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def valid_partition(self, nums: list[int]) -> bool:
# dp over the last three prefix results, rolling to constant space
dp2 = False # can partition nums[:i-3]
dp1 = True # can partition nums[:i-2]
dp0 = False # can partition nums[:i-1]
n = len(nums)
for i in range(2, n + 1):
nxt = False
if dp1 and nums[i - 1] == nums[i - 2]:
nxt = True
elif i >= 3 and dp2:
a, b, c = nums[i - 3], nums[i - 2], nums[i - 1]
if (a == b == c) or (a + 1 == b and b + 1 == c):
nxt = True
dp2, dp1, dp0 = dp1, dp0, nxt
return dp0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Cherry Pickup Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/cherry-pickup
Tested Python solution for LeetCode 741 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 741, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/cherry-pickup/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 741 # by problem number
lcpy gen -s cherry_pickup # by problem name
```
## Problem
You are given an `n x n` `grid` representing a field of cherries, each cell is one of three possible integers.
* `0` means the cell is empty, so you can pass through,
* `1` means the cell contains a cherry that you can pick up and pass through, or
* `-1` means the cell contains a thorn that blocks your way.
Return *the maximum number of cherries you can collect by following the rules below*:
* Starting at the position `(0, 0)` and reaching `(n - 1, n - 1)` by moving right or down through valid path cells (cells with value `0` or `1`).
* After reaching `(n - 1, n - 1)`, returning to `(0, 0)` by moving left or up through valid path cells.
* When passing through a path cell containing a cherry, you pick it up, and the cell becomes an empty cell `0`.
* If there is no valid path between `(0, 0)` and `(n - 1, n - 1)`, then no cherries can be collected.
### Examples

```
Input: grid = [[0,1,-1],[1,0,-1],[1,1,1]]
Output: 5
Explanation: The player started at (0, 0) and went down, down, right right to reach (2, 2).
4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]].
Then, the player went left, up, up, left to return home, picking up one more cherry.
The total number of cherries picked up is 5, and this is the maximum possible.
```
```
Input: grid = [[1,1,-1],[1,-1,1],[-1,1,1]]
Output: 0
```
### Constraints
* n == grid.length
* n == grid\[i].length
* 1 \<= n \<= 50
* grid\[i]\[j] is -1, 0, or 1.
* grid\[0]\[0] != -1
* grid\[n - 1]\[n - 1] != -1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cherry_pickup/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cherry_pickup/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^3) steps x O(n^2) row pairs
# Space: O(n^2)
def cherry_pickup(self, grid: list[list[int]]) -> int:
n = len(grid)
# -1 marks unreachable states (cherry counts are always >= 0)
unreachable = -1
# dp[r1][r2]: max cherries with both walkers on diagonal r + c = t
dp = [[unreachable] * n for _ in range(n)]
dp[0][0] = grid[0][0]
for t in range(1, 2 * n - 1):
ndp = [[unreachable] * n for _ in range(n)]
for r1 in range(max(0, t - n + 1), min(n, t + 1)):
for r2 in range(r1, min(n, t + 1)):
c1, c2 = t - r1, t - r2
if grid[r1][c1] == -1 or grid[r2][c2] == -1:
continue
best = unreachable
for pr1 in (r1 - 1, r1):
for pr2 in (r2 - 1, r2):
if 0 <= pr1 < n and 0 <= pr2 < n and dp[pr1][pr2] > best:
best = dp[pr1][pr2]
if best < 0:
continue
cherries = grid[r1][c1]
if r1 != r2:
cherries += grid[r2][c2]
ndp[r1][r2] = best + cherries
dp = ndp
return max(dp[n - 1][n - 1], 0)
```
## Complexity
| Time | Space |
| ------------------------------- | ------ |
| O(n^3) steps x O(n^2) row pairs | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Cherry Pickup II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/cherry-pickup-ii
Tested Python solution for LeetCode 1463 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1463, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/cherry-pickup-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1463 # by problem number
lcpy gen -s cherry_pickup_ii # by problem name
```
## Problem
You are given a `rows x cols` matrix `grid` representing a field of cherries where `grid[i][j]` represents the number of cherries that you can collect from the `(i, j)` cell.
You have two robots that can collect cherries for you:
* **Robot #1** is located at the **top-left corner** `(0, 0)`, and
* **Robot #2** is located at the **top-right corner** `(0, cols - 1)`.
Return *the maximum number of cherries collection using both robots by following the rules below*:
* From a cell `(i, j)`, robots can move to cell `(i + 1, j - 1)`, `(i + 1, j)`, or `(i + 1, j + 1)`.
* When any robot passes through a cell, It picks up all cherries, and the cell becomes an empty cell.
* When both robots stay in the same cell, only one takes the cherries.
* Both robots cannot move outside of the grid at any moment.
* Both robots should reach the bottom row in `grid`.
### Examples

```
Input: grid = [[3,1,1],[2,5,1],[1,5,5],[2,1,1]]
Output: 24
Explanation: Path of robot #1 and #2 are described in color green and blue respectively.
Cherries taken by Robot #1, (3 + 2 + 5 + 2) = 12.
Cherries taken by Robot #2, (1 + 5 + 5 + 1) = 12.
Total of cherries: 12 + 12 = 24.
```

```
Input: grid = [[1,0,0,0,0,0,1],[2,0,0,0,0,3,0],[2,0,9,0,0,0,0],[0,3,0,5,4,0,0],[1,0,2,3,0,0,6]]
Output: 28
Explanation: Path of robot #1 and #2 are described in color green and blue respectively.
Cherries taken by Robot #1, (1 + 9 + 5 + 2) = 17.
Cherries taken by Robot #2, (1 + 3 + 4 + 3) = 11.
Total of cherries: 17 + 11 = 28.
```
### Constraints
* rows == grid.length
* cols == grid\[i].length
* 2 \<= rows, cols \<= 70
* 0 \<= grid\[i]\[j] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cherry_pickup_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cherry_pickup_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(rows * cols^2)
# Space: O(cols^2)
def cherry_pickup(self, grid: list[list[int]]) -> int:
rows, cols = len(grid), len(grid[0])
cols_sq = cols * cols
# -1 marks unreachable (col, col) state pairs.
prev = [-1] * cols_sq
prev[cols - 1] = grid[0][0] + grid[0][cols - 1]
for row in range(1, rows):
cur = [-1] * cols_sq
row_grid = grid[row]
for c1 in range(cols):
for c2 in range(cols):
best = -1
for d1 in (-1, 0, 1):
p1 = c1 + d1
if p1 < 0 or p1 >= cols:
continue
for d2 in (-1, 0, 1):
p2 = c2 + d2
if p2 < 0 or p2 >= cols:
continue
val = prev[p1 * cols + p2]
if val > best:
best = val
if best < 0:
continue
gain = row_grid[c1] + (row_grid[c2] if c1 != c2 else 0)
cur[c1 * cols + c2] = best + gain
prev = cur
return max(prev)
```
## Complexity
| Time | Space |
| ----------------- | --------- |
| O(rows \* cols^2) | O(cols^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Circular Array Loop Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/circular-array-loop
Tested Python solution for LeetCode 457 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 457, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), Floyd's Cycle Finding Algorithm. [View on LeetCode](https://leetcode.com/problems/circular-array-loop/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 457 # by problem number
lcpy gen -s circular_array_loop # by problem name
```
## Problem
You are playing a game involving a **circular** array of non-zero integers `nums`. Each `nums[i]` denotes the number of indices forward/backward you must move if you are located at index `i`:
* If `nums[i]` is positive, move `nums[i]` steps **forward**, and
* If `nums[i]` is negative, move `abs(nums[i])` steps **backward**.
Since the array is **circular**, you may assume that moving forward from the last element puts you on the first element, and moving backwards from the first element puts you on the last element.
A **cycle** in the array consists of a sequence of indices `seq` of length `k` where:
* Following the movement rules above results in the repeating index sequence `seq[0] -> seq[1] -> ... -> seq[k - 1] -> seq[0] -> ...`
* Every `nums[seq[j]]` is either **all positive** or **all negative**.
* `k > 1`
Return `true` if there is a **cycle** in `nums`, or `false` otherwise.
### Examples

```
Input: nums = [2,-1,1,2,2]
Output: true
```
**Explanation:** The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
We can see the cycle 0 -> 2 -> 3 -> 0 -> ..., and all of its nodes are white (jumping in the same direction).

```
Input: nums = [-1,-2,-3,-4,-5,6]
Output: false
```
**Explanation:** The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
The only cycle is of size 1, so we return false.

```
Input: nums = [1,-1,5,1,4]
Output: true
```
**Explanation:** The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
We can see the cycle 0 -> 1 -> 0 -> ..., and while it is of size > 1, it has a node jumping forward and a node jumping backward, so **it is not a cycle**.
We can see the cycle 3 -> 4 -> 3 -> ..., and all of its nodes are white (jumping in the same direction).
### Constraints
* 1 \<= nums.length \<= 5000
* -1000 \<= nums\[i] \<= 1000
* nums\[i] != 0
**Follow up:** Could you solve it in O(n) time complexity and O(1) extra space complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/circular_array_loop/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/circular_array_loop/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def circular_array_loop(self, nums: list[int]) -> bool:
n = len(nums)
def nxt(i: int) -> int:
return (i + nums[i]) % n
for start in range(n):
if nums[start] == 0:
continue
forward = nums[start] > 0
def ok(j: int, forward: bool = forward) -> bool:
return nums[j] != 0 and (nums[j] > 0) == forward
slow = start
fast = nxt(slow)
while ok(fast) and ok(nxt(fast)):
if slow == fast:
if nxt(slow) != slow:
return True
break
slow = nxt(slow)
fast = nxt(nxt(fast))
# The walk from `start` cannot yield a valid cycle; mark it dead.
i = start
for _ in range(n):
if not ok(i):
break
nums[i], i = 0, nxt(i)
return False
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Circular Sentence Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/circular-sentence
Tested Python solution for LeetCode 2490 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 2490, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/circular-sentence/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2490 # by problem number
lcpy gen -s circular_sentence # by problem name
```
## Problem
\A \sentence\ is a list of words that are separated by a\ single\ space with no leading or trailing spaces.\
\"Hello World"\, \"HELLO"\, \"hello world hello world"\ are all sentences.\Words consist of \only\ uppercase and lowercase English letters. Uppercase and lowercase English letters are considered different.\
\A sentence is \circular \if:\
\For example, \"leetcode exercises sound delightful"\, \"eetcode"\, \"leetcode eats soul" \are all circular sentences. However, \"Leetcode is cool"\, \"happy Leetcode"\, \"Leetcode"\ and \"I like Leetcode"\ are \not\ circular sentences.\
Given a string \sentence\, return \true\\ if it is circular\. Otherwise, return \false\.\
n\, return \the number of ways you can write \\n\\ as the sum of consecutive positive integers.\
### Examples
```
Input: n = 5
Output: 2
```
**Explanation:** 5 = 2 + 3
```
Input: n = 9
Output: 3
```
**Explanation:** 9 = 4 + 5 = 2 + 3 + 4
```
Input: n = 15
Output: 4
```
**Explanation:** 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5
### Constraints
* 1 \<= n \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/consecutive_numbers_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/consecutive_numbers_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(sqrt(n))
# Space: O(1)
def consecutive_numbers_sum(self, n: int) -> int:
count = 0
k = 1
while k * (k - 1) // 2 < n:
if (n - k * (k - 1) // 2) % k == 0:
count += 1
k += 1
return count
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(sqrt(n)) | O(1) |
## Tags
# Constrained Subsequence Sum Python Solution
Source: https://leetcode-py.wisl.dev/problems/constrained-subsequence-sum
Tested Python solution for LeetCode 1425 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 1425, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Queue](/catalog/topics/queue), [Sliding Window](/catalog/topics/sliding-window), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), Monotonic Queue. [View on LeetCode](https://leetcode.com/problems/constrained-subsequence-sum/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1425 # by problem number
lcpy gen -s constrained_subsequence_sum # by problem name
```
## Problem
Given an integer array \nums\ and an integer \k\, return the maximum sum of a \non-empty\ subsequence of that array such that for every two \consecutive\ integers in the subsequence, \nums\[i]\ and \nums\[j]\, where \i \< j\, the condition \j - i \<= k\ is satisfied.\
\A \subsequence\ of an array is obtained by deleting some number of elements (can be zero) from the array, leaving the remaining elements in their original order.
### Examples
```
Input: nums = [10,2,-10,5,20], k = 2
Output: 37
Explanation: The subsequence is [10, 2, 5, 20].
```
```
Input: nums = [-1,-2,-3], k = 1
Output: -1
Explanation: The subsequence must be non-empty, so we choose the largest number.
```
```
Input: nums = [10,-2,-10,-5,20], k = 2
Output: 23
Explanation: The subsequence is [10, -2, -5, 20].
```
### Constraints
* 1 \<= k \<= nums.length \<= 10^5
* -10^4 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/constrained_subsequence_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/constrained_subsequence_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n)
# Space: O(k)
def constrained_subset_sum(self, nums: list[int], k: int) -> int:
dp = [0] * len(nums)
window = deque()
for i, num in enumerate(nums):
dp[i] = num + (dp[window[0]] if window and dp[window[0]] > 0 else 0)
while window and dp[window[-1]] <= dp[i]:
window.pop()
window.append(i)
if window[0] <= i - k:
window.popleft()
return max(dp)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Construct Binary Tree from Inorder and
Source: https://leetcode-py.wisl.dev/problems/construct-binary-tree-from-inorder-and-postorder-traversal
Tested Python solution for LeetCode 106 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 106, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 106 # by problem number
lcpy gen -s construct_binary_tree_from_inorder_and_postorder_traversal # by problem name
```
## Problem
Given two integer arrays `inorder` and `postorder` where `inorder` is the inorder traversal of a binary tree and `postorder` is the postorder traversal of the same tree, construct and return *the binary tree*.
### Examples

```
Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
Output: [3,9,20,null,null,15,7]
```
```
Input: inorder = [-1], postorder = [-1]
Output: [-1]
```
### Constraints
* 1 \<= inorder.length \<= 3000
* postorder.length == inorder.length
* -3000 \<= inorder\[i], postorder\[i] \<= 3000
* inorder and postorder consist of **unique** values
* Each value of postorder also appears in inorder
* inorder is **guaranteed** to be the inorder traversal of the tree
* postorder is **guaranteed** to be the postorder traversal of the tree
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_inorder_and_postorder_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_inorder_and_postorder_traversal/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(n)
def build_tree(self, inorder: list[int], postorder: list[int]) -> TreeNode[int] | None:
indices: dict[int, int] = {value: i for i, value in enumerate(inorder)}
def build(
in_left: int, in_right: int, post_left: int, post_right: int
) -> TreeNode[int] | None:
if in_left > in_right:
return None
root_value = postorder[post_right]
root = TreeNode[int](root_value)
mid = indices[root_value]
left_size = mid - in_left
root.left = build(in_left, mid - 1, post_left, post_left + left_size - 1)
root.right = build(mid + 1, in_right, post_left + left_size, post_right - 1)
return root
return build(0, len(inorder) - 1, 0, len(postorder) - 1)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Construct Binary Tree from Preorder and (#105)
Source: https://leetcode-py.wisl.dev/problems/construct-binary-tree-from-preorder-and-inorder-traversal
Tested Python solution for LeetCode 105 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 105, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 105 # by problem number
lcpy gen -s construct_binary_tree_from_preorder_and_inorder_traversal # by problem name
```
## Problem
Given two integer arrays `preorder` and `inorder` where `preorder` is the preorder traversal of a binary tree and `inorder` is the inorder traversal of the same tree, construct and return the binary tree.
### Examples

```
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
```
```
Input: preorder = [-1], inorder = [-1]
Output: [-1]
```
### Constraints
* 1 \<= preorder.length \<= 3000
* inorder.length == preorder.length
* -3000 \<= preorder\[i], inorder\[i] \<= 3000
* preorder and inorder consist of unique values.
* Each value of inorder also appears in preorder.
* preorder is guaranteed to be the preorder traversal of the tree.
* inorder is guaranteed to be the inorder traversal of the tree.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_preorder_and_inorder_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_preorder_and_inorder_traversal/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
"""
Construct Binary Tree from Preorder and Inorder Traversal
Algorithm Explanation:
- Preorder: Root -> Left -> Right (first element is always root)
- Inorder: Left -> Root -> Right (root splits left/right subtrees)
Example: preorder=[3,9,20,15,7], inorder=[9,3,15,20,7]
Step 1: Root = 3 (first in preorder)
Find 3 in inorder at index 1
Left subtree: inorder[0:1] = [9]
Right subtree: inorder[2:] = [15,20,7]
Step 2: Build left subtree with preorder=[9], inorder=[9]
Root = 9, no children
Step 3: Build right subtree with preorder=[20,15,7], inorder=[15,20,7]
Root = 20, left=[15], right=[7]
Final tree:
3
/ \
9 20
/ \
15 7
"""
# Time: O(n) - hashmap lookup O(1) for each of n nodes
# Space: O(n) - hashmap + recursion stack
def build_tree(self, preorder: list[int], inorder: list[int]) -> TreeNode | None:
if not preorder or not inorder:
return None
inorder_map = {val: i for i, val in enumerate(inorder)}
self.preorder_index = 0
def build(left: int, right: int) -> TreeNode | None:
# left, right: boundaries in inorder array for current subtree
if left > right:
return None
root_val = preorder[self.preorder_index]
self.preorder_index += 1
root = TreeNode(root_val)
mid = inorder_map[root_val] # root position in inorder
# Left subtree: inorder[left:mid-1]
root.left = build(left, mid - 1)
# Right subtree: inorder[mid+1:right]
root.right = build(mid + 1, right)
return root
return build(0, len(inorder) - 1)
```
## Complexity
| Time | Space |
| ---------------------------------------------- | -------------------------------- |
| O(n) - hashmap lookup O(1) for each of n nodes | O(n) - hashmap + recursion stack |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Construct Binary Tree from Preorder and (#889)
Source: https://leetcode-py.wisl.dev/problems/construct-binary-tree-from-preorder-and-postorder-traversal
Tested Python solution for LeetCode 889 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 889, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 889 # by problem number
lcpy gen -s construct_binary_tree_from_preorder_and_postorder_traversal # by problem name
```
## Problem
Given two integer arrays, \preorder\ and \postorder\ where \preorder\ is the preorder traversal of a binary tree of \distinct\ values and \postorder\ is the postorder traversal of the same tree, reconstruct and return the binary tree.\
If there exist multiple answers, you can return \any\ of them.\
### Examples  ``` Input: preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1] Output: [1,2,3,4,5,6,7] ``` ``` Input: preorder = [1], postorder = [1] Output: [1] ``` ### Constraints * 1 \<= preorder.length \<= 30 * 1 \<= preorder\[i] \<= preorder.length * All the values of preorder are unique. * postorder.length == preorder.length * 1 \<= postorder\[i] \<= postorder.length * All the values of postorder are unique. * It is guaranteed that preorder and postorder are the preorder traversal and postorder traversal of the same binary tree. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_preorder_and_postorder_traversal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_preorder_and_postorder_traversal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(n) def construct_from_pre_post( self, preorder: list[int], postorder: list[int] ) -> TreeNode[int] | None: index = {value: i for i, value in enumerate(postorder)} self._pre_index = 0 return self._build(preorder, index, 0, len(postorder) - 1) def _build( self, preorder: list[int], index: dict[int, int], lo: int, hi: int ) -> TreeNode[int] | None: if lo > hi: return None node = TreeNode(preorder[self._pre_index]) self._pre_index += 1 if lo < hi: left_size = index[preorder[self._pre_index]] - lo + 1 node.left = self._build(preorder, index, lo, lo + left_size - 1) node.right = self._build(preorder, index, lo + left_size, hi - 1) return node ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Construct Binary Tree from String Source: https://leetcode-py.wisl.dev/problems/construct-binary-tree-from-string Tested Python solution for LeetCode 536 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 536, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [String](/catalog/topics/string), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/construct-binary-tree-from-string/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 536 # by problem number lcpy gen -s construct_binary_tree_from_string # by problem name ``` ## Problem You need to construct a binary tree from a string consisting of parenthesis and integers. The whole input represents a binary tree. It contains an integer followed by zero, one or two pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains a child binary tree with the same structure. You always start to construct the **left** child node of the parent first if it exists. ### Examples  ``` Input: s = "4(2(3)(1))(6(5))" Output: [4,2,6,3,1,5] ``` ``` Input: s = "4(2(3)(1))(6(5)(7))" Output: [4,2,6,3,1,5,7] ``` ``` Input: s = "-4(2(3)(1))(6(5)(7))" Output: [-4,2,6,3,1,5,7] ``` ### Constraints * 0 \<= s.length \<= 3 \* 10^4 * s consists of digits, '(', ')', and '-' only. * All numbers in the tree have value at most than 2^30. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_binary_tree_from_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) for the recursion stack, where h is the tree height def str2tree(self, s: str) -> TreeNode[int] | None: if not s: return None def parse(i: int) -> tuple[TreeNode[int], int]: start = i if s[i] == "-": i += 1 while i < len(s) and s[i].isdigit(): i += 1 node = TreeNode(int(s[start:i])) if i < len(s) and s[i] == "(": node.left, i = parse(i + 1) i += 1 # closing paren of the left subtree if i < len(s) and s[i] == "(": node.right, i = parse(i + 1) i += 1 # closing paren of the right subtree return node, i root, _ = parse(0) return root ``` ## Complexity | Time | Space | | ---- | -------------------------------------------------------- | | O(n) | O(h) for the recursion stack, where h is the tree height | ## Tags # Construct K Palindrome Strings Python Solution Source: https://leetcode-py.wisl.dev/problems/construct-k-palindrome-strings Tested Python solution for LeetCode 1400 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 1400, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/construct-k-palindrome-strings/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1400 # by problem number lcpy gen -s construct_k_palindrome_strings # by problem name ``` ## Problem Given a string `s` and an integer `k`, return `true` if you can use all the characters in `s` to construct **non-empty** `k` palindrome strings or `false` otherwise. ### Examples ``` Input: s = "annabelle", k = 2 Output: true ``` **Explanation:** You can construct two palindromes using all characters in `s`. Some possible constructions `"anna" + "elble"`, `"anbna" + "elle"`, `"anellena" + "b"`. ``` Input: s = "leetcode", k = 3 Output: false ``` **Explanation:** It is impossible to construct 3 palindromes using all the characters of `s`. ``` Input: s = "true", k = 4 Output: true ``` **Explanation:** The only possible solution is to put each character in a separate string. ### Constraints * `1 <= s.length <= 10^5` * `s` consists of lowercase English letters. * `1 <= k <= 10^5` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_k_palindrome_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_k_palindrome_strings/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n) # Space: O(1) def can_construct(self, s: str, k: int) -> bool: odd = sum(count % 2 for count in Counter(s).values()) return odd <= k <= len(s) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Construct Quad Tree Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/construct-quad-tree Tested Python solution for LeetCode 427 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 427, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/construct-quad-tree/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 427 # by problem number lcpy gen -s construct_quad_tree # by problem name ``` ## Problem Given a `n * n` matrix `grid` of `0's` and `1's` only. We want to represent `grid` with a Quad-Tree. Return *the root of the Quad-Tree representing `grid`*. A Quad-Tree is a tree data structure in which each internal node has exactly four children. Besides, each node has two attributes: * `val`: True if the node represents a grid of 1's or False if the node represents a grid of 0's. Notice that you can assign the `val` to True or False when `isLeaf` is False, and both are accepted in the answer. * `isLeaf`: True if the node is a leaf node on the tree or False if the node has four children. ``` class Node { public boolean val; public boolean isLeaf; public Node topLeft; public Node topRight; public Node bottomLeft; public Node bottomRight; } ``` We can construct a Quad-Tree from a two-dimensional area using the following steps: 1. If the current grid has the same value (i.e all `1's` or all `0's`) set `isLeaf` True and set `val` to the value of the grid and set the four children to Null and stop. 2. If the current grid has different values, set `isLeaf` to False and set `val` to any value and divide the current grid into four sub-grids as shown in the photo. 3. Recurse for each of the children with the proper sub-grid. **Quad-Tree format:** The output represents the serialized format of a Quad-Tree using level order traversal, where `null` signifies a path terminator where no node exists below. The node is represented as a list `[isLeaf, val]`. ### Examples  ``` Input: grid = [[0,1],[1,0]] Output: [[0,1],[1,0],[1,1],[1,1],[1,0]] Explanation: The root is not a leaf. Its four children (top-left, top-right, bottom-left, bottom-right) are leaves. ```  ``` Input: grid = [[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0]] Output: [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]] ``` ### Constraints * n == grid.length == grid\[i].length * n == 2^x where 0 \<= x \<= 6 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_quad_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_quad_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from __future__ import annotations # ruff: noqa: N803 class Node: def __init__( self, val: bool, isLeaf: bool, topLeft: Node | None = None, topRight: Node | None = None, bottomLeft: Node | None = None, bottomRight: Node | None = None, ) -> None: self.val = val self.isLeaf = isLeaf self.topLeft = topLeft self.topRight = topRight self.bottomLeft = bottomLeft self.bottomRight = bottomRight class Solution: # Time: O(n^2) every cell visited once per level, log n levels # Space: O(log n) recursion depth (tree height) def construct(self, grid: list[list[int]]) -> Node: def build(row: int, col: int, size: int) -> Node: first = grid[row][col] uniform = True for r in range(row, row + size): for c in range(col, col + size): if grid[r][c] != first: uniform = False break if not uniform: break if uniform: return Node(val=bool(first), isLeaf=True) half = size // 2 return Node( val=True, isLeaf=False, topLeft=build(row, col, half), topRight=build(row, col + half, half), bottomLeft=build(row + half, col, half), bottomRight=build(row + half, col + half, half), ) return build(0, 0, len(grid)) ``` ## Complexity | Time | Space | | ------------------------------------------------------ | -------------------------------------- | | O(n^2) every cell visited once per level, log n levels | O(log n) recursion depth (tree height) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Construct Smallest Number From DI String Source: https://leetcode-py.wisl.dev/problems/construct-smallest-number-from-di-string Tested Python solution for LeetCode 2375 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 2375, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/construct-smallest-number-from-di-string/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2375 # by problem number lcpy gen -s construct_smallest_number_from_di_string # by problem name ``` ## Problem You are given a 0-indexed string `pattern` of length `n` consisting of the characters `'I'` meaning increasing and `'D'` meaning decreasing. A 0-indexed string `num` of length `n + 1` is created using the following conditions: * `num` consists of the digits `'1'` to `'9'`, where each digit is used at most once. * If `pattern[i] == 'I'`, then `num[i] < num[i + 1]`. * If `pattern[i] == 'D'`, then `num[i] > num[i + 1]`. Return the lexicographically smallest possible string `num` that meets the conditions. ### Examples ``` Input: pattern = "IIIDIDDD" Output: "123549876" Explanation: At indices 0, 1, 2, and 4 we must have that num[i] < num[i+1]. At indices 3, 5, 6, and 7 we must have that num[i] > num[i+1]. Some possible values of num are "245639871", "135749862", and "123849765". It can be proven that "123549876" is the smallest possible num that meets the conditions. ``` ``` Input: pattern = "DDD" Output: "4321" Explanation: Some possible values of num are "9876", "7321", and "8742". It can be proven that "4321" is the smallest possible num that meets the conditions. ``` ### Constraints * 1 \<= pattern.length \<= 8 * pattern consists of only the letters 'I' and 'D'. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_smallest_number_from_di_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_smallest_number_from_di_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def smallest_number(self, pattern: str) -> str: result: list[str] = [] stack: list[str] = [] for i in range(len(pattern) + 1): stack.append(str(i + 1)) if i == len(pattern) or pattern[i] == "I": while stack: result.append(stack.pop()) return "".join(result) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Construct String from Binary Tree Source: https://leetcode-py.wisl.dev/problems/construct-string-from-binary-tree Tested Python solution for LeetCode 606 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 606, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/construct-string-from-binary-tree/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 606 # by problem number lcpy gen -s construct_string_from_binary_tree # by problem name ``` ## Problem Given the `root` node of a binary tree, your task is to create a string representation of the tree following a specific set of formatting rules. The representation should be based on a preorder traversal of the binary tree and must adhere to the following guidelines: * **Node Representation**: Each node in the tree should be represented by its integer value. * **Parentheses for Children**: If a node has at least one child (either left or right), its children should be represented inside parentheses. Specifically: * If a node has a left child, the value of the left child should be enclosed in parentheses immediately following the node's value. * If a node has a right child, the value of the right child should also be enclosed in parentheses. The parentheses for the right child should follow those of the left child. * **Omitting Empty Parentheses**: Any empty parentheses pairs (i.e., `()`) should be omitted from the final string representation of the tree, with one specific exception: when a node has a right child but no left child. In such cases, you must include an empty pair of parentheses to indicate the absence of the left child. This ensures that the one-to-one mapping between the string representation and the original binary tree structure is maintained. ### Examples  ``` Input: root = [1,2,3,4] Output: "1(2(4))(3)" Explanation: Originally, it needs to be "1(2(4)())(3()())", but you need to omit all the empty parenthesis pairs. And it will be "1(2(4))(3)". ```  ``` Input: root = [1,2,3,null,4] Output: "1(2()(4))(3)" Explanation: Almost the same as the first example, except the () after 2 is necessary to indicate the absence of a left child for 2 and the presence of the right child. ``` ### Constraints * The number of nodes in the tree is in the range \[1, 10^4]. * -1000 \<= Node.val \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_string_from_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_string_from_binary_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(n) def tree2str(self, root: TreeNode[int] | None) -> str: if root is None: return "" left = self.tree2str(root.left) right = self.tree2str(root.right) if root.left is None and root.right is not None: return f"{root.val}()({right})" if root.right is not None: return f"{root.val}({left})({right})" if root.left is not None: return f"{root.val}({left})" return str(root.val) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Construct String With Repeat Limit Source: https://leetcode-py.wisl.dev/problems/construct-string-with-repeat-limit Tested Python solution for LeetCode 2182 with 40 pytest cases. Generate a practice environment with lcpy. LeetCode 2182, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/construct-string-with-repeat-limit/description/). Generate this problem as a practice environment: tested reference solution, 40 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2182 # by problem number lcpy gen -s construct_string_with_repeat_limit # by problem name ``` ## Problem You are given a string `s` and an integer `repeatLimit`. Construct a new string `repeatLimitedString` using the characters of `s` such that no letter appears **more than** `repeatLimit` times **in a row**. You do **not** have to use all characters from `s`. Return *the **lexicographically largest*** `repeatLimitedString` *possible*. A string `a` is **lexicographically larger** than a string `b` if in the first position where `a` and `b` differ, string `a` has a letter that appears later in the alphabet than the corresponding letter in `b`. If the first `min(a.length, b.length)` characters do not differ, then the longer string is the lexicographically larger one. ### Examples ``` Input: s = "cczazcc", repeatLimit = 3 Output: "zzcccac" Explanation: We use all of the characters from s to construct the repeatLimitedString "zzcccac". The letter 'a' appears at most 1 time in a row. The letter 'c' appears at most 3 times in a row. The letter 'z' appears at most 2 times in a row. Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString. The string is the lexicographically largest repeatLimitedString possible so we return "zzcccac". Note that the string "zzcccca" is lexicographically larger but the letter 'c' appears more than 3 times in a row, so it is not a valid repeatLimitedString. ``` ``` Input: s = "aababab", repeatLimit = 2 Output: "bbabaa" Explanation: We use only some of the characters from s to construct the repeatLimitedString "bbabaa". The letter 'a' appears at most 2 times in a row. The letter 'b' appears at most 2 times in a row. Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString. The string is the lexicographically largest repeatLimitedString possible so we return "bbabaa". Note that the string "bbabaaa" is lexicographically larger but the letter 'a' appears more than 2 times in a row, so it is not a valid repeatLimitedString. ``` ### Constraints * `1 <= repeatLimit <= s.length <= 10^5` * `s` consists of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_string_with_repeat_limit/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_string_with_repeat_limit/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n + 26 log 26) # Space: O(26) def repeat_limited_string(self, s: str, repeat_limit: int) -> str: counts = [0] * 26 for ch in s: counts[ord(ch) - ord("a")] += 1 parts: list[str] = [] big = 25 while big >= 0: if counts[big] == 0: big -= 1 continue use = min(counts[big], repeat_limit) parts.append(chr(ord("a") + big) * use) counts[big] -= use if counts[big] == 0: big -= 1 continue small = big - 1 while small >= 0 and counts[small] == 0: small -= 1 if small < 0: break parts.append(chr(ord("a") + small)) counts[small] -= 1 return "".join(parts) ``` ## Complexity | Time | Space | | ---------------- | ----- | | O(n + 26 log 26) | O(26) | ## Tags [NeetCode All](/catalog/neetcode). # Construct the Lexicographically Largest Valid Source: https://leetcode-py.wisl.dev/problems/construct-the-lexicographically-largest-valid-sequence Tested Python solution for LeetCode 1718 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 1718, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/construct-the-lexicographically-largest-valid-sequence/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1718 # by problem number lcpy gen -s construct_the_lexicographically_largest_valid_sequence # by problem name ``` ## Problem Given an integer `n`, find a sequence with elements in the range `[1, n]` that satisfies all of the following: * The integer `1` occurs once in the sequence. * Each integer between `2` and `n` occurs twice in the sequence. * For every integer `i` between `2` and `n`, the **distance** between the two occurrences of `i` is exactly `i`. The **distance** between two numbers on the sequence, `a[i]` and `a[j]`, is the absolute difference of their indices, `|j - i|`. Return *the **lexicographically largest** sequence*. It is guaranteed that under the given constraints, there is always a solution. A sequence `a` is lexicographically larger than a sequence `b` (of the same length) if in the first position where `a` and `b` differ, sequence `a` has a number greater than the corresponding number in `b`. For example, `[0,1,9,0]` is lexicographically larger than `[0,1,5,6]` because the first position they differ is at the third number, and `9` is greater than `5`. ### Examples ``` Input: n = 3 Output: [3,1,2,3,2] Explanation: [2,3,2,1,3] is also a valid sequence, but [3,1,2,3,2] is the lexicographically largest valid sequence. ``` ``` Input: n = 5 Output: [5,3,1,4,3,5,2,4,2] ``` ### Constraints * 1 \<= n \<= 20 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_the_lexicographically_largest_valid_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_the_lexicographically_largest_valid_sequence/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n!) # Space: O(n) def construct_distanced_sequence(self, n: int) -> list[int]: size = 2 * n - 1 result = [0] * size used = [False] * (n + 1) def backtrack(index: int) -> bool: if index == size: return True if result[index] != 0: return backtrack(index + 1) for num in range(n, 0, -1): if used[num]: continue second = index + num if num == 1: result[index] = 1 used[1] = True if backtrack(index + 1): return True result[index] = 0 used[1] = False elif second < size and result[second] == 0: result[index] = result[second] = num used[num] = True if backtrack(index + 1): return True result[index] = result[second] = 0 used[num] = False return False backtrack(0) return result ``` ## Complexity | Time | Space | | ----- | ----- | | O(n!) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Construct the Rectangle Python Solution Source: https://leetcode-py.wisl.dev/problems/construct-the-rectangle Tested Python solution for LeetCode 492 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 492, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/construct-the-rectangle/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 492 # by problem number lcpy gen -s construct_the_rectangle # by problem name ``` ## Problem A web developer needs to know how to design a web page's size. So, given a specific rectangular web page's area, your job by now is to design a rectangular web page, whose length L and width W satisfy the following requirements: 1. The area of the rectangular web page you designed must equal to the given target area. 2. The width `W` should not be larger than the length `L`, which means `L >= W`. 3. The difference between length `L` and width `W` should be as small as possible. Return an array `[L, W]` where `L` and `W` are the length and width of the web page you designed in sequence. ### Examples ``` Input: area = 4 Output: [2,2] Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. But according to requirement 2, [1,4] is illegal; according to requirement 3, [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2. ``` ``` Input: area = 37 Output: [37,1] ``` ``` Input: area = 122122 Output: [427,286] ``` ### Constraints * 1 \<= area \<= 10^7 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_the_rectangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/construct_the_rectangle/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import math class Solution: # Time: O(sqrt(area)) # Space: O(1) def construct_rectangle(self, area: int) -> list[int]: width = math.isqrt(area) while area % width != 0: width -= 1 return [area // width, width] ``` ## Complexity | Time | Space | | ------------- | ----- | | O(sqrt(area)) | O(1) | ## Tags # Contain Virus Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/contain-virus Tested Python solution for LeetCode 749 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 749, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/contain-virus/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 749 # by problem number lcpy gen -s contain_virus # by problem name ``` ## Problem A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls. The world is modeled as an `m x n` binary grid `isInfected`, where `isInfected[i][j] == 0` represents uninfected cells, and `isInfected[i][j] == 1` represents cells contaminated with the virus. A wall (and only one wall) can be installed between any two **4-directionally** adjacent cells, on the shared boundary. Every night, the virus spreads to all neighboring cells in all four directions unless blocked by a wall. Resources are limited. Each day, you can install walls around only one region (i.e., the affected area (continuous block of infected cells) that threatens the most uninfected cells the following night). There **will never be a tie**. Return *the number of walls used to quarantine all the infected regions*. If the world will become fully infected, return the number of walls used. ### Examples  ``` Input: isInfected = [[0,1,0,0,0,0,0,1],[0,1,0,0,0,0,0,1],[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0]] Output: 10 Explanation: There are 2 contaminated regions. On the first day, add 5 walls to quarantine the viral region on the left. The board after the virus spreads is:  On the second day, add 5 walls to quarantine the viral region on the right. The virus is fully contained.  ```  ``` Input: isInfected = [[1,1,1],[1,0,1],[1,1,1]] Output: 4 Explanation: Even though there is only one cell saved, there are 4 walls built. Notice that walls are only built on the shared boundary of two different cells. ``` ``` Input: isInfected = [[1,1,1,0,0,0,0,0,0],[1,0,1,0,1,1,1,1,1],[1,1,1,0,0,0,0,0,0]] Output: 13 Explanation: The region on the left only builds two new walls. ``` ### Constraints * m == isInfected.length * n == isInfected\[i].length * 1 \<= m, n \<= 50 * isInfected\[i]\[j] is either 0 or 1. * There is always a contiguous viral region throughout the described process that will infect strictly more uncontaminated squares in the next round. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contain_virus/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contain_virus/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O((m * n)^2) across all days # Space: O(m * n) def contain_virus(self, is_infected: list[list[int]]) -> int: grid = is_infected rows, cols = len(grid), len(grid[0]) walls_used = 0 while True: seen = [[False] * cols for _ in range(rows)] regions: list[tuple[list[tuple[int, int]], set[tuple[int, int]], int]] = [] for r in range(rows): for c in range(cols): if grid[r][c] == 1 and not seen[r][c]: seen[r][c] = True stack = [(r, c)] cells: list[tuple[int, int]] = [] fronts: set[tuple[int, int]] = set() walls = 0 while stack: x, y = stack.pop() cells.append((x, y)) for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): nx, ny = x + dx, y + dy if 0 <= nx < rows and 0 <= ny < cols: if grid[nx][ny] == 0: walls += 1 fronts.add((nx, ny)) elif grid[nx][ny] == 1 and not seen[nx][ny]: seen[nx][ny] = True stack.append((nx, ny)) regions.append((cells, fronts, walls)) if not regions: break max_threat = max(len(fronts) for _, fronts, _ in regions) if max_threat == 0: break target = next(region for region in regions if len(region[1]) == max_threat) walls_used += target[2] for x, y in target[0]: grid[x][y] = -1 for cells, fronts, _ in regions: if cells is not target[0]: for x, y in fronts: grid[x][y] = 1 return walls_used ``` ## Complexity | Time | Space | | ----------------------------- | --------- | | O((m \* n)^2) across all days | O(m \* n) | ## Tags # Container With Most Water Python Solution Source: https://leetcode-py.wisl.dev/problems/container-with-most-water Tested Python solution for LeetCode 11 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 11, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/container-with-most-water/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 11 # by problem number lcpy gen -s container_with_most_water # by problem name ``` ## Problem 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])`. Find two lines that together with the x-axis form a container, such that the container contains the most water. Return the maximum amount of water a container can store. Notice that you may not slant the container. ### Examples  ``` Input: height = [1,8,6,2,5,4,8,3,7] Output: 49 ``` **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. ``` Input: height = [1,1] Output: 1 ``` ### Constraints * n == height.length * 2 \<= n \<= 10^5 * 0 \<= height\[i] \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/container_with_most_water/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/container_with_most_water/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_area(self, height: list[int]) -> int: left = 0 right = len(height) - 1 max_area_so_far = 0 while left < right: area = min(height[left], height[right]) * (right - left) max_area_so_far = max(area, max_area_so_far) if height[right] > height[left]: left += 1 else: right -= 1 return max_area_so_far ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Contains Duplicate Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/contains-duplicate Tested Python solution for LeetCode 217 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 217, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/contains-duplicate/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 217 # by problem number lcpy gen -s contains_duplicate # by problem name ``` ## Problem 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. ### Examples ``` Input: nums = [1,2,3,1] Output: true ``` **Explanation:** The element 1 occurs at the indices 0 and 3. ``` Input: nums = [1,2,3,4] Output: false ``` **Explanation:** All elements are distinct. ``` Input: nums = [1,1,1,3,3,4,3,2,4,2] Output: true ``` ### Constraints * 1 \<= nums.length \<= 10^5 * -10^9 \<= nums\[i] \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contains_duplicate/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contains_duplicate/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def contains_duplicate(self, nums: list[int]) -> bool: seen = set() for num in nums: if num in seen: return True seen.add(num) return False ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Contains Duplicate II Python Solution Source: https://leetcode-py.wisl.dev/problems/contains-duplicate-ii Tested Python solution for LeetCode 219 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 219, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/contains-duplicate-ii/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 219 # by problem number lcpy gen -s contains_duplicate_ii # by problem name ``` ## Problem Given an integer array `nums` and an integer `k`, return `true` \*if there are two **distinct indices** \* `i` *and* `j` *in the array such that* `nums[i] == nums[j]` *and* `abs(i - j) <= k`. ### Examples ``` Input: nums = [1,2,3,1], k = 3 Output: true ``` ``` Input: nums = [1,0,1,1], k = 1 Output: true ``` ``` Input: nums = [1,2,3,1,2,3], k = 2 Output: false ``` ### Constraints * 1 \<= nums.length \<= 10^5 * -10^9 \<= nums\[i] \<= 10^9 * 0 \<= k \<= 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contains_duplicate_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contains_duplicate_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def contains_nearby_duplicate(self, nums: list[int], k: int) -> bool: last_seen: dict[int, int] = {} for i, num in enumerate(nums): if num in last_seen and i - last_seen[num] <= k: return True last_seen[num] = i return False ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Contains Duplicate III Python Solution Source: https://leetcode-py.wisl.dev/problems/contains-duplicate-iii Tested Python solution for LeetCode 220 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 220, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window), [Sorting](/catalog/topics/sorting), Bucket Sort, [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/contains-duplicate-iii/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 220 # by problem number lcpy gen -s contains_duplicate_iii # by problem name ``` ## Problem You are given an integer array `nums` and two integers `indexDiff` and `valueDiff`. Find a pair of indices `(i, j)` such that: * `i != j`, * `abs(i - j) <= indexDiff`, and * `abs(nums[i] - nums[j]) <= valueDiff`. Return `true` *if such pair exists or* `false` *otherwise*. ### Examples ``` Input: nums = [1,2,3,1], indexDiff = 3, valueDiff = 0 Output: true Explanation: We can choose (i, j) = (0, 3). i != j, abs(i - j) <= indexDiff, abs(nums[i] - nums[j]) <= valueDiff ``` ``` Input: nums = [1,5,9,1,5,9], indexDiff = 2, valueDiff = 3 Output: false Explanation: No pair of indices satisfies all three conditions. ``` ### Constraints * 2 \<= nums.length \<= 10^5 * -10^9 \<= nums\[i] \<= 10^9 * 1 \<= indexDiff \<= nums.length * 0 \<= valueDiff \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contains_duplicate_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contains_duplicate_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(min(n, index_diff)) def contains_nearby_almost_duplicate( self, nums: list[int], index_diff: int, value_diff: int ) -> bool: width = value_diff + 1 buckets: dict[int, int] = {} for i, num in enumerate(nums): if i > index_diff: del buckets[nums[i - index_diff - 1] // width] bucket = num // width if bucket in buckets: return True if bucket - 1 in buckets and num - buckets[bucket - 1] <= value_diff: return True if bucket + 1 in buckets and buckets[bucket + 1] - num <= value_diff: return True buckets[bucket] = num return False ``` ## Complexity | Time | Space | | ---- | ---------------------- | | O(n) | O(min(n, index\_diff)) | ## Tags # Contiguous Array Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/contiguous-array Tested Python solution for LeetCode 525 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 525, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/contiguous-array/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 525 # by problem number lcpy gen -s contiguous_array # by problem name ``` ## Problem Given a binary array `nums`, return *the maximum length of a contiguous subarray with an equal number of* `0` *and* `1`. ### Examples ``` Input: nums = [0,1] Output: 2 Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1. ``` ``` Input: nums = [0,1,0] Output: 2 Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1. ``` ``` Input: nums = [0,1,1,1,1,1,0,0,0] Output: 6 Explanation: [1,1,1,0,0,0] is the longest contiguous subarray with equal number of 0 and 1. ``` ### Constraints * `1 <= nums.length <= 10^5` * `nums[i]` is either `0` or `1`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contiguous_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/contiguous_array/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def find_max_length(self, nums: list[int]) -> int: count_map = {0: -1} count = 0 max_len = 0 for i, num in enumerate(nums): count += 1 if num == 1 else -1 if count in count_map: max_len = max(max_len, i - count_map[count]) else: count_map[count] = i return max_len ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Continuous Subarray Sum Python Solution Source: https://leetcode-py.wisl.dev/problems/continuous-subarray-sum Tested Python solution for LeetCode 523 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 523, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/continuous-subarray-sum/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 523 # by problem number lcpy gen -s continuous_subarray_sum # by problem name ``` ## Problem Given an integer array `nums` and an integer `k`, return `true` *if* `nums` *has a **good subarray** or* `false` *otherwise*. A **good subarray** is a subarray where: * its length is **at least two**, and * the sum of the elements of the subarray is a multiple of `k`. **Note** that: * A **subarray** is a contiguous part of the array. * An integer `x` is a multiple of `k` if there exists an integer `n` such that `x = n * k`. `0` is **always** a multiple of `k`. ### Examples ``` Input: nums = [23,2,4,6,7], k = 6 Output: true Explanation: [2, 4] is a continuous subarray of size 2 whose elements sum up to 6. ``` ``` Input: nums = [23,2,6,4,7], k = 6 Output: true Explanation: [23, 2, 6, 4, 7] is an continuous subarray of size 5 whose elements sum up to 42. 42 is a multiple of 6 because 42 = 7 * 6 and 7 is an integer. ``` ``` Input: nums = [23,2,6,4,7], k = 13 Output: false ``` ### Constraints * `1 <= nums.length <= 10^5` * `0 <= nums[i] <= 10^9` * `0 <= sum(nums[i]) <= 2^31 - 1` * `1 <= k <= 2^31 - 1` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/continuous_subarray_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/continuous_subarray_sum/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(min(n, k)) def check_subarray_sum(self, nums: list[int], k: int) -> bool: remainder_index: dict[int, int] = {0: -1} prefix = 0 for i, num in enumerate(nums): prefix = (prefix + num) % k if prefix in remainder_index: if i - remainder_index[prefix] >= 2: return True else: remainder_index[prefix] = i return False ``` ## Complexity | Time | Space | | ---- | ------------ | | O(n) | O(min(n, k)) | ## Tags [NeetCode All](/catalog/neetcode). # Convert 1D Array Into 2D Array Python Solution Source: https://leetcode-py.wisl.dev/problems/convert-1d-array-into-2d-array Tested Python solution for LeetCode 2022 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 2022, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/convert-1d-array-into-2d-array/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2022 # by problem number lcpy gen -s convert_1d_array_into_2d_array # by problem name ``` ## Problem You are given a 0-indexed 1-dimensional (1D) integer array `original`, and two integers, `m` and `n`. You are tasked with creating a 2-dimensional (2D) array with `m` rows and `n` columns using **all** the elements from `original`. The elements from indices `0` to `n - 1` (**inclusive**) of `original` should form the first row of the constructed 2D array, the elements from indices `n` to `2 * n - 1` (**inclusive**) should form the second row of the constructed 2D array, and so on. Return *an* `m x n` *2D array constructed according to the above procedure, or an empty 2D array if it is impossible*. ### Examples  ``` Input: original = [1,2,3,4], m = 2, n = 2 Output: [[1,2],[3,4]] Explanation: The constructed 2D array should contain 2 rows and 2 columns. The first group of n=2 elements in original, [1,2], becomes the first row in the constructed 2D array. The second group of n=2 elements in original, [3,4], becomes the second row in the constructed 2D array. ``` ``` Input: original = [1,2,3], m = 1, n = 3 Output: [[1,2,3]] Explanation: The constructed 2D array should contain 1 row and 3 columns. Put all three elements in original into the first row of the constructed 2D array. ``` ``` Input: original = [1,2], m = 1, n = 1 Output: [] Explanation: There are 2 elements in original. It is impossible to fit 2 elements in a 1x1 2D array, so return an empty 2D array. ``` ### Constraints * `1 <= original.length <= 5 * 10^4` * `1 <= original[i] <= 10^5` * `1 <= m, n <= 4 * 10^4` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_1d_array_into_2d_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_1d_array_into_2d_array/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(len(original)) # Space: O(m * n) for the output def construct_2d_array(self, original: list[int], m: int, n: int) -> list[list[int]]: if len(original) != m * n: return [] return [original[i * n : (i + 1) * n] for i in range(m)] ``` ## Complexity | Time | Space | | ---------------- | ------------------------ | | O(len(original)) | O(m \* n) for the output | ## Tags [NeetCode All](/catalog/neetcode). # Convert a Number to Hexadecimal Source: https://leetcode-py.wisl.dev/problems/convert-a-number-to-hexadecimal Tested Python solution for LeetCode 405 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 405, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/convert-a-number-to-hexadecimal/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 405 # by problem number lcpy gen -s convert_a_number_to_hexadecimal # by problem name ``` ## Problem Given a 32-bit integer `num`, return *a string representing its hexadecimal representation*. For negative integers, [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) method is used. All the letters in the answer string should be lowercase characters, and there should not be any leading zeros in the answer except for the zero itself. **Note:** You are not allowed to use any built-in library method to directly solve this problem. ### Examples ``` Input: num = 26 Output: "1a" ``` ``` Input: num = -1 Output: "ffffffff" ``` ### Constraints * -2^31 \<= num \<= 2^31 - 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_a_number_to_hexadecimal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_a_number_to_hexadecimal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(1) - at most 8 hex digits for a 32-bit integer # Space: O(1) - output string holds at most 8 characters def to_hex(self, num: int) -> str: value = num & 0xFFFFFFFF digits = "0123456789abcdef" if value == 0: return "0" out: list[str] = [] while value: out.append(digits[value & 0xF]) value >>= 4 return "".join(reversed(out)) ``` ## Complexity | Time | Space | | ------------------------------------------------ | ----------------------------------------------- | | O(1) - at most 8 hex digits for a 32-bit integer | O(1) - output string holds at most 8 characters | ## Tags # Convert an Array Into a 2D Array With Source: https://leetcode-py.wisl.dev/problems/convert-an-array-into-a-2d-array-with-conditions Tested Python solution for LeetCode 2610 with 23 pytest cases. Generate a practice environment with lcpy. LeetCode 2610, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/convert-an-array-into-a-2d-array-with-conditions/description/). Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2610 # by problem number lcpy gen -s convert_an_array_into_a_2d_array_with_conditions # by problem name ``` ## Problem You are given an integer array `nums`. You need to create a 2D array from `nums` satisfying the following conditions: * The 2D array should contain **only** the elements of the array `nums`. * Each row in the 2D array contains **distinct** integers. * The number of rows in the 2D array should be **minimal**. Return *the resulting array*. If there are multiple answers, return **any** of them. **Note** that the 2D array can have a different number of elements on each row. ### Examples ``` Input: nums = [1,3,4,1,2,3,1] Output: [[1,3,4,2],[1,3],[1]] Explanation: We can create a 2D array that contains the following rows: - 1,3,4,2 - 1,3 - 1 All elements of nums were used, and each row of the 2D array contains distinct integers, so it is a valid answer. It can be shown that we cannot have less than 3 rows in a valid array. ``` ``` Input: nums = [1,2,3,4] Output: [[4,3,2,1]] Explanation: All elements of the array are distinct, so we can keep all of them in the first row of the 2D array. ``` ### Constraints * `1 <= nums.length <= 200` * `1 <= nums[i] <= nums.length` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_an_array_into_a_2d_array_with_conditions/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_an_array_into_a_2d_array_with_conditions/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n) # Space: O(n) def find_matrix(self, nums: list[int]) -> list[list[int]]: counts = Counter(nums) rows: list[list[int]] = [[] for _ in range(max(counts.values()))] for value, count in counts.items(): for row in rows[:count]: row.append(value) return rows ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Convert Binary Search Tree to Sorted Doubly Source: https://leetcode-py.wisl.dev/problems/convert-binary-search-tree-to-sorted-doubly-linked-list Tested Python solution for LeetCode 426 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 426, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Linked List](/catalog/topics/linked-list), [Binary Tree](/catalog/topics/binary-tree), Doubly-Linked List. [View on LeetCode](https://leetcode.com/problems/convert-binary-search-tree-to-sorted-doubly-linked-list/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 426 # by problem number lcpy gen -s convert_binary_search_tree_to_sorted_doubly_linked_list # by problem name ``` ## Problem Convert a **Binary Search Tree** to a sorted **Circular Doubly-Linked List** in place. You can think of the left and right pointers as synonymous to the predecessor and successor pointers in a doubly-linked list. For a circular doubly linked list, the predecessor of the first element is the last element, and the successor of the last element is the first element. We want to do the transformation **in place**. After the transformation, the left pointer of the tree node should point to its predecessor, and the right pointer should point to its successor. You should return the pointer to the smallest element of the linked list. ### Examples  ``` Input: root = [4,2,5,1,3] Output: [1,2,3,4,5] Explanation: The figure below shows the transformed BST. The solid line indicates the successor relationship, while the dashed line means the predecessor relationship. ``` ``` Input: root = [2,1,3] Output: [1,2,3] ``` ### Constraints * The number of nodes in the tree is in the range `[0, 2000]`. * `-1000 <= Node.val <= 1000` * All the values of the tree are **unique**. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_binary_search_tree_to_sorted_doubly_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_binary_search_tree_to_sorted_doubly_linked_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) recursion stack def tree_to_doubly_list(self, root: TreeNode[int] | None) -> TreeNode[int] | None: if root is None: return None first: TreeNode[int] | None = None last: TreeNode[int] | None = None def link(node: TreeNode[int]) -> None: nonlocal first, last if last is not None: last.right = node node.left = last else: first = node last = node def dfs(node: TreeNode[int] | None) -> None: if node is None: return dfs(node.left) link(node) dfs(node.right) dfs(root) assert last is not None and first is not None last.right = first first.left = last return first ``` ## Complexity | Time | Space | | ---- | -------------------- | | O(n) | O(h) recursion stack | ## Tags [NeetCode All](/catalog/neetcode). # Convert BST to Greater Tree Python Solution Source: https://leetcode-py.wisl.dev/problems/convert-bst-to-greater-tree Tested Python solution for LeetCode 538 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 538, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/convert-bst-to-greater-tree/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 538 # by problem number lcpy gen -s convert_bst_to_greater_tree # by problem name ``` ## Problem Given the `root` of a Binary Search Tree (BST), convert it to a **Greater Tree** such that every key of the original BST is changed to the original key plus the sum of all keys **greater** than the original key in BST. As a reminder, a *binary search tree* is a tree that satisfies these constraints: * The left subtree of a node contains only nodes with keys **less than** the node's key. * The right subtree of a node contains only nodes with keys **greater than** the node's key. * Both the left and right subtrees must also be binary search trees. ### Examples  ``` Input: root = [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8] Output: [30,36,21,36,35,26,15,null,null,null,33,null,null,null,8] ``` ``` Input: root = [0,null,1] Output: [1,null,1] ``` ### Constraints * The number of nodes in the tree is in the range `[0, 10^4]`. * `-10^4 <= Node.val <= 10^4` * All the values in the tree are **unique**. * `root` is guaranteed to be a valid binary search tree. **Note:** This question is the same as 1038: Binary Search Tree to Greater Sum Tree. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_bst_to_greater_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_bst_to_greater_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(h) recursion stack def convert_bst(self, root: TreeNode[int] | None) -> TreeNode[int] | None: def reverse_inorder(node: TreeNode[int] | None) -> None: nonlocal total if node is None: return reverse_inorder(node.right) total += node.val node.val = total reverse_inorder(node.left) total = 0 reverse_inorder(root) return root ``` ## Complexity | Time | Space | | ---- | -------------------- | | O(n) | O(h) recursion stack | ## Tags [NeetCode All](/catalog/neetcode). # Convert Sorted Array to Binary Search Tree Source: https://leetcode-py.wisl.dev/problems/convert-sorted-array-to-binary-search-tree Tested Python solution for LeetCode 108 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 108, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 108 # by problem number lcpy gen -s convert_sorted_array_to_binary_search_tree # by problem name ``` ## Problem Given an integer array `nums` where the elements are sorted in ascending order, convert it to a **height-balanced** binary search tree. ### Examples  ``` Input: nums = [-10,-3,0,5,9] Output: [0,-3,9,-10,null,5] Explanation: [0,-10,5,null,-3,null,9] is also accepted:  ```  ``` Input: nums = [1,3] Output: [3,1] Explanation: [1,null,3] and [3,1] are both height-balanced BSTs. ``` ### Constraints * 1 \<= nums.length \<= 10^4 * -10^4 \<= nums\[i] \<= 10^4 * nums is sorted in a strictly increasing order. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_sorted_array_to_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_sorted_array_to_binary_search_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) — each element becomes one node # Space: O(log n) recursion stack for a balanced build def sorted_array_to_bst(self, nums: list[int]) -> TreeNode[int] | None: def build(left: int, right: int) -> TreeNode[int] | None: if left > right: return None mid = (left + right) // 2 node = TreeNode[int](nums[mid]) node.left = build(left, mid - 1) node.right = build(mid + 1, right) return node return build(0, len(nums) - 1) ``` ## Complexity | Time | Space | | ------------------------------------ | --------------------------------------------- | | O(n) — each element becomes one node | O(log n) recursion stack for a balanced build | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Convert Sorted List to Binary Search Tree Source: https://leetcode-py.wisl.dev/problems/convert-sorted-list-to-binary-search-tree Tested Python solution for LeetCode 109 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 109, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 109 # by problem number lcpy gen -s convert_sorted_list_to_binary_search_tree # by problem name ``` ## Problem Given the `head` of a singly linked list where elements are sorted in **ascending order**, convert it to a **height-balanced** binary search tree. ### Examples  ``` Input: head = [-10,-3,0,5,9] Output: [0,-3,9,-10,null,5] Explanation: One possible answer is [0,-3,9,-10,null,5], which represents the shown height balanced BST. ``` ``` Input: head = [] Output: [] ``` ### Constraints * The number of nodes in head is in the range \[0, 2 \* 10^4]. * -10^5 \<= Node.val \<= 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_sorted_list_to_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convert_sorted_list_to_binary_search_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode, TreeNode class Solution: # Time: O(n) - each list node is visited once, in the same order the # in-order traversal consumes them. # Space: O(log n) - recursion depth equals the tree height. def sorted_list_to_bst(self, head: ListNode[int] | None) -> TreeNode[int] | None: size = 0 node = head while node is not None: size += 1 node = node.next cursor = head def build(lo: int, hi: int) -> TreeNode[int] | None: nonlocal cursor if lo > hi: return None mid = (lo + hi) // 2 left = build(lo, mid - 1) cur = cursor assert cur is not None cursor = cur.next return TreeNode(cur.val, left, build(mid + 1, hi)) return build(0, size - 1) ``` ## Complexity | Time | Space | | ------------------------------------------------------------ | -------------------------------------------------- | | O(n) - each list node is visited once, in the same order the | O(log n) - recursion depth equals the tree height. | ## Tags # Convex Polygon Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/convex-polygon Tested Python solution for LeetCode 469 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 469, [Medium](/catalog/medium). Topics: [Geometry](/catalog/topics/geometry), [Array](/catalog/topics/array), [Math](/catalog/topics/math), Polygon. [View on LeetCode](https://leetcode.com/problems/convex-polygon/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 469 # by problem number lcpy gen -s convex_polygon # by problem name ``` ## Problem You are given an array of points on the **X-Y** plane `points` where `points[i] = [x_i, y_i]`. The points form a polygon when joined sequentially. Return `true` if this polygon is [convex](http://en.wikipedia.org/wiki/Convex_polygon) and `false` otherwise. You may assume the polygon formed by given points is always a [simple polygon](http://en.wikipedia.org/wiki/Simple_polygon). In other words, we ensure that exactly two edges intersect at each vertex and that edges otherwise don't intersect each other. ### Examples  ``` Input: points = [[0,0],[0,5],[5,5],[5,0]] Output: true ```  ``` Input: points = [[0,0],[0,10],[10,10],[10,0],[5,5]] Output: false ``` ### Constraints * `3 <= points.length <= 10^4` * `points[i].length == 2` * `-10^4 <= x_i, y_i <= 10^4` * All the given points are **unique**. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convex_polygon/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/convex_polygon/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def is_convex(self, points: list[list[int]]) -> bool: n = len(points) sign = 0 for i in range(n): x1, y1 = points[i] x2, y2 = points[(i + 1) % n] x3, y3 = points[(i + 2) % n] cross = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2) if cross != 0: if sign == 0: sign = 1 if cross > 0 else -1 elif (cross > 0) != (sign > 0): return False return True ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Copy List with Random Pointer Python Solution Source: https://leetcode-py.wisl.dev/problems/copy-list-with-random-pointer Tested Python solution for LeetCode 138 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 138, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/copy-list-with-random-pointer/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 138 # by problem number lcpy gen -s copy_list_with_random_pointer # by problem name ``` ## Problem A linked list of length `n` is given such that each node contains an additional **random pointer**, which could point to any node in the list, or `null`. Construct a [**deep copy**](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) of the list. The deep copy should consist of exactly `n` **brand new** nodes, where each new node has its value set to the value of its corresponding original node. Both the `next` and `random` pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. **None of the pointers in the new list should point to nodes in the original list**. Return *the head of the copied linked list*. The linked list is represented in the input/output as a list of `n` nodes. Each node is represented as a pair of `[val, random_index]` where: * `val`: an integer representing `Node.val` * `random_index`: the index of the node (range from `0` to `n-1`) that the `random` pointer points to, or `null` if it does not point to any node. ### Examples  ``` Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]] Output: [[7,null],[13,0],[11,4],[10,2],[1,0]] ```  ``` Input: head = [[1,1],[2,1]] Output: [[1,1],[2,1]] ```  ``` Input: head = [[3,null],[3,0],[3,null]] Output: [[3,null],[3,0],[3,null]] ``` ### Constraints * 0 \<= n \<= 1000 * -10^4 \<= Node.val \<= 10^4 * Node.random is null or points to some node in the linked list. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/copy_list_with_random_pointer/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/copy_list_with_random_pointer/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from __future__ import annotations class Node: def __init__(self, x: int, next: Node | None = None, random: Node | None = None): self.val = int(x) self.next = next self.random = random class Solution: # Time: O(n) # Space: O(1) extra (interweaves clones into the original list) def copy_random_list(self, head: Node | None) -> Node | None: if head is None: return None # Phase 1: insert each clone right after its original node current: Node | None = head while current is not None: nxt = current.next clone = Node(current.val, nxt) current.next = clone current = nxt # Phase 2: wire each clone's random from its original's random current = head while current is not None: clone = current.next assert clone is not None if current.random is not None: rand_clone = current.random.next assert rand_clone is not None clone.random = rand_clone current = clone.next # Phase 3: detach clones, restore the original, return the copy head current = head copy_head = head.next while current is not None: clone = current.next assert clone is not None current.next = clone.next tail = clone.next clone.next = tail.next if tail is not None else None current = current.next return copy_head ``` ## Complexity | Time | Space | | ---- | ------------------------------------------------------ | | O(n) | O(1) extra (interweaves clones into the original list) | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Count All Valid Pickup and Delivery Options Source: https://leetcode-py.wisl.dev/problems/count-all-valid-pickup-and-delivery-options Tested Python solution for LeetCode 1359 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 1359, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), Combinatorics. [View on LeetCode](https://leetcode.com/problems/count-all-valid-pickup-and-delivery-options/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1359 # by problem number lcpy gen -s count_all_valid_pickup_and_delivery_options # by problem name ``` ## Problem Given \n\ orders, each order consists of a pickup and a delivery service.
Count all valid pickup/delivery possible sequences such that delivery(i) is always after of pickup(i).
Since the answer may be too large, return it modulo\ 10\9\ + 7\.
### Examples
```
Input: n = 1
Output: 1
Explanation: Unique order (P1, D1), Delivery 1 always is after of Pickup 1.
```
```
Input: n = 2
Output: 6
Explanation: All possible orders:
(P1,P2,D1,D2), (P1,P2,D2,D1), (P1,D1,P2,D2), (P2,P1,D1,D2), (P2,P1,D2,D1) and (P2,D2,P1,D1).
This is an invalid order (P1,D2,P2,D1) because Pickup 2 is after of Delivery 2.
```
```
Input: n = 3
Output: 90
```
### Constraints
* 1 \<= n \<= 500
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_all_valid_pickup_and_delivery_options/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_all_valid_pickup_and_delivery_options/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_orders(self, n: int) -> int:
# Inserting the i-th order into a valid sequence of i-1 orders:
# place pickup_i in one of 2i-1 gaps, then delivery_i in one of
# the remaining 2i positions -> factor of (2i - 1) * i.
mod = 1_000_000_007
result = 1
for i in range(2, n + 1):
result = result * (2 * i - 1) % mod * i % mod
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count and Say Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/count-and-say
Tested Python solution for LeetCode 38 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 38, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/count-and-say/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 38 # by problem number
lcpy gen -s count_and_say # by problem name
```
## Problem
The **count-and-say** sequence is a sequence of digit strings defined by the recursive formula:
* `countAndSay(1) = "1"`
* `countAndSay(n)` is the run-length encoding of `countAndSay(n - 1)`.
[Run-length encoding](http://en.wikipedia.org/wiki/Run-length_encoding) (RLE) is a string compression method that works by replacing each maximal group of consecutive identical characters with the concatenation of the length of the group followed by the character itself. For example, to compress the string `"3322251"` we replace `"33"` with `"23"`, replace `"222"` with `"32"`, replace `"5"` with `"15"`, and replace `"1"` with `"11"`. Thus the compressed string becomes `"23321511"`.
Given a positive integer `n`, return the `nth` element of the **count-and-say** sequence.
### Examples
```
Input: n = 4
Output: "1211"
Explanation:
countAndSay(1) = "1"
countAndSay(2) = RLE of "1" = "11"
countAndSay(3) = RLE of "11" = "21"
countAndSay(4) = RLE of "21" = "1211"
```
```
Input: n = 1
Output: "1"
Explanation:
This is the base case.
```
### Constraints
* 1 \<= n \<= 30
**Follow up:** Could you solve it iteratively?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_and_say/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_and_say/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * L) where L is the length of the resulting string
# Space: O(L)
def count_and_say(self, n: int) -> str:
s = "1"
for _ in range(n - 1):
parts: list[str] = []
i = 0
while i < len(s):
j = i
while j < len(s) and s[j] == s[i]:
j += 1
parts.append(str(j - i))
parts.append(s[i])
i = j
s = "".join(parts)
return s
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | ----- |
| O(n \* L) where L is the length of the resulting string | O(L) |
## Tags
# Count Binary Substrings Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-binary-substrings
Tested Python solution for LeetCode 696 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 696, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/count-binary-substrings/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 696 # by problem number
lcpy gen -s count_binary_substrings # by problem name
```
## Problem
Given a binary string `s`, return the number of non-empty substrings that have the same number of `0`'s and `1`'s, and all the `0`'s and all the `1`'s in these substrings are grouped consecutively.
Substrings that occur multiple times are counted the number of times they occur.
### Examples
```
Input: s = "00110011"
Output: 6
Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01".
Notice that some of these substrings repeat and are counted the number of times they occur.
Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
```
```
Input: s = "10101"
Output: 4
Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
```
### Constraints
* 1 \<= s.length \<= 10^5
* s\[i] is either '0' or '1'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_binary_substrings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_binary_substrings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_binary_substrings(self, s: str) -> int:
prev = 0
cur = 1
total = 0
for i in range(1, len(s)):
if s[i] == s[i - 1]:
cur += 1
else:
total += min(prev, cur)
prev = cur
cur = 1
total += min(prev, cur)
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Count the Number of Complete Components
Source: https://leetcode-py.wisl.dev/problems/count-complete-components
Tested Python solution for LeetCode 2685 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2685, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/count-complete-components/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2685 # by problem number
lcpy gen -s count_complete_components # by problem name
```
## Problem
You are given an integer `n`. There is an **undirected** graph with `n` vertices, numbered from `0` to `n - 1`. You are given a 2D integer array `edges` where `edges[i] = [ai, bi]` denotes that there exists an **undirected** edge connecting vertices `ai` and `bi`.
Return *the number of **complete connected components** of the graph*.
A **connected component** is a subgraph of a graph in which there exists a path between any two vertices, and no vertex of the subgraph shares an edge with a vertex outside of the subgraph.
A connected component is said to be **complete** if there exists an edge between every pair of its vertices.
### Examples

```
Input: n = 6, edges = [[0,1],[0,2],[1,2],[3,4]]
Output: 3
Explanation: From the picture above, one can see that all of the components of this graph are complete.
```

```
Input: n = 6, edges = [[0,1],[0,2],[1,2],[3,4],[3,5]]
Output: 1
Explanation: The component containing vertices 0, 1, and 2 is complete since there is an edge between every pair of two vertices. On the other hand, the component containing vertices 3, 4, and 5 is not complete since there is no edge between vertices 4 and 5. Thus, the number of complete components in this graph is 1.
```
### Constraints
* 1 \<= n \<= 50
* 0 \<= edges.length \<= n \* (n - 1) / 2
* edges\[i].length == 2
* 0 \<= a\i\, b\i\ \<= n - 1
* a\i\ != b\i\
* There are no repeated edges.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_complete_components/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_complete_components/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + e * alpha(n))
# Space: O(n)
def count_complete_components(self, n: int, edges: list[list[int]]) -> int:
parent = list(range(n))
size = [1] * n
edge_count = [0] * n
def find(x: int) -> int:
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
for a, b in edges:
ra, rb = find(a), find(b)
if ra != rb:
if size[ra] < size[rb]:
ra, rb = rb, ra
parent[rb] = ra
size[ra] += size[rb]
edge_count[ra] += edge_count[rb] + 1
else:
edge_count[ra] += 1
complete = 0
for v in range(n):
if find(v) == v and edge_count[v] == size[v] * (size[v] - 1) // 2:
complete += 1
return complete
```
## Complexity
| Time | Space |
| -------------------- | ----- |
| O(n + e \* alpha(n)) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Complete Tree Nodes Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-complete-tree-nodes
Tested Python solution for LeetCode 222 with 32 pytest cases. Generate a practice environment with lcpy.
LeetCode 222, [Medium](/catalog/medium). Topics: [Binary Search](/catalog/topics/binary-search), [Bit Manipulation](/catalog/topics/bit-manipulation), [Tree](/catalog/topics/tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/count-complete-tree-nodes/description/).
Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 222 # by problem number
lcpy gen -s count_complete_tree_nodes # by problem name
```
## Problem
Given the `root` of a **complete** binary tree, return the number of the nodes in the tree.
According to Wikipedia's definition of a complete binary tree, every level, except possibly the last, is completely filled in a complete binary tree, and all nodes in the last level are as far left as possible. It can have between `1` and `2^h` nodes inclusive at the last level `h`.
Design an algorithm that runs in less than `O(n)` time complexity.
### Examples

```
Input: root = [1,2,3,4,5,6]
Output: 6
```
```
Input: root = []
Output: 0
```
```
Input: root = [1]
Output: 1
```
### Constraints
* The number of nodes in the tree is in the range `[0, 5 * 10^4]`.
* `0 <= Node.val <= 5 * 10^4`
* The tree is guaranteed to be **complete**.
**Follow up:** Design an algorithm that runs in less than `O(n)` time complexity.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_complete_tree_nodes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_complete_tree_nodes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(log^2 n)
# Space: O(1)
def count_nodes(self, root: TreeNode[int] | None) -> int:
if root is None:
return 0
left_depth = 0
node = root
while node.left is not None:
left_depth += 1
node = node.left
def exists(index: int) -> bool:
current = root
for shift in range(left_depth - 1, -1, -1):
if current is None:
return False
current = current.right if (index >> shift) & 1 else current.left
return current is not None
low, high = 1, 1 << left_depth
while low < high:
mid = (low + high + 1) // 2
if exists(mid - 1):
low = mid
else:
high = mid - 1
return (1 << left_depth) - 1 + low
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(log^2 n) | O(1) |
## Tags
# Count Days Without Meetings Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-days-without-meetings
Tested Python solution for LeetCode 3169 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 3169, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/count-days-without-meetings/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3169 # by problem number
lcpy gen -s count_days_without_meetings # by problem name
```
## Problem
You are given a positive integer `days` representing the total number of days an employee is available for work (starting from day 1). You are also given a 2D array `meetings` of size `n` where, `meetings[i] = [starti, endi]` represents the starting and ending days of meeting `i` (inclusive).
Return the count of days when the employee is available for work but no meetings are scheduled.
**Note:** The meetings may overlap.
### Examples
```
Input: days = 10, meetings = [[5,7],[1,3],[9,10]]
Output: 2
```
**Explanation:** There is no meeting scheduled on the 4th and 8th days.
```
Input: days = 5, meetings = [[2,4],[1,3]]
Output: 1
```
**Explanation:** There is no meeting scheduled on the 5th day.
```
Input: days = 6, meetings = [[1,6]]
Output: 0
```
**Explanation:** Meetings are scheduled for all working days.
### Constraints
* `1 <= days <= 10^9`
* `1 <= meetings.length <= 10^5`
* `meetings[i].length == 2`
* `1 <= meetings[i][0] <= meetings[i][1] <= days`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_days_without_meetings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_days_without_meetings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n) for sorting
def count_days(self, days: int, meetings: list[list[int]]) -> int:
meetings.sort()
free = 0
last = 0
for start, end in meetings:
if start > last:
free += start - last - 1
last = max(last, end)
return free + days - last
```
## Complexity
| Time | Space |
| ---------- | ---------------- |
| O(n log n) | O(n) for sorting |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Good Nodes in Binary Tree
Source: https://leetcode-py.wisl.dev/problems/count-good-nodes-in-binary-tree
Tested Python solution for LeetCode 1448 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 1448, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/count-good-nodes-in-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1448 # by problem number
lcpy gen -s count_good_nodes_in_binary_tree # by problem name
```
## Problem
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.
Return the number of **good** nodes in the binary tree.
### Examples

```
Input: root = [3,1,4,3,null,1,5]
Output: 4
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.
```

```
Input: root = [3,3,null,4,2]
Output: 3
Explanation: Node 2 -> (3,3,2) is not good, because "3" is higher than it.
```
```
Input: root = [1]
Output: 1
Explanation: Root is considered as good.
```
### Constraints
* The number of nodes in the binary tree is in the range `[1, 10^5]`.
* Each node's value is between `[-10^4, 10^4]`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_good_nodes_in_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_good_nodes_in_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h) - recursion stack, h = tree height
def good_nodes(self, root: TreeNode[int] | None) -> int:
if root is None:
return 0
def dfs(node: TreeNode[int], max_so_far: int) -> int:
good = 1 if node.val >= max_so_far else 0
next_max = max(max_so_far, node.val)
total = good
if node.left is not None:
total += dfs(node.left, next_max)
if node.right is not None:
total += dfs(node.right, next_max)
return total
return dfs(root, root.val)
```
## Complexity
| Time | Space |
| ---- | --------------------------------------- |
| O(n) | O(h) - recursion stack, h = tree height |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Count Number of Bad Pairs Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-number-of-bad-pairs
Tested Python solution for LeetCode 2364 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2364, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/count-number-of-bad-pairs/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2364 # by problem number
lcpy gen -s count_number_of_bad_pairs # by problem name
```
## Problem
You are given a \0-indexed\ integer array \nums\. A pair of indices \(i, j)\ is a \bad pair\ if \i \< j\ and \j - i != nums\[j] - nums\[i]\.
Return \the total number of \bad pairs\ in \\nums\.
### Examples
```
Input: nums = [4,1,3,3]
Output: 5
```
**Explanation:** The pair (0, 1) is a bad pair since 1 - 0 != 1 - 4.
The pair (0, 2) is a bad pair since 2 - 0 != 3 - 4, 2 != -1.
The pair (0, 3) is a bad pair since 3 - 0 != 3 - 4, 3 != -1.
The pair (1, 2) is a bad pair since 2 - 1 != 3 - 1, 1 != 2.
The pair (2, 3) is a bad pair since 3 - 2 != 3 - 3, 1 != 0.
There are a total of 5 bad pairs, so we return 5.
```
Input: nums = [1,2,3,4,5]
Output: 0
```
**Explanation:** There are no bad pairs.
### Constraints
* 1 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_bad_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_bad_pairs/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def count_bad_pairs(self, nums: list[int]) -> int:
good = 0
seen: dict[int, int] = {}
for i, num in enumerate(nums):
key = num - i
good += seen.get(key, 0)
seen[key] = seen.get(key, 0) + 1
n = len(nums)
return n * (n - 1) // 2 - good
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Number of Maximum Bitwise-OR Subsets
Source: https://leetcode-py.wisl.dev/problems/count-number-of-maximum-bitwise-or-subsets
Tested Python solution for LeetCode 2044 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2044, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/count-number-of-maximum-bitwise-or-subsets/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2044 # by problem number
lcpy gen -s count_number_of_maximum_bitwise_or_subsets # by problem name
```
## Problem
Given an integer array `nums`, find the **maximum** possible **bitwise OR** of a subset of `nums` and return *the **number of different non-empty subsets** with the maximum bitwise OR*.
An array `a` is a **subset** of an array `b` if `a` can be obtained from `b` by deleting some (possibly zero) elements of `b`. Two subsets are considered **different** if the indices of the elements chosen are different.
The bitwise OR of an array `a` is equal to `a[0] OR a[1] OR ... OR a[a.length - 1]` (**0-indexed**).
### Examples
```
Input: nums = [3,1]
Output: 2
```
**Explanation:** The maximum possible bitwise OR of a subset is 3. There are 2 subsets with a bitwise OR of 3:
* `[3]`
* `[3,1]`
```
Input: nums = [2,2,2]
Output: 7
```
**Explanation:** All non-empty subsets of `[2,2,2]` have a bitwise OR of 2. There are 2^3 - 1 = 7 total subsets.
```
Input: nums = [3,2,1,5]
Output: 6
```
**Explanation:** The maximum possible bitwise OR of a subset is 7. There are 6 subsets with a bitwise OR of 7:
* `[3,5]`
* `[3,1,5]`
* `[3,2,5]`
* `[3,2,1,5]`
* `[2,5]`
* `[2,1,5]`
### Constraints
* `1 <= nums.length <= 16`
* `1 <= nums[i] <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_maximum_bitwise_or_subsets/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_maximum_bitwise_or_subsets/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * max_or) where max_or <= 2^17 for nums[i] <= 10^5
# Space: O(max_or)
def count_max_or_subsets(self, nums: list[int]) -> int:
target = 0
for num in nums:
target |= num
# counts[acc] = number of subsets (possibly empty) with OR value acc
counts = [1] + [0] * target
for num in nums:
for acc in range(target, -1, -1):
if counts[acc]:
counts[acc | num] += counts[acc]
return counts[target]
```
## Complexity
| Time | Space |
| ------------------------------------------------------------ | ---------- |
| O(n \* max\_or) where max\_or \<= 2^17 for nums\[i] \<= 10^5 | O(max\_or) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Number of Nice Subarrays Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-number-of-nice-subarrays
Tested Python solution for LeetCode 1248 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1248, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Sliding Window](/catalog/topics/sliding-window), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/count-number-of-nice-subarrays/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1248 # by problem number
lcpy gen -s count_number_of_nice_subarrays # by problem name
```
## Problem
Given an array of integers `nums` and an integer `k`. A continuous subarray is called **nice** if there are `k` odd numbers on it.
Return *the number of **nice** sub-arrays*.
### Examples
```
Input: nums = [1,1,2,1,1], k = 3
Output: 2
Explanation: The only sub-arrays with 3 odd numbers are [1,1,2,1] and [1,2,1,1].
```
```
Input: nums = [2,4,6], k = 1
Output: 0
Explanation: There are no odd numbers in the array.
```
```
Input: nums = [2,2,2,1,2,2,1,2,2,2], k = 2
Output: 16
```
### Constraints
* `1 <= nums.length <= 50000`
* `1 <= nums[i] <= 10^5`
* `1 <= k <= nums.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_nice_subarrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_nice_subarrays/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(nums))
# Space: O(len(nums))
def number_of_subarrays(self, nums: list[int], k: int) -> int:
prefix: dict[int, int] = {0: 1}
odds = 0
count = 0
for num in nums:
odds += num % 2
count += prefix.get(odds - k, 0)
prefix[odds] = prefix.get(odds, 0) + 1
return count
```
## Complexity
| Time | Space |
| ------------ | ------------ |
| O(len(nums)) | O(len(nums)) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Number of Teams Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-number-of-teams
Tested Python solution for LeetCode 1395 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 1395, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree). [View on LeetCode](https://leetcode.com/problems/count-number-of-teams/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1395 # by problem number
lcpy gen -s count_number_of_teams # by problem name
```
## Problem
There are `n` soldiers standing in a line. Each soldier is assigned a **unique** `rating` value.
You have to form a team of 3 soldiers amongst them under the following rules:
* Choose 3 soldiers with index (`i`, `j`, `k`) with rating (`rating[i]`, `rating[j]`, `rating[k]`).
* A team is valid if: `rating[i] < rating[j] < rating[k]` or `rating[i] > rating[j] > rating[k]` where (`0 <= i < j < k < n`).
Return the number of teams you can form given the conditions. (soldiers can be part of multiple teams).
### Examples
```
Input: rating = [2,5,3,4,1]
Output: 3
Explanation: We can form three teams given the conditions. (2,3,4), (5,4,1), (5,3,1).
```
```
Input: rating = [2,1,3]
Output: 0
Explanation: We can't form any team given the conditions.
```
```
Input: rating = [1,2,3,4]
Output: 4
```
### Constraints
* `n == rating.length`
* `3 <= n <= 1000`
* `1 <= rating[i] <= 10^5`
* All the integers in `rating` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_teams/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_number_of_teams/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(1)
def num_teams(self, rating: list[int]) -> int:
n = len(rating)
total = 0
for mid in range(n):
less_before = sum(rating[i] < rating[mid] for i in range(mid))
greater_before = mid - less_before
less_after = sum(rating[k] < rating[mid] for k in range(mid + 1, n))
greater_after = n - mid - 1 - less_after
total += less_before * greater_after + greater_before * less_after
return total
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Numbers with Unique Digits
Source: https://leetcode-py.wisl.dev/problems/count-numbers-with-unique-digits
Tested Python solution for LeetCode 357 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 357, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/count-numbers-with-unique-digits/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 357 # by problem number
lcpy gen -s count_numbers_with_unique_digits # by problem name
```
## Problem
Given an integer `n`, return the count of all numbers with unique digits, `x`, where `0 <= x < 10^n`.
### Examples
```
Input: n = 2
Output: 91
```
**Explanation:** The answer should be the total numbers in the range of 0 \<= x \< 100, excluding 11,22,33,44,55,66,77,88,99.
```
Input: n = 0
Output: 1
```
### Constraints
* 0 \<= n \<= 8
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_numbers_with_unique_digits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_numbers_with_unique_digits/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_numbers_with_unique_digits(self, n: int) -> int:
if n == 0:
return 1
total = 10
count = 9
available = 9
for _ in range(2, n + 1):
count *= available
available -= 1
total += count
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Count Odd Numbers in an Interval Range
Source: https://leetcode-py.wisl.dev/problems/count-odd-numbers-in-an-interval-range
Tested Python solution for LeetCode 1523 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1523, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/count-odd-numbers-in-an-interval-range/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1523 # by problem number
lcpy gen -s count_odd_numbers_in_an_interval_range # by problem name
```
## Problem
Given two non-negative integers `low` and `high`. Return the count of odd numbers between `low` and `high` (inclusive).
### Examples
```
Input: low = 3, high = 7
Output: 3
Explanation: The odd numbers between 3 and 7 are [3,5,7].
```
```
Input: low = 8, high = 10
Output: 1
Explanation: The odd numbers between 8 and 10 are [9].
```
### Constraints
* 0 \<= low \<= high \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_odd_numbers_in_an_interval_range/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_odd_numbers_in_an_interval_range/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def count_odds(self, low: int, high: int) -> int:
return (high + 1) // 2 - low // 2
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count of Matches in Tournament Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-of-matches-in-tournament
Tested Python solution for LeetCode 1688 with 36 pytest cases. Generate a practice environment with lcpy.
LeetCode 1688, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/count-of-matches-in-tournament/description/).
Generate this problem as a practice environment: tested reference solution, 36 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1688 # by problem number
lcpy gen -s count_of_matches_in_tournament # by problem name
```
## Problem
You are given an integer `n`, the number of teams in a tournament that has strange rules:
* If the current number of teams is **even**, each team gets paired with another team. A total of `n / 2` matches are played, and `n / 2` teams advance to the next round.
* If the current number of teams is **odd**, one team randomly advances in the tournament, and the rest gets paired. A total of `(n - 1) / 2` matches are played, and `(n - 1) / 2 + 1` teams advance to the next round.
Return *the number of matches played in the tournament until a winner is decided.*
### Examples
```
Input: n = 7
Output: 6
Explanation: Details of the tournament:
- 1st Round: Teams = 7, Matches = 3, and 4 teams advance.
- 2nd Round: Teams = 4, Matches = 2, and 2 teams advance.
- 3rd Round: Teams = 2, Matches = 1, and 1 team is declared the winner.
Total number of matches = 3 + 2 + 1 = 6.
```
```
Input: n = 14
Output: 13
Explanation: Details of the tournament:
- 1st Round: Teams = 14, Matches = 7, and 7 teams advance.
- 2nd Round: Teams = 7, Matches = 3, and 4 teams advance.
- 3rd Round: Teams = 4, Matches = 2, and 2 teams advance.
- 4th Round: Teams = 2, Matches = 1, and 1 team is declared the winner.
Total number of matches = 7 + 3 + 2 + 1 = 13.
```
### Constraints
* `1 <= n <= 200`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_of_matches_in_tournament/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_of_matches_in_tournament/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def number_of_matches(self, n: int) -> int:
# Each match eliminates exactly one team, and all but the winner are
# eliminated, so n - 1 matches are played regardless of pairing rules.
return n - 1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count of Range Sum Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/count-of-range-sum
Tested Python solution for LeetCode 327 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 327, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree), Merge Sort, [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/count-of-range-sum/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 327 # by problem number
lcpy gen -s count_of_range_sum # by problem name
```
## Problem
\Given an integer array \nums\ and two integers \lower\ and \upper\, return \the number of range sums that lie in\ \\[lower, upper]\ \inclusive\.\
Range sum \S(i, j)\ is defined as the sum of the elements in \nums\ between indices \i\ and \j\ inclusive, where \i \<= j\.\
1 \<= nums.length \<= 10\5\\\-2\31\ \<= nums\[i] \<= 2\31\ - 1\\-10\5\ \<= lower \<= upper \<= 10\5\\\word\ and a \non-negative\ integer \k\.
Return the total number of \substrings\ of \word\ that contain every vowel (\'a'\, \'e'\, \'i'\, \'o'\, and \'u'\) \at least\ once and \exactly\ \k\ consonants.
### Examples
```
Input: word = "aeioqq", k = 1
Output: 0
Explanation: There is no substring with every vowel.
```
```
Input: word = "aeiou", k = 0
Output: 1
Explanation: The only substring with every vowel and zero consonants is word[0..4], which is "aeiou".
```
```
Input: word = "ieaouqqieaouqq", k = 1
Output: 3
Explanation: The substrings with every vowel and one consonant are:
- word[0..5], which is "ieaouq".
- word[6..11], which is "qieaou".
- word[7..12], which is "ieaouq".
```
### Constraints
* 5 \<= word.length \<= 2 \* 10^5
* word consists only of lowercase English letters.
* 0 \<= k \<= word.length - 5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_of_substrings_containing_every_vowel_and_k_consonants_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_of_substrings_containing_every_vowel_and_k_consonants_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_of_substrings(self, word: str, k: int) -> int:
def at_least(min_k: int) -> int:
vowel_counts: dict[str, int] = {}
consonants = 0
total = 0
left = 0
for right, ch in enumerate(word):
if ch in "aeiou":
vowel_counts[ch] = vowel_counts.get(ch, 0) + 1
else:
consonants += 1
while len(vowel_counts) == 5 and consonants >= min_k:
total += len(word) - right
left_ch = word[left]
if left_ch in "aeiou":
vowel_counts[left_ch] -= 1
if vowel_counts[left_ch] == 0:
del vowel_counts[left_ch]
else:
consonants -= 1
left += 1
return total
return at_least(k) - at_least(k + 1)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Different Palindromic Subsequences
Source: https://leetcode-py.wisl.dev/problems/count-palindromic-subsequences
Tested Python solution for LeetCode 730 with 35 pytest cases. Generate a practice environment with lcpy.
LeetCode 730, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/count-palindromic-subsequences/description/).
Generate this problem as a practice environment: tested reference solution, 35 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 730 # by problem number
lcpy gen -s count_palindromic_subsequences # by problem name
```
## Problem
Given a string `s`, return *the number of different non-empty palindromic subsequences in* `s`. Since the answer may be very large, return it **modulo** `10^9 + 7`.
A **subsequence** of a string is obtained by deleting zero or more characters from the string.
A sequence is palindromic if it is equal to the sequence reversed.
Two sequences `a1, a2, ...` and `b1, b2, ...` are different if there is some `i` for which `ai != bi`.
### Examples
```
Input: s = "bccb"
Output: 6
Explanation: The 6 different non-empty palindromic subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'.
Note that 'bcb' is counted only once, even though it occurs twice.
```
```
Input: s = "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba"
Output: 104860361
Explanation: There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 10^9 + 7.
```
### Constraints
* `1 <= s.length <= 1000`
* `s[i]` is either `'a'`, `'b'`, `'c'`, or `'d'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_palindromic_subsequences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_palindromic_subsequences/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_left, bisect_right
class Solution:
# Time: O(n^2 log n)
# Space: O(n^2)
def count_palindromic_subsequences(self, s: str) -> int:
mod = 1_000_000_007
n = len(s)
pos: dict[str, list[int]] = {c: [] for c in "abcd"}
for i, c in enumerate(s):
pos[c].append(i)
# dp[i][j]: number of distinct palindromic subsequences in s[i..j]
dp = [[0] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
dp[i][i] = 1
for j in range(i + 1, n):
inner = dp[i + 1][j - 1] if i + 1 <= j - 1 else 0
if s[i] != s[j]:
dp[i][j] = (dp[i + 1][j] + dp[i][j - 1] - inner) % mod
continue
# s[i] == s[j] == c: every palindrome either has no c at the
# ends (counted twice) or is wrapped in a new c layer.
lst = pos[s[i]]
k = lst[bisect_right(lst, i)] # first c strictly inside (i, j)
if k >= j:
dp[i][j] = (2 * inner + 2) % mod
continue
h = lst[bisect_left(lst, j) - 1] # last c strictly inside (i, j)
if k == h:
dp[i][j] = (2 * inner + 1) % mod
else:
mid = dp[k + 1][h - 1] if k + 1 <= h - 1 else 0
dp[i][j] = (2 * inner - mid) % mod
return dp[0][n - 1]
```
## Complexity
| Time | Space |
| ------------ | ------ |
| O(n^2 log n) | O(n^2) |
## Tags
# Count Prefix and Suffix Pairs I
Source: https://leetcode-py.wisl.dev/problems/count-prefix-and-suffix-pairs-i
Tested Python solution for LeetCode 3042 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 3042, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Trie](/catalog/topics/trie), Rolling Hash, [String Matching](/catalog/topics/string-matching), [Hash Function](/catalog/topics/hash-function). [View on LeetCode](https://leetcode.com/problems/count-prefix-and-suffix-pairs-i/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3042 # by problem number
lcpy gen -s count_prefix_and_suffix_pairs_i # by problem name
```
## Problem
You are given a **0-indexed** string array `words`.
Let's define a **boolean** function `isPrefixAndSuffix` that takes two strings, `str1` and `str2`:
* `isPrefixAndSuffix(str1, str2)` returns `true` if `str1` is **both** a prefix and a suffix of `str2`, and `false` otherwise.
For example, `isPrefixAndSuffix("aba", "ababa")` is `true` because `"aba"` is a prefix of `"ababa"` and also a suffix, but `isPrefixAndSuffix("abc", "abcd")` is `false`.
Return *an integer denoting the **number** of index pairs* `(i, j)` *such that* `i < j` *and* `isPrefixAndSuffix(words[i], words[j])` *is* `true`.
### Examples
```
Input: words = ["a","aba","ababa","aa"]
Output: 4
Explanation: In this example, the counted index pairs are:
i = 0 and j = 1 because isPrefixAndSuffix("a", "aba") is true.
i = 0 and j = 2 because isPrefixAndSuffix("a", "ababa") is true.
i = 0 and j = 3 because isPrefixAndSuffix("a", "aa") is true.
i = 1 and j = 2 because isPrefixAndSuffix("aba", "ababa") is true.
Therefore, the answer is 4.
```
```
Input: words = ["pa","papa","ma","mama"]
Output: 2
Explanation: In this example, the counted index pairs are:
i = 0 and j = 1 because isPrefixAndSuffix("pa", "papa") is true.
i = 2 and j = 3 because isPrefixAndSuffix("ma", "mama") is true.
Therefore, the answer is 2.
```
```
Input: words = ["abab","ab"]
Output: 0
Explanation: In this example, the only valid index pair is i = 0 and j = 1, and isPrefixAndSuffix("abab", "ab") is false.
Therefore, the answer is 0.
```
### Constraints
* 1 \<= words.length \<= 50
* 1 \<= words\[i].length \<= 10
* words\[i] consists only of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_prefix_and_suffix_pairs_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_prefix_and_suffix_pairs_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m^2)
# Space: O(1)
def count_prefix_suffix_pairs(self, words: list[str]) -> int:
count = 0
for i, prefix in enumerate(words):
for suffix in words[i + 1 :]:
if suffix.startswith(prefix) and suffix.endswith(prefix):
count += 1
return count
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(n \* m^2) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Prefix and Suffix Pairs II
Source: https://leetcode-py.wisl.dev/problems/count-prefix-and-suffix-pairs-ii
Tested Python solution for LeetCode 3045 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 3045, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Trie](/catalog/topics/trie), Rolling Hash, [String Matching](/catalog/topics/string-matching), [Hash Function](/catalog/topics/hash-function), Z Algorithm. [View on LeetCode](https://leetcode.com/problems/count-prefix-and-suffix-pairs-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3045 # by problem number
lcpy gen -s count_prefix_and_suffix_pairs_ii # by problem name
```
## Problem
You are given a 0-indexed string array words.
Let's define a boolean function isPrefixAndSuffix that takes two strings, str1 and str2:
* isPrefixAndSuffix(str1, str2) returns true if str1 is both a prefix and a suffix of str2, and false otherwise.
For example, isPrefixAndSuffix("aba", "ababa") is true because "aba" is a prefix of "ababa" and also a suffix, but isPrefixAndSuffix("abc", "abcd") is false.
Return an integer denoting the number of index pairs (i, j) such that i \< j, and isPrefixAndSuffix(words\[i], words\[j]) is true.
### Examples
```
Input: words = ["a","aba","ababa","aa"]
Output: 4
```
**Explanation:** The counted index pairs are (0, 1), (0, 2), (0, 3) and (1, 2).
```
Input: words = ["pa","papa","ma","mama"]
Output: 2
```
**Explanation:** The counted index pairs are (0, 1) and (2, 3).
```
Input: words = ["abab","ab"]
Output: 0
```
### Constraints
* 1 \<= words.length \<= 10^5
* 1 \<= words\[i].length \<= 10^5
* words\[i] consists only of lowercase English letters.
* The sum of the lengths of all words\[i] does not exceed 5 \* 10^5.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_prefix_and_suffix_pairs_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_prefix_and_suffix_pairs_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from typing import Any
class Solution:
# Time: O(total chars), each character pair inserted/visited once
# Space: O(total chars) for the paired trie
def count_prefix_and_suffix_pairs(self, words: list[str]) -> int:
root: dict[Any, Any] = {}
total = 0
for word in words:
node: dict[Any, Any] = root
length = len(word)
for i in range(length):
key = (word[i], word[length - 1 - i])
if key not in node:
node[key] = {}
node = node[key]
total += node.get("", 0)
node[""] = node.get("", 0) + 1
return total
```
## Complexity
| Time | Space |
| --------------------------------------------------------- | ---------------------------------- |
| O(total chars), each character pair inserted/visited once | O(total chars) for the paired trie |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Primes Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/count-primes
Tested Python solution for LeetCode 204 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 204, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Enumeration](/catalog/topics/enumeration), [Number Theory](/catalog/topics/number-theory), Primality Test, Sieve Theory, Prime Number Sieve. [View on LeetCode](https://leetcode.com/problems/count-primes/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 204 # by problem number
lcpy gen -s count_primes # by problem name
```
## Problem
Given an integer `n`, return *the number of prime numbers that are strictly less than* `n`.
### Examples
```
Input: n = 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
```
```
Input: n = 0
Output: 0
```
```
Input: n = 1
Output: 0
```
### Constraints
* 0 \<= n \<= 5 \* 10\6\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_primes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_primes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log log n)
# Space: O(n)
def count_primes(self, n: int) -> int:
if n < 3:
return 0
is_prime = [True] * n
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for multiple in range(i * i, n, i):
is_prime[multiple] = False
return sum(is_prime)
```
## Complexity
| Time | Space |
| -------------- | ----- |
| O(n log log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Servers that Communicate Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-servers-that-communicate
Tested Python solution for LeetCode 1267 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1267, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/count-servers-that-communicate/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1267 # by problem number
lcpy gen -s count_servers_that_communicate # by problem name
```
## Problem
You are given a map of a server center, represented as a m \* n integer matrix grid, where 1 means that on that cell there is a server and 0 means that it is no server. Two servers are said to communicate if they are on the same row or on the same column.
Return the number of servers that communicate with any other server.
### Examples

```
Input: grid = [[1,0],[0,1]]
Output: 0
Explanation: No servers can communicate with others.
```

```
Input: grid = [[1,0],[1,1]]
Output: 3
Explanation: All three servers can communicate with at least one other server.
```

```
Input: grid = [[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]
Output: 4
Explanation: The two servers in the first row can communicate with each other. The two servers in the third column can communicate with each other. The server at right bottom corner can't communicate with any other server.
```
### Constraints
* m == grid.length
* n == grid\[i].length
* 1 \<= m \<= 250
* 1 \<= n \<= 250
* grid\[i]\[j] == 0 or 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_servers_that_communicate/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_servers_that_communicate/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def count_servers(self, grid: list[list[int]]) -> int:
m, n = len(grid), len(grid[0])
rows = [sum(row) for row in grid]
cols = [sum(grid[i][j] for i in range(m)) for j in range(n)]
return sum(
grid[i][j] == 1 and (rows[i] > 1 or cols[j] > 1) for i in range(m) for j in range(n)
)
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Count of Smaller Numbers After Self
Source: https://leetcode-py.wisl.dev/problems/count-smaller-numbers-after-self
Tested Python solution for LeetCode 315 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 315, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree), Merge Sort, [Ordered Set](/catalog/topics/ordered-set), Treap. [View on LeetCode](https://leetcode.com/problems/count-smaller-numbers-after-self/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 315 # by problem number
lcpy gen -s count_smaller_numbers_after_self # by problem name
```
## Problem
Given an integer array `nums`, return an integer array `counts` where `counts[i]` is the number of smaller elements to the right of `nums[i]`.
### Examples
```
Input: nums = [5,2,6,1]
Output: [2,1,1,0]
```
**Explanation:**
To the right of 5 there are **2** smaller elements (2 and 1).
To the right of 2 there is only **1** smaller element (1).
To the right of 6 there is **1** smaller element (1).
To the right of 1 there is **0** smaller element.
```
Input: nums = [-1]
Output: [0]
```
```
Input: nums = [-1,-1]
Output: [0,0]
```
### Constraints
* 1 \<= nums.length \<= 10^5
* -10^4 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_smaller_numbers_after_self/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_smaller_numbers_after_self/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def count_smaller(self, nums: list[int]) -> list[int]:
counts = [0] * len(nums)
indices = list(range(len(nums)))
def merge_sort(lo: int, hi: int) -> None:
if hi - lo <= 1:
return
mid = (lo + hi) // 2
merge_sort(lo, mid)
merge_sort(mid, hi)
merged: list[int] = []
i, j = lo, mid
while i < mid and j < hi:
if nums[indices[j]] < nums[indices[i]]:
merged.append(indices[j])
j += 1
else:
counts[indices[i]] += j - mid
merged.append(indices[i])
i += 1
while i < mid:
counts[indices[i]] += j - mid
merged.append(indices[i])
i += 1
while j < hi:
merged.append(indices[j])
j += 1
indices[lo:hi] = merged
merge_sort(0, len(nums))
return counts
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
# Count Square Submatrices with All Ones
Source: https://leetcode-py.wisl.dev/problems/count-square-submatrices-with-all-ones
Tested Python solution for LeetCode 1277 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1277, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/count-square-submatrices-with-all-ones/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1277 # by problem number
lcpy gen -s count_square_submatrices_with_all_ones # by problem name
```
## Problem
Given a m \* n matrix of ones and zeros, return how many square submatrices have all ones.
### Examples
```
Input: matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
Output: 15
Explanation:
There are 10 squares of side 1.
There are 4 squares of side 2.
There is 1 square of side 3.
Total number of squares = 10 + 4 + 1 = 15.
```
```
Input: matrix =
[
[1,0,1],
[1,1,0],
[1,1,0]
]
Output: 7
Explanation:
There are 6 squares of side 1.
There is 1 square of side 2.
Total number of squares = 6 + 1 = 7.
```
### Constraints
* 1 \<= arr.length \<= 300
* 1 \<= arr\[0].length \<= 300
* 0 \<= arr\[i]\[j] \<= 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_square_submatrices_with_all_ones/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_square_submatrices_with_all_ones/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def count_squares(self, matrix: list[list[int]]) -> int:
m, n = len(matrix), len(matrix[0])
total = 0
for i in range(m):
for j in range(n):
if matrix[i][j] and i > 0 and j > 0:
matrix[i][j] = 1 + min(matrix[i - 1][j], matrix[i][j - 1], matrix[i - 1][j - 1])
total += matrix[i][j]
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Strictly Increasing Subarrays
Source: https://leetcode-py.wisl.dev/problems/count-strictly-increasing-subarrays
Tested Python solution for LeetCode 2393 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2393, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/count-strictly-increasing-subarrays/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2393 # by problem number
lcpy gen -s count_strictly_increasing_subarrays # by problem name
```
## Problem
You are given an array `nums` consisting of **positive** integers.
Return *the number of **subarrays** of* `nums` *that are in **strictly increasing** order*.
A **subarray** is a **contiguous** part of an array.
### Examples
```
Input: nums = [1,3,5,4,4,6]
Output: 10
Explanation: The strictly increasing subarrays are the following:
- Subarrays of length 1: [1], [3], [5], [4], [4], [6].
- Subarrays of length 2: [1,3], [3,5], [4,6].
- Subarrays of length 3: [1,3,5].
The total number of subarrays is 6 + 3 + 1 = 10.
```
```
Input: nums = [1,2,3,4,5]
Output: 15
Explanation: Every subarray is strictly increasing. There are 15 possible subarrays that we can take.
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= nums[i] <= 10^6`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_strictly_increasing_subarrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_strictly_increasing_subarrays/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_strictly_increasing(self, nums: list[int]) -> int:
total = 0
run = 0
prev = 0
for i, x in enumerate(nums):
if i > 0 and x > prev:
run += 1
else:
run = 1
total += run
prev = x
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Sub Islands Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/count-sub-islands
Tested Python solution for LeetCode 1905 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1905, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/count-sub-islands/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1905 # by problem number
lcpy gen -s count_sub_islands # by problem name
```
## Problem
You are given two `m x n` binary matrices `grid1` and `grid2` containing only `0`s (representing water) and `1`s (representing land). An *island* is a group of `1`s connected **4-directionally** (horizontal or vertical). Any cells outside of the grid are considered water cells.
An island in `grid2` is considered a *sub-island* if there is an island in `grid1` that contains **all** the cells that make up **this** island in `grid2`.
Return the number of islands in `grid2` that are considered *sub-islands*.
### Examples

```
Input: grid1 = [[1,1,1,0,0],[0,1,1,1,1],[0,0,0,0,0],[1,0,0,0,0],[1,1,0,1,1]], grid2 = [[1,1,1,0,0],[0,0,1,1,1],[0,1,0,0,0],[1,0,1,1,0],[0,1,0,1,0]]
Output: 3
Explanation: The grid on the left is grid1 and the grid on the right is grid2. The 1s colored red in grid2 are those considered to be part of a sub-island. There are three sub-islands.
```

```
Input: grid1 = [[1,0,1,0,1],[1,1,1,1,1],[0,0,0,0,0],[1,1,1,1,1],[1,0,1,0,1]], grid2 = [[0,0,0,0,0],[1,1,1,1,1],[0,1,0,1,0],[0,1,0,1,0],[1,0,0,0,1]]
Output: 2
Explanation: The grid on the left is grid1 and the grid on the right is grid2. The 1s colored red in grid2 are those considered to be part of a sub-island. There are two sub-islands.
```
### Constraints
* `m == grid1.length == grid2.length`
* `n == grid1[i].length == grid2[i].length`
* `1 <= m, n <= 500`
* `grid1[i][j]` and `grid2[i][j]` are either `0` or `1`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_sub_islands/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_sub_islands/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def count_sub_islands(self, grid1: list[list[int]], grid2: list[list[int]]) -> int:
rows, cols = len(grid1), len(grid1[0])
count = 0
for r in range(rows):
for c in range(cols):
if grid2[r][c] != 1:
continue
is_sub = True
stack = [(r, c)]
grid2[r][c] = 0
while stack:
cr, cc = stack.pop()
if grid1[cr][cc] != 1:
is_sub = False
for nr, nc in ((cr + 1, cc), (cr - 1, cc), (cr, cc + 1), (cr, cc - 1)):
if 0 <= nr < rows and 0 <= nc < cols and grid2[nr][nc] == 1:
grid2[nr][nc] = 0
stack.append((nr, nc))
if is_sub:
count += 1
return count
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Subarrays Where Max Element Appears at
Source: https://leetcode-py.wisl.dev/problems/count-subarrays-where-max-element-appears-at-least-k-times
Tested Python solution for LeetCode 2962 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2962, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/count-subarrays-where-max-element-appears-at-least-k-times/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2962 # by problem number
lcpy gen -s count_subarrays_where_max_element_appears_at_least_k_times # by problem name
```
## Problem
You are given an integer array `nums` and a positive integer `k`.
Return the number of subarrays where the maximum element of `nums` appears at least `k` times in that subarray.
A subarray is a contiguous sequence of elements within an array.
### Examples
```
Input: nums = [1,3,2,3,3], k = 2
Output: 6
Explanation: The subarrays that contain the element 3 at least 2 times are: [1,3,2,3], [1,3,2,3,3], [3,2,3], [3,2,3,3], [2,3,3] and [3,3].
```
```
Input: nums = [1,4,2,1], k = 3
Output: 0
Explanation: No subarray contains the element 4 at least 3 times.
```
### Constraints
* 1 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= 10^6
* 1 \<= k \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_subarrays_where_max_element_appears_at_least_k_times/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_subarrays_where_max_element_appears_at_least_k_times/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_subarrays(self, nums: list[int], k: int) -> int:
mx = max(nums)
total = 0
count = 0
left = 0
for value in nums:
if value == mx:
count += 1
while count >= k:
if nums[left] == mx:
count -= 1
left += 1
total += left
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Substrings with Only One Distinct Letter
Source: https://leetcode-py.wisl.dev/problems/count-substrings-with-only-one-distinct-letter
Tested Python solution for LeetCode 1180 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 1180, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/count-substrings-with-only-one-distinct-letter/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1180 # by problem number
lcpy gen -s count_substrings_with_only_one_distinct_letter # by problem name
```
## Problem
Given a string `s`, return *the number of substrings that have only **one distinct** letter*.
### Examples
```
Input: s = "aaaba"
Output: 8
Explanation: The substrings with one distinct letter are "aaa", "aa", "a", "b".
"aaa" occurs 1 time.
"aa" occurs 2 times.
"a" occurs 4 times.
"b" occurs 1 time.
So the answer is 1 + 2 + 4 + 1 = 8.
```
```
Input: s = "aaaaaaaaaa"
Output: 55
```
### Constraints
* 1 \<= s.length \<= 1000
* `s` consists of only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_substrings_with_only_one_distinct_letter/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_substrings_with_only_one_distinct_letter/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_letters(self, s: str) -> int:
ans = 0
i = 0
n = len(s)
while i < n:
j = i
while j < n and s[j] == s[i]:
ans += j - i + 1
j += 1
i = j
return ans
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count the Number of Consistent Strings
Source: https://leetcode-py.wisl.dev/problems/count-the-number-of-consistent-strings
Tested Python solution for LeetCode 1684 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1684, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/count-the-number-of-consistent-strings/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1684 # by problem number
lcpy gen -s count_the_number_of_consistent_strings # by problem name
```
## Problem
You are given a string `allowed` consisting of **distinct** characters and an array of strings `words`. A string is **consistent** if all characters in the string appear in the string `allowed`.
Return the number of consistent strings in the array `words`.
### Examples
```
Input: allowed = "ab", words = ["ad","bd","aaab","baa","badab"]
Output: 2
Explanation: Strings "aaab" and "baa" are consistent since they only contain characters 'a' and 'b'.
```
```
Input: allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"]
Output: 7
Explanation: All strings are consistent.
```
```
Input: allowed = "cad", words = ["cc","acd","b","ba","bac","bad","ac","d"]
Output: 4
Explanation: Strings "cc", "acd", "ac", and "d" are consistent.
```
### Constraints
* 1 \<= words.length \<= 10^4
* 1 \<= allowed.length \<= 26
* 1 \<= words\[i].length \<= 10
* The characters in allowed are distinct.
* words\[i] and allowed contain only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_the_number_of_consistent_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_the_number_of_consistent_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m) where n = len(words), m = max word length
# Space: O(1) since allowed is at most 26 characters
def count_consistent_strings(self, allowed: str, words: list[str]) -> int:
allowed_mask = 0
for ch in allowed:
allowed_mask |= 1 << (ord(ch) - ord("a"))
count = 0
for word in words:
word_mask = 0
for ch in word:
word_mask |= 1 << (ord(ch) - ord("a"))
if word_mask | allowed_mask == allowed_mask:
count += 1
return count
```
## Complexity
| Time | Space |
| --------------------------------------------------- | ------------------------------------------- |
| O(n \* m) where n = len(words), m = max word length | O(1) since allowed is at most 26 characters |
## Tags
[NeetCode All](/catalog/neetcode).
# Count the Number of Fair Pairs Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-the-number-of-fair-pairs
Tested Python solution for LeetCode 2563 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2563, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/count-the-number-of-fair-pairs/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2563 # by problem number
lcpy gen -s count_the_number_of_fair_pairs # by problem name
```
## Problem
Given a \0-indexed\ integer array \nums\ of size \n\ and two integers \lower\ and \upper\, return \the number of \fair pairs\\.
A pair \(i, j)\ is \fair\ if:
\0 \<= i \< j \< n\, and\lower \<= nums\[i] + nums\[j] \<= upper\\Let's define a function \countUniqueChars(s)\ that returns the number of unique characters in \s\.\
countUniqueChars(s)\ if \s = "LEETCODE"\ then \"L"\, \"T"\, \"C"\, \"O"\, \"D"\ are the unique characters since they appear only once in \s\, therefore \countUniqueChars(s) = 5\.\Given a string \s\, return the sum of \countUniqueChars(t)\ where \t\ is a substring of \s\. The test cases are generated such that the answer fits in a 32-bit integer.\
Notice that some substrings can be repeated so in this case you have to count the repeated ones too.\
### Examples ``` Input: s = "ABC" Output: 10 Explanation: All possible substrings are: "A","B","C","AB","BC" and "ABC". Every substring is composed with only unique letters. Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10 ``` ``` Input: s = "ABA" Output: 8 Explanation: The same as example 1, except countUniqueChars("ABA") = 1. ``` ``` Input: s = "LEETCODE" Output: 92 ``` ### Constraints * 1 \<= s.length \<= 10^5 * s consists of uppercase English letters only. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_unique_characters_of_all_substrings_of_a_given_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_unique_characters_of_all_substrings_of_a_given_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) (26 alphabet slots) def unique_letter_string(self, s: str) -> int: # Each character contributes to the substrings in which it is the only # occurrence of its letter. For index i with previous occurrence at # prev[i] and next occurrence at next[i], the number of such substrings # is (i - prev[i]) * (next[i] - i). n = len(s) prev = [-1] * n last: dict[str, int] = {} for i, ch in enumerate(s): prev[i] = last.get(ch, -1) last[ch] = i next_pos = [n] * n last = {} for i in range(n - 1, -1, -1): next_pos[i] = last.get(s[i], n) last[s[i]] = i return sum((i - prev[i]) * (next_pos[i] - i) for i in range(n)) ``` ## Complexity | Time | Space | | ---- | ------------------------ | | O(n) | O(1) (26 alphabet slots) | ## Tags # Count Univalue Subtrees Python Solution Source: https://leetcode-py.wisl.dev/problems/count-univalue-subtrees Tested Python solution for LeetCode 250 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 250, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/count-univalue-subtrees/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 250 # by problem number lcpy gen -s count_univalue_subtrees # by problem name ``` ## Problem Given the `root` of a binary tree, return *the number of **uni-value*** *subtrees*. A **uni-value subtree** means all nodes of the subtree have the same value. ### Examples  ``` Input: root = [5,1,5,5,5,null,5] Output: 4 ``` ``` Input: root = [] Output: 0 ``` ``` Input: root = [5,5,5,5,5,null,5] Output: 6 ``` ### Constraints * The number of nodes in the tree will be in the range `[0, 1000]`. * `-1000 <= Node.val <= 1000` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_univalue_subtrees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_univalue_subtrees/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(n) def count_unival_subtrees(self, root: TreeNode[int] | None) -> int: count = 0 def is_unival(node: TreeNode[int] | None) -> bool: nonlocal count if node is None: return True left_unival = is_unival(node.left) right_unival = is_unival(node.right) if not left_unival or not right_unival: return False if node.left is not None and node.left.val != node.val: return False if node.right is not None and node.right.val != node.val: return False count += 1 return True is_unival(root) return count ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Count Vowel Strings in Ranges Python Solution Source: https://leetcode-py.wisl.dev/problems/count-vowel-strings-in-ranges Tested Python solution for LeetCode 2559 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 2559, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/count-vowel-strings-in-ranges/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2559 # by problem number lcpy gen -s count_vowel_strings_in_ranges # by problem name ``` ## Problem You are given a \0-indexed\ array of strings \words\ and a 2D array of integers \queries\.
Each query \queries\[i] = \[l\i\, r\i\]\ asks us to find the number of strings present at the indices ranging from \l\i\\ to \r\i\\ (both \inclusive\) of \words\ that start and end with a vowel.
Return \an array \\ans\\ of size \\queries.length\\, where \\ans\[i]\\ is the answer to the \\i\\th\\ query\.
\Note\ that the vowel letters are \'a'\, \'e'\, \'i'\, \'o'\, and \'u'\.
### Examples
```
Input: words = ["aba","bcb","ece","aa","e"], queries = [[0,2],[1,4],[1,1]]
Output: [2,3,0]
Explanation: The strings starting and ending with a vowel are "aba", "ece", "aa" and "e".
The answer to the query [0,2] is 2 (strings "aba" and "ece").
The answer to the query [1,4] is 3 (strings "ece", "aa", "e").
The answer to the query [1,1] is 0.
We return [2,3,0].
```
```
Input: words = ["a","e","i"], queries = [[0,2],[0,1],[2,2]]
Output: [3,2,1]
Explanation: Every string satisfies the conditions, so we return [3,2,1].
```
### Constraints
* 1 \<= words.length \<= 10^5
* 1 \<= words\[i].length \<= 40
* words\[i] consists only of lowercase English letters.
* sum(words\[i].length) \<= 3 \* 10^5
* 1 \<= queries.length \<= 10^5
* 0 \<= l\i\ \<= r\i\ \< words.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_vowel_strings_in_ranges/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_vowel_strings_in_ranges/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + q)
# Space: O(n)
def vowel_strings(self, words: list[str], queries: list[list[int]]) -> list[int]:
vowels = set("aeiou")
prefix = [0]
for word in words:
is_vowel = word[0] in vowels and word[-1] in vowels
prefix.append(prefix[-1] + int(is_vowel))
return [prefix[right + 1] - prefix[left] for left, right in queries]
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + q) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Vowels Permutation Python Solution
Source: https://leetcode-py.wisl.dev/problems/count-vowels-permutation
Tested Python solution for LeetCode 1220 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1220, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/count-vowels-permutation/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1220 # by problem number
lcpy gen -s count_vowels_permutation # by problem name
```
## Problem
Given an integer `n`, your task is to count how many strings of length `n` can be formed under the following rules:
* Each character is a lower case vowel (`'a'`, `'e'`, `'i'`, `'o'`, `'u'`)
* Each vowel `'a'` may only be followed by an `'e'`.
* Each vowel `'e'` may only be followed by an `'a'` or an `'i'`.
* Each vowel `'i'` **may not** be followed by another `'i'`.
* Each vowel `'o'` may only be followed by an `'i'` or a `'u'`.
* Each vowel `'u'` may only be followed by an `'a'`.
Since the answer may be too large, return it modulo `10^9 + 7`.
### Examples
```
Input: n = 1
Output: 5
Explanation: All possible strings are: "a", "e", "i" , "o" and "u".
```
```
Input: n = 2
Output: 10
Explanation: All possible strings are: "ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou" and "ua".
```
```
Input: n = 5
Output: 68
```
### Constraints
* `1 <= n <= 2 * 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_vowels_permutation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_vowels_permutation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def count_vowel_permutation(self, n: int) -> int:
mod = 10**9 + 7
counts = {"a": 1, "e": 1, "i": 1, "o": 1, "u": 1}
for _ in range(n - 1):
counts = {
"a": counts["e"] + counts["i"] + counts["u"],
"e": counts["a"] + counts["i"],
"i": counts["e"] + counts["o"],
"o": counts["i"],
"u": counts["i"] + counts["o"],
}
return sum(counts.values()) % mod
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Count Ways To Build Good Strings
Source: https://leetcode-py.wisl.dev/problems/count-ways-to-build-good-strings
Tested Python solution for LeetCode 2466 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2466, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/count-ways-to-build-good-strings/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2466 # by problem number
lcpy gen -s count_ways_to_build_good_strings # by problem name
```
## Problem
Given the integers `zero`, `one`, `low`, and `high`, we can construct a string by starting with an empty string, and then at each step perform either of the following:
* Append the character `'0'` `zero` times.
* Append the character `'1'` `one` times.
This can be performed any number of times.
A **good** string is a string constructed by the above process having a **length** between `low` and `high` (**inclusive**).
Return *the number of **different** good strings that can be constructed satisfying these properties.* Since the answer can be large, return it **modulo** `10^9 + 7`.
### Examples
```
Input: low = 3, high = 3, zero = 1, one = 1
Output: 8
Explanation: One possible valid good string is "011".
It can be constructed as follows: "" -> "0" -> "01" -> "011".
All binary strings from "000" to "111" are good strings in this example.
```
```
Input: low = 2, high = 3, zero = 1, one = 2
Output: 5
Explanation: The good strings are "00", "11", "000", "110", and "011".
```
### Constraints
* 1 \<= low \<= high \<= 10^5
* 1 \<= zero, one \<= low
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_ways_to_build_good_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/count_ways_to_build_good_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
MOD = 1_000_000_007
class Solution:
# Time: O(high)
# Space: O(high)
def count_good_strings(self, low: int, high: int, zero: int, one: int) -> int:
# dp[i] = number of distinct strings of length i buildable from the empty string
dp = [0] * (high + 1)
dp[0] = 1
for length in range(1, high + 1):
total = dp[length - zero] if length >= zero else 0
if length >= one:
total += dp[length - one]
dp[length] = total % MOD
return sum(dp[low : high + 1]) % MOD
```
## Complexity
| Time | Space |
| ------- | ------- |
| O(high) | O(high) |
## Tags
[NeetCode All](/catalog/neetcode).
# Counting Bits Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/counting-bits
Tested Python solution for LeetCode 338 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 338, [Easy](/catalog/easy). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/counting-bits/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 338 # by problem number
lcpy gen -s counting_bits # by problem name
```
## Problem
Given an integer `n`, return *an array* `ans` *of length* `n + 1` *such that for each* `i` *(0 \<= i \<= n),* `ans[i]` *is the **number of*** `1`***'s** in the binary representation of* `i`.
### Examples
```
Input: n = 2
Output: [0,1,1]
Explanation:
0 --> 0
1 --> 1
2 --> 10
```
```
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
```
### Constraints
* 0 \<= n \<= 10^5
**Follow up:**
* It is very easy to come up with a solution with a runtime of `O(n log n)`. Can you do it in linear time `O(n)` and possibly in a single pass?
* Can you do it without using any built-in function (i.e., like `__builtin_popcount` in C++)?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/counting_bits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/counting_bits/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def count_bits(self, n: int) -> list[int]:
"""
Optimized version with better variable naming and comments.
Time: O(n)
Space: O(1) excluding output array
"""
if n == 0:
return [0]
bits_count = [0] * (n + 1)
for num in range(1, n + 1):
# For any number, the count of 1s equals:
# count of 1s in (num >> 1) + whether the last bit is 1
bits_count[num] = bits_count[num >> 1] + (num & 1)
return bits_count
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Counting Elements Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/counting-elements
Tested Python solution for LeetCode 1426 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 1426, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/counting-elements/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1426 # by problem number
lcpy gen -s counting_elements # by problem name
```
## Problem
Given an integer array `arr`, count how many elements `x` there are, such that `x + 1` is also in `arr`. If there are duplicates in `arr`, count them separately.
### Examples
```
Input: arr = [1,2,3]
Output: 2
Explanation: 1 and 2 are counted cause 2 and 3 are in arr.
```
```
Input: arr = [1,1,3,3,5,5,7,7]
Output: 0
Explanation: No numbers are counted, cause there is no 2, 4, 6, or 8 in arr.
```
### Constraints
* 1 \<= arr.length \<= 1000
* 0 \<= arr\[i] \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/counting_elements/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/counting_elements/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def count_elements(self, arr: list[int]) -> int:
counts: set[int] = set(arr)
return sum(x + 1 in counts for x in arr)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Counting Words With a Given Prefix
Source: https://leetcode-py.wisl.dev/problems/counting-words-with-a-given-prefix
Tested Python solution for LeetCode 2185 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 2185, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching). [View on LeetCode](https://leetcode.com/problems/counting-words-with-a-given-prefix/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2185 # by problem number
lcpy gen -s counting_words_with_a_given_prefix # by problem name
```
## Problem
You are given an array of strings `words` and a string `pref`.
Return the number of strings in `words` that contain `pref` as a prefix.
A prefix of a string `s` is any leading contiguous substring of `s`.
### Examples
```
Input: words = ["pay","attention","practice","attend"], pref = "at"
Output: 2
Explanation: The 2 strings that contain "at" as a prefix are: "attention" and "attend".
```
```
Input: words = ["leetcode","win","loops","success"], pref = "code"
Output: 0
Explanation: There are no strings that contain "code" as a prefix.
```
### Constraints
* 1 \<= words.length \<= 100
* 1 \<= words\[i].length, pref.length \<= 100
* words\[i] and pref consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/counting_words_with_a_given_prefix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/counting_words_with_a_given_prefix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(sum(len(w) for w in words) * len(pref)) worst case via startswith
# Space: O(1)
def prefix_count(self, words: list[str], pref: str) -> int:
return sum(1 for word in words if word.startswith(pref))
```
## Complexity
| Time | Space |
| -------------------------------------------------------------------- | ----- |
| O(sum(len(w) for w in words) \* len(pref)) worst case via startswith | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Couples Holding Hands Python Solution
Source: https://leetcode-py.wisl.dev/problems/couples-holding-hands
Tested Python solution for LeetCode 765 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 765, [Hard](/catalog/hard). Topics: [Greedy](/catalog/topics/greedy), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/couples-holding-hands/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 765 # by problem number
lcpy gen -s couples_holding_hands # by problem name
```
## Problem
There are `n` couples sitting in `2n` seats arranged in a row and want to hold hands.
The people and seats are represented by an integer array `row` where `row[i]` is the ID of the person sitting in the `ith` seat. The couples are numbered in order, the first couple being `(0, 1)`, the second couple being `(2, 3)`, and so on with the last couple being `(2n - 2, 2n - 1)`.
Return *the minimum number of swaps so that every couple is sitting side by side*. A swap consists of choosing any two people, then they stand up and switch seats.
### Examples
```
Input: row = [0,2,1,3]
Output: 1
Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
```
```
Input: row = [3,2,0,1]
Output: 0
Explanation: All couples are already seated side by side.
```
### Constraints
* 2n == row\.length
* 2 \<= n \<= 30
* 0 \<= row\[i] \< 2n
* All the elements of row are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/couples_holding_hands/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/couples_holding_hands/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def min_swaps_couples(self, row: list[int]) -> int:
arr = list(row)
pos = {person: i for i, person in enumerate(arr)}
swaps = 0
for i in range(0, len(arr), 2):
partner = arr[i] ^ 1
if arr[i + 1] != partner:
j = pos[partner]
other = arr[i + 1]
arr[i + 1], arr[j] = partner, other
pos[partner] = i + 1
pos[other] = j
swaps += 1
return swaps
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Course Schedule Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/course-schedule
Tested Python solution for LeetCode 207 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 207, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph](/catalog/topics/graph), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/course-schedule/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 207 # by problem number
lcpy gen -s course_schedule # by problem name
```
## Problem
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`.
* For example, the pair `[0, 1]`, indicates that to take course `0` you have to first take course `1`.
Return `true` if you can finish all courses. Otherwise, return `false`.
### Examples
```
Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
```
**Explanation:** There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
```
Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
```
**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.
### Constraints
* `1 <= numCourses <= 2000`
* `0 <= prerequisites.length <= 5000`
* `prerequisites[i].length == 2`
* `0 <= ai, bi < numCourses`
* All the pairs prerequisites\[i] are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(V + E) where V = num_courses, E = prerequisites
# Space: O(V + E) for adjacency list and recursion stack
def can_finish(self, num_courses: int, prerequisites: list[list[int]]) -> bool:
UNVISITED, VISITING, VISITED = 0, 1, 2 # noqa: N806
graph: list[list[int]] = [[] for _ in range(num_courses)]
for course, prereq in prerequisites:
graph[course].append(prereq)
state = [UNVISITED] * num_courses
def has_cycle(course: int) -> bool:
if state[course] == VISITING: # Currently visiting - cycle detected
return True
if state[course] == VISITED:
return False
state[course] = VISITING
for prereq in graph[course]:
if has_cycle(prereq):
return True
state[course] = VISITED
return False
for course in range(num_courses):
if state[course] == UNVISITED and has_cycle(course):
return False
return True
```
## Complexity
| Time | Space |
| -------------------------------------------------- | ----------------------------------------------- |
| O(V + E) where V = num\_courses, E = prerequisites | O(V + E) for adjacency list and recursion stack |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Course Schedule II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/course-schedule-ii
Tested Python solution for LeetCode 210 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 210, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph](/catalog/topics/graph), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/course-schedule-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 210 # by problem number
lcpy gen -s course_schedule_ii # by problem name
```
## Problem
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`.
* For example, the pair `[0, 1]`, indicates that to take course `0` you have to first take course `1`.
Return the ordering of courses you should take to finish all courses. If there are many valid answers, return **any** of them. If it is impossible to finish all courses, return **an empty array**.
### Examples
```
Input: numCourses = 2, prerequisites = [[1,0]]
Output: [0,1]
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].
```
```
Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output: [0,2,1,3]
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].
```
```
Input: numCourses = 1, prerequisites = []
Output: [0]
```
### Constraints
* `1 <= numCourses <= 2000`
* `0 <= prerequisites.length <= numCourses * (numCourses - 1)`
* `prerequisites[i].length == 2`
* `0 <= ai, bi < numCourses`
* `ai != bi`
* All the pairs `[ai, bi]` are **distinct**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# TOPOLOGICAL SORT using Kahn's Algorithm (BFS-based)
# Keywords: DAG, in-degree, adjacency list, cycle detection, dependency resolution
# Time: O(V + E) where V = num_courses, E = len(prerequisites)
# Space: O(V + E) for adjacency list and in_degree array
def find_order(self, num_courses: int, prerequisites: list[list[int]]) -> list[int]:
"""
Topological Sort: Linear ordering of vertices in DAG where all edges go from left to right.
Algorithm: Kahn's Algorithm (BFS approach)
1. Build adjacency list and calculate in-degrees
2. Start with nodes having 0 in-degree (no dependencies)
3. Remove nodes and update in-degrees of neighbors
4. If all nodes processed → valid ordering, else cycle exists
Keywords: Directed Acyclic Graph (DAG), in-degree, out-degree, dependency graph,
prerequisite resolution, cycle detection, BFS traversal
"""
# Build adjacency list and in-degree count
graph: list[list[int]] = [[] for _ in range(num_courses)]
in_degree = [0] * num_courses
for course, prereq in prerequisites:
graph[prereq].append(course)
in_degree[course] += 1
# Start with courses having no prerequisites
queue = deque([i for i in range(num_courses) if in_degree[i] == 0])
result = []
while queue:
course = queue.popleft()
result.append(course)
# Remove this course and update in-degrees
for neighbor in graph[course]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
# Check if all courses can be taken (no cycle)
return result if len(result) == num_courses else []
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | ------------------------------------------------ |
| O(V + E) where V = num\_courses, E = len(prerequisites) | O(V + E) for adjacency list and in\_degree array |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Course Schedule III Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/course-schedule-iii
Tested Python solution for LeetCode 630 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 630, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/course-schedule-iii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 630 # by problem number
lcpy gen -s course_schedule_iii # by problem name
```
## Problem
There are `n` different online courses numbered from `1` to `n`. You are given an array `courses` where `courses[i] = [duration_i, lastDay_i]` indicate that the `i_th` course should be taken **continuously** for `duration_i` days and must be finished before or on `lastDay_i`.
You will start on the `1_st` day and you cannot take two or more courses simultaneously.
Return *the maximum number of courses that you can take*.
### Examples
```
Input: courses = [[100,200],[200,1300],[1000,1250],[2000,3200]]
Output: 3
Explanation: There are totally 4 courses, but you can take 3 courses at most:
First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day.
Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day.
Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day.
The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date.
```
```
Input: courses = [[1,2]]
Output: 1
```
```
Input: courses = [[3,2],[4,3]]
Output: 0
```
### Constraints
* `1 <= courses.length <= 10^4`
* `1 <= duration_i, lastDay_i <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log n)
# Space: O(n)
def schedule_course(self, courses: list[list[int]]) -> int:
taken: list[int] = []
total = 0
for duration, last_day in sorted(courses, key=lambda c: c[1]):
heapq.heappush(taken, -duration)
total += duration
if total > last_day:
total += heapq.heappop(taken)
return len(taken)
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
# Course Schedule IV Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/course-schedule-iv
Tested Python solution for LeetCode 1462 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1462, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/course-schedule-iv/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1462 # by problem number
lcpy gen -s course_schedule_iv # by problem name
```
## Problem
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 `ai` first if you want to take course `bi`.
* For example, the pair `[0, 1]` indicates that you have to take course `0` before you can take course `1`.
Prerequisites can also be **indirect**. If course `a` is a prerequisite of course `b`, and course `b` is a prerequisite of course `c`, then course `a` is a prerequisite of course `c`.
You are also given an array `queries` where `queries[j] = [uj, vj]`. For the `jth` query, you should answer whether course `uj` is a prerequisite of course `vj` or not.
Return *a boolean array* `answer`, *where* `answer[j]` *is the answer to the* `jth` *query*.
### Examples

```
Input: numCourses = 2, prerequisites = [[1,0]], queries = [[0,1],[1,0]]
Output: [false,true]
Explanation: The pair [1, 0] indicates that you have to take course 1 before you can take course 0.
Course 0 is not a prerequisite of course 1, but the opposite is true.
```
```
Input: numCourses = 2, prerequisites = [], queries = [[1,0],[0,1]]
Output: [false,false]
Explanation: There are no prerequisites, and each course is independent.
```

```
Input: numCourses = 3, prerequisites = [[1,2],[1,0],[2,0]], queries = [[1,0],[1,2]]
Output: [true,true]
```
### Constraints
* `2 <= numCourses <= 100`
* `0 <= prerequisites.length <= (numCourses * (numCourses - 1) / 2)`
* `prerequisites[i].length == 2`
* `0 <= ai, bi <= numCourses - 1`
* `ai != bi`
* All the pairs `[ai, bi]` are **unique**.
* The prerequisites graph has no cycles.
* `1 <= queries.length <= 10^4`
* `0 <= ui, vi <= numCourses - 1`
* `ui != vi`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule_iv/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/course_schedule_iv/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^3) Floyd-Warshall transitive closure (n <= 100)
# Space: O(n^2)
def check_if_prerequisite(
self, num_courses: int, prerequisites: list[list[int]], queries: list[list[int]]
) -> list[bool]:
# reach[a][b] = True if a is a (direct or indirect) prerequisite of b.
reach = [[False] * num_courses for _ in range(num_courses)]
for a, b in prerequisites:
reach[a][b] = True
for k in range(num_courses):
for i in range(num_courses):
if reach[i][k]:
for j in range(num_courses):
if reach[k][j]:
reach[i][j] = True
return [reach[u][v] for u, v in queries]
```
## Complexity
| Time | Space |
| ---------------------------------------------------- | ------ |
| O(n^3) Floyd-Warshall transitive closure (n \<= 100) | O(n^2) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Cousins in Binary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/cousins-in-binary-tree
Tested Python solution for LeetCode 993 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 993, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/cousins-in-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 993 # by problem number
lcpy gen -s cousins_in_binary_tree # by problem name
```
## Problem
Given the `root` of a binary tree with unique values and the values of two different nodes of the tree `x` and `y`, return `true` if the nodes corresponding to the values `x` and `y` in the tree are cousins, or `false` otherwise.
Two nodes of a binary tree are **cousins** if they have the same depth with different parents.
Note that in a binary tree, the root node is at the depth `0`, and children of each depth `k` node are at the depth `k + 1`.
### Examples

```
Input: root = [1,2,3,4], x = 4, y = 3
Output: false
```

```
Input: root = [1,2,3,null,4,null,5], x = 5, y = 4
Output: true
```

```
Input: root = [1,2,3,null,4], x = 2, y = 3
Output: false
```
### Constraints
* The number of nodes in the tree is in the range \[2, 100]
* 1 \<= Node.val \<= 100
* Each node has a unique value
* x != y
* x and y exist in the tree
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cousins_in_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cousins_in_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) - single traversal of the tree
# Space: O(h) - recursion stack, h is the tree height
def is_cousins(self, root: TreeNode[int] | None, x: int, y: int) -> bool:
info: dict[int, tuple[int, int | None]] = {}
def dfs(node: TreeNode[int] | None, parent: int | None, depth: int) -> None:
if node is None:
return
info[node.val] = (depth, parent)
dfs(node.left, node.val, depth + 1)
dfs(node.right, node.val, depth + 1)
if root is None:
return False
dfs(root, None, 0)
dx, px = info[x]
dy, py = info[y]
return dx == dy and px != py
```
## Complexity
| Time | Space |
| ----------------------------------- | -------------------------------------------- |
| O(n) - single traversal of the tree | O(h) - recursion stack, h is the tree height |
## Tags
# Cousins in Binary Tree II Python Solution
Source: https://leetcode-py.wisl.dev/problems/cousins-in-binary-tree-ii
Tested Python solution for LeetCode 2641 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2641, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/cousins-in-binary-tree-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2641 # by problem number
lcpy gen -s cousins_in_binary_tree_ii # by problem name
```
## Problem
Given the `root` of a binary tree, replace the value of each node in the tree with the **sum of all its cousins' values**.
Two nodes of a binary tree are **cousins** if they have the same depth with different parents.
Return the root of the modified tree.
Note that the depth of a node is the number of edges in the path from the root node to it.
### Examples

```
Input: root = [5,4,9,1,10,null,7]
Output: [0,0,0,7,7,null,11]
```
**Explanation:** Node with value 5 does not have any cousins so its sum is 0. Node with value 4 does not have any cousins so its sum is 0. Node with value 9 does not have any cousins so its sum is 0. Node with value 1 has a cousin with value 7 so its sum is 7. Node with value 10 has a cousin with value 7 so its sum is 7. Node with value 7 has cousins with values 1 and 10 so its sum is 11.

```
Input: root = [3,1,2]
Output: [0,0,0]
```
**Explanation:** Node with value 3 does not have any cousins so its sum is 0. Node with value 1 does not have any cousins so its sum is 0. Node with value 2 does not have any cousins so its sum is 0.
### Constraints
* The number of nodes in the tree is in the range \[1, 10^5].
* 1 \<= Node.val \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cousins_in_binary_tree_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cousins_in_binary_tree_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(n)
def replace_value_in_tree(self, root: TreeNode[int] | None) -> TreeNode[int] | None:
if root is None:
return None
queue: deque[TreeNode[int]] = deque([root])
root.val = 0
while queue:
next_sum = 0
for node in queue:
for child in (node.left, node.right):
if child is not None:
next_sum += child.val
for _ in range(len(queue)):
node = queue.popleft()
left, right = node.left, node.right
child_sum = 0
if left is not None:
child_sum += left.val
if right is not None:
child_sum += right.val
for child in (left, right):
if child is not None:
child.val = next_sum - child_sum
queue.append(child)
return root
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Cracking the Safe Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/cracking-the-safe
Tested Python solution for LeetCode 753 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 753, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Depth-First Search](/catalog/topics/depth-first-search), [Graph Theory](/catalog/topics/graph-theory), Eulerian Circuit, Eulerian Path, Eulerian Graph. [View on LeetCode](https://leetcode.com/problems/cracking-the-safe/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 753 # by problem number
lcpy gen -s cracking_the_safe # by problem name
```
## Problem
There is a safe protected by a password. The password is a sequence of `n` digits where each digit can be in the range `[0, k - 1]`.
The safe has a peculiar way of checking the password. When you enter in a sequence, it checks the **most recent `n` digits** that were entered each time you type a digit.
* For example, the correct password is `"345"` and you enter in `"012345"`:
* After typing `0`, the most recent `3` digits is `"0"`, which is incorrect.
* After typing `1`, the most recent `3` digits is `"01"`, which is incorrect.
* After typing `2`, the most recent `3` digits is `"012"`, which is incorrect.
* After typing `3`, the most recent `3` digits is `"123"`, which is incorrect.
* After typing `4`, the most recent `3` digits is `"234"`, which is incorrect.
* After typing `5`, the most recent `3` digits is `"345"`, which is correct and the safe unlocks.
Return any string of minimum length that will unlock the safe at some point of entering it.
### Examples
```
Input: n = 1, k = 2
Output: "10"
Explanation: The password is a single digit, so enter each digit. "01" would also unlock the safe.
```
```
Input: n = 2, k = 2
Output: "01100"
Explanation: For each possible password:
- "00" is typed in starting from the 4th digit.
- "01" is typed in starting from the 1st digit.
- "10" is typed in starting from the 3rd digit.
- "11" is typed in starting from the 2nd digit.
Thus "01100" will unlock the safe. "10011", and "11001" would also unlock the safe.
```
### Constraints
* `1 <= n <= 4`
* `1 <= k <= 10`
* `1 <= k^n <= 4096`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cracking_the_safe/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cracking_the_safe/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(k^n) - each of the k^n edges is visited exactly once
# Space: O(k^n) - visited set plus the Eulerian path stack
def crack_safe(self, n: int, k: int) -> str:
if n == 1:
return "".join(str(d) for d in range(k - 1, -1, -1))
start = "0" * (n - 1)
seen: set[str] = set()
digits: list[str] = []
def dfs(node: str) -> None:
for d in range(k):
edge = node + str(d)
if edge not in seen:
seen.add(edge)
dfs(edge[1:])
digits.append(str(d))
dfs(start)
return "".join(digits) + start
```
## Complexity
| Time | Space |
| ------------------------------------------------------ | ------------------------------------------------- |
| O(k^n) - each of the k^n edges is visited exactly once | O(k^n) - visited set plus the Eulerian path stack |
## Tags
# Crawler Log Folder Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/crawler-log-folder
Tested Python solution for LeetCode 1598 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1598, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/crawler-log-folder/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1598 # by problem number
lcpy gen -s crawler_log_folder # by problem name
```
## Problem
The Leetcode file system keeps a log each time some user performs a change folder operation.
The operations are described below:
* `'../'` : Move to the parent folder of the current folder. (If you are already in the main folder, remain in the same folder).
* `'./'` : Remain in the same folder.
* `'x/'` : Move to the child folder named x (This folder is guaranteed to always exist).
You are given a list of strings `logs` where `logs[i]` is the operation performed by the user at the ith step.
The file system starts in the main folder, then the operations in `logs` are performed.
Return the minimum number of operations needed to go back to the main folder after the change folder operations.
### Examples

```
Input: logs = ["d1/","d2/","../","d21/","./"]
Output: 2
Explanation: Use this change folder operation "../" 2 times and go back to the main folder.
```

```
Input: logs = ["d1/","d2/","./","d3/","../","d31/"]
Output: 3
```
```
Input: logs = ["d1/","../","../","../"]
Output: 0
```
### Constraints
* 1 \<= logs.length \<= 10^3
* 2 \<= logs\[i].length \<= 10
* `logs[i]` contains lowercase English letters, digits, `'.'`, and `'/'`.
* `logs[i]` follows the format described in the statement.
* Folder names consist of lowercase English letters and digits.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/crawler_log_folder/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/crawler_log_folder/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def min_operations(self, logs: list[str]) -> int:
depth = 0
for op in logs:
if op == "../":
depth = max(0, depth - 1)
elif op != "./":
depth += 1
return depth
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Create Binary Tree From Descriptions
Source: https://leetcode-py.wisl.dev/problems/create-binary-tree-from-descriptions
Tested Python solution for LeetCode 2196 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2196, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Tree](/catalog/topics/tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/create-binary-tree-from-descriptions/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2196 # by problem number
lcpy gen -s create_binary_tree_from_descriptions # by problem name
```
## Problem
You are given a 2D integer array `descriptions` where `descriptions[i] = [parenti, childi, isLefti]` indicates that `parenti` is the **parent** of `childi` in a **binary** tree of **unique** values. Furthermore,
* If `isLefti == 1`, then `childi` is the left child of `parenti`.
* If `isLefti == 0`, then `childi` is the right child of `parenti`.
Construct the binary tree described by `descriptions` and return its **root**.
The test cases will be generated such that the binary tree is **valid**.
### Examples

```
Input: descriptions = [[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]]
Output: [50,20,80,15,17,19]
Explanation: The root node is the node with value 50 since it has no parent.
```

```
Input: descriptions = [[1,2,1],[2,3,0],[3,4,1]]
Output: [1,2,null,null,3,4]
Explanation: The root node is the node with value 1 since it has no parent.
```
### Constraints
* 1 \<= descriptions.length \<= 10^4
* descriptions\[i].length == 3
* 1 \<= parent\i\, child\i\ \<= 10^5
* 0 \<= isLeft\i\ \<= 1
* The binary tree described by descriptions is valid.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/create_binary_tree_from_descriptions/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/create_binary_tree_from_descriptions/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) - one pass to link nodes, one pass over created nodes to find the root
# Space: O(n) - one TreeNode per unique value plus the children set
def create_binary_tree(self, descriptions: list[list[int]]) -> TreeNode[int] | None:
nodes: dict[int, TreeNode[int]] = {}
children: set[int] = set()
for parent, child, is_left in descriptions:
if parent not in nodes:
nodes[parent] = TreeNode(parent)
if child not in nodes:
nodes[child] = TreeNode(child)
if is_left:
nodes[parent].left = nodes[child]
else:
nodes[parent].right = nodes[child]
children.add(child)
for val, node in nodes.items():
if val not in children:
return node
return None
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------------- | ---------------------------------------------------------- |
| O(n) - one pass to link nodes, one pass over created nodes to find the root | O(n) - one TreeNode per unique value plus the children set |
## Tags
[NeetCode All](/catalog/neetcode).
# Create Maximum Number Python Solution
Source: https://leetcode-py.wisl.dev/problems/create-maximum-number
Tested Python solution for LeetCode 321 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 321, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/create-maximum-number/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 321 # by problem number
lcpy gen -s create_maximum_number # by problem name
```
## Problem
You are given two integer arrays `nums1` and `nums2` of lengths `m` and `n` respectively. `nums1` and `nums2` represent the digits of two numbers. You are also given an integer `k`.
Create the maximum number of length `k <= m + n` from digits of the two numbers. The relative order of the digits from the same array must be preserved.
Return an array of the `k` digits representing the answer.
### Examples
```
Input: nums1 = [3,4,6,5], nums2 = [9,1,2,5,8,3], k = 5
Output: [9,8,6,5,3]
```
```
Input: nums1 = [6,7], nums2 = [6,0,4], k = 5
Output: [6,7,6,0,4]
```
```
Input: nums1 = [3,9], nums2 = [8,9], k = 3
Output: [9,8,9]
```
### Constraints
* `m == nums1.length`
* `n == nums2.length`
* `1 <= m, n <= 500`
* `0 <= nums1[i], nums2[i] <= 9`
* `1 <= k <= m + n`
* `nums1` and `nums2` do not have leading zeros.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/create_maximum_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/create_maximum_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(k * (m + n))
# Space: O(k)
def max_number(self, nums1: list[int], nums2: list[int], k: int) -> list[int]:
def pick(nums: list[int], size: int) -> list[int]:
drop = len(nums) - size
stack: list[int] = []
for digit in nums:
while drop and stack and stack[-1] < digit:
stack.pop()
drop -= 1
stack.append(digit)
return stack[:size]
def merge(a: list[int], b: list[int]) -> list[int]:
merged: list[int] = []
i = j = 0
while i < len(a) and j < len(b):
if a[i:] > b[j:]:
merged.append(a[i])
i += 1
else:
merged.append(b[j])
j += 1
merged.extend(a[i:])
merged.extend(b[j:])
return merged
best: list[int] = []
for take1 in range(max(0, k - len(nums2)), min(k, len(nums1)) + 1):
candidate = merge(pick(nums1, take1), pick(nums2, k - take1))
if candidate > best:
best = candidate
return best
```
## Complexity
| Time | Space |
| --------------- | ----- |
| O(k \* (m + n)) | O(k) |
## Tags
# Custom Sort String Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/custom-sort-string
Tested Python solution for LeetCode 791 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 791, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/custom-sort-string/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 791 # by problem number
lcpy gen -s custom_sort_string # by problem name
```
## Problem
You are given two strings `order` and `s`. All the characters of `order` are **unique** and were sorted in some custom order previously.
*Permute* the characters of `s` so that they match the order that `order` was sorted. More specifically, if a character `x` occurs before a character `y` in `order`, then `x` should occur before `y` in the permuted string.
Return *any permutation of* `s` *that satisfies this property*.
### Examples
```
Input: order = "cba", s = "abcd"
Output: "cbad"
Explanation: "a", "b", "c" appear in order, so the order of "a", "b", "c" should be "c", "b", and "a".
Since "d" does not appear in order, it can be at any position in the returned string. "dcba", "cdba", "cbda" are also valid outputs.
```
```
Input: order = "bcafg", s = "abcd"
Output: "bcad"
Explanation: The characters "b", "c", and "a" from order dictate the order for the characters in s. The character "d" in s does not appear in order, so its position is flexible.
Following the order of appearance in order, "b", "c", and "a" from s should be arranged as "b", "c", "a". "d" can be placed at any position since it's not in order. The output "bcad" correctly follows this rule. Other arrangements like "dbca" or "bcda" would also be valid, as long as "b", "c", "a" maintain their order.
```
### Constraints
* 1 \<= order.length \<= 26
* 1 \<= s.length \<= 200
* order and s consist of lowercase English letters.
* All the characters of order are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/custom_sort_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/custom_sort_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(s) log len(s))
# Space: O(len(s))
def custom_sort_string(self, order: str, s: str) -> str:
rank = {c: i for i, c in enumerate(order)}
return "".join(sorted(s, key=lambda c: rank.get(c, 26)))
```
## Complexity
| Time | Space |
| -------------------- | --------- |
| O(len(s) log len(s)) | O(len(s)) |
## Tags
[NeetCode All](/catalog/neetcode).
# Cut Off Trees for Golf Event Python Solution
Source: https://leetcode-py.wisl.dev/problems/cut-off-trees-for-golf-event
Tested Python solution for LeetCode 675 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 675, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/cut-off-trees-for-golf-event/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 675 # by problem number
lcpy gen -s cut_off_trees_for_golf_event # by problem name
```
## Problem
You are asked to cut off all the trees in a forest for a golf event. The forest is represented as an `m x n` matrix. In this matrix:
* `0` means the cell cannot be walked through.
* `1` represents an empty cell that can be walked through.
* A number greater than `1` represents a tree in a cell that can be walked through, and this number is the tree's height.
In one step, you can walk in any of the four directions: north, east, south, and west. If you are standing in a cell with a tree, you can choose whether to cut it off.
You must cut off the trees in order from shortest to tallest. When you cut off a tree, the value at its cell becomes `1` (an empty cell).
Starting from the point `(0, 0)`, return *the minimum steps you need to walk to cut off all the trees*. If you cannot cut off all the trees, return `-1`.
Note: The input is generated such that no two trees have the same height, and there is at least one tree needs to be cut off.
### Examples

```
Input: forest = [[1,2,3],[0,0,4],[7,6,5]]
Output: 6
```
**Explanation:** Following the path above allows you to cut off the trees from shortest to tallest in 6 steps.

```
Input: forest = [[1,2,3],[0,0,0],[7,6,5]]
Output: -1
```
**Explanation:** The trees in the bottom row cannot be accessed as the middle row is blocked.
```
Input: forest = [[2,3,4],[0,0,5],[8,7,6]]
Output: 6
```
**Explanation:** You can follow the same path as Example 1 to cut off all the trees. Note that you can cut off the first tree at (0, 0) before making any steps.
### Constraints
* `m == forest.length`
* `n == forest[i].length`
* `1 <= m, n <= 50`
* `0 <= forest[i][j] <= 10^9`
* Heights of all trees are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cut_off_trees_for_golf_event/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cut_off_trees_for_golf_event/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O((mn)^2) each BFS scan is O(mn) and runs once per tree
# Space: O(mn) for the BFS queue and visited set
def cut_off_tree(self, forest: list[list[int]]) -> int:
rows, cols = len(forest), len(forest[0])
trees = sorted(
(forest[r][c], r, c) for r in range(rows) for c in range(cols) if forest[r][c] > 1
)
def bfs(sr: int, sc: int, tr: int, tc: int) -> int:
if (sr, sc) == (tr, tc):
return 0
seen: set[tuple[int, int]] = {(sr, sc)}
queue: deque[tuple[int, int, int]] = deque([(sr, sc, 0)])
while queue:
r, c, steps = queue.popleft()
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if (
0 <= nr < rows
and 0 <= nc < cols
and forest[nr][nc] > 0
and (nr, nc) not in seen
):
if (nr, nc) == (tr, tc):
return steps + 1
seen.add((nr, nc))
queue.append((nr, nc, steps + 1))
return -1
total = 0
cur_r, cur_c = 0, 0
for _, tree_r, tree_c in trees:
dist = bfs(cur_r, cur_c, tree_r, tree_c)
if dist < 0:
return -1
total += dist
cur_r, cur_c = tree_r, tree_c
return total
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | --------------------------------------- |
| O((mn)^2) each BFS scan is O(mn) and runs once per tree | O(mn) for the BFS queue and visited set |
## Tags
# Cutting Ribbons Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/cutting-ribbons
Tested Python solution for LeetCode 1891 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1891, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/cutting-ribbons/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1891 # by problem number
lcpy gen -s cutting_ribbons # by problem name
```
## Problem
You are given an integer array `ribbons`, where `ribbons[i]` represents the length of the i\th\ ribbon, and an integer `k`. You may cut any of the ribbons into any number of segments of **positive integer** lengths, or perform no cuts at all.
* For example, if you have a ribbon of length `4`, you can:
* Keep the ribbon of length `4`,
* Cut it into one ribbon of length `3` and one ribbon of length `1`,
* Cut it into two ribbons of length `2`,
* Cut it into one ribbon of length `2` and two ribbons of length `1`, or
* Cut it into four ribbons of length `1`.
Your task is to determine the **maximum** length of ribbon, `x`, that allows you to cut *at least* `k` ribbons, each of length `x`. You can discard any leftover ribbon from the cuts. If it is **impossible** to cut `k` ribbons of the same length, return 0.
### Examples
```
Input: ribbons = [9,7,5], k = 3
Output: 5
Explanation:
- Cut the first ribbon to two ribbons, one of length 5 and one of length 4.
- Cut the second ribbon to two ribbons, one of length 5 and one of length 2.
- Keep the third ribbon as it is.
Now you have 3 ribbons of length 5.
```
```
Input: ribbons = [7,5,9], k = 4
Output: 4
Explanation:
- Cut the first ribbon to two ribbons, one of length 4 and one of length 3.
- Cut the second ribbon to two ribbons, one of length 4 and one of length 1.
- Cut the third ribbon to three ribbons, two of length 4 and one of length 1.
Now you have 4 ribbons of length 4.
```
```
Input: ribbons = [5,7,9], k = 22
Output: 0
Explanation: You cannot obtain k ribbons of the same positive integer length.
```
### Constraints
* 1 \<= ribbons.length \<= 10\5\
* 1 \<= ribbons\[i] \<= 10\5\
* 1 \<= k \<= 10\9\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cutting_ribbons/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/cutting_ribbons/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log M) where n = len(ribbons), M = max(ribbons)
# Space: O(1)
def max_length(self, ribbons: list[int], k: int) -> int:
left, right = 1, max(ribbons)
while left <= right:
mid = (left + right) // 2
if sum(r // mid for r in ribbons) >= k:
left = mid + 1
else:
right = mid - 1
return right
```
## Complexity
| Time | Space |
| --------------------------------------------------- | ----- |
| O(n log M) where n = len(ribbons), M = max(ribbons) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Daily Temperatures Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/daily-temperatures
Tested Python solution for LeetCode 739 with 35 pytest cases. Generate a practice environment with lcpy.
LeetCode 739, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/daily-temperatures/description/).
Generate this problem as a practice environment: tested reference solution, 35 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 739 # by problem number
lcpy gen -s daily_temperatures # by problem name
```
## Problem
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 `ith` day to get a warmer temperature. If there is no future day for which this is possible, keep `answer[i] == 0` instead.
### Examples
```
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]
```
**Explanation:**
* For input `[73,74,75,71,69,72,76,73]`, the output should be `[1,1,4,2,1,1,0,0]`.
* For example, the first temperature is 73. The next warmer temperature is 74, which is 1 day later, so we put 1.
* The second temperature is 74. The next warmer temperature is 75, which is 1 day later, so we put 1.
* The third temperature is 75. The next warmer temperature is 76, which is 4 days later, so we put 4.
```
Input: temperatures = [30,40,50,60]
Output: [1,1,1,0]
```
```
Input: temperatures = [30,60,90]
Output: [1,1,0]
```
### Constraints
* `1 <= temperatures.length <= 10^5`
* `30 <= temperatures[i] <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/daily_temperatures/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/daily_temperatures/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def daily_temperatures(self, temperatures: list[int]) -> list[int]:
result = [0] * len(temperatures)
stack: list[int] = []
for i, temp in enumerate(temperatures):
while stack and temperatures[stack[-1]] < temp:
prev_index = stack.pop()
result[prev_index] = i - prev_index
stack.append(i)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Data Stream as Disjoint Intervals
Source: https://leetcode-py.wisl.dev/problems/data-stream-as-disjoint-intervals
Tested Python solution for LeetCode 352 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 352, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [Binary Search](/catalog/topics/binary-search), [Union-Find](/catalog/topics/union-find), [Design](/catalog/topics/design), [Data Stream](/catalog/topics/data-stream), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/data-stream-as-disjoint-intervals/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 352 # by problem number
lcpy gen -s data_stream_as_disjoint_intervals # by problem name
```
## Problem
Given a data stream input of non-negative integers `a1, a2, ..., an`, summarize the numbers seen so far as a list of disjoint intervals.
Implement the `SummaryRanges` class:
* `SummaryRanges()` Initializes the object with an empty stream.
* `void addNum(int value)` Adds the integer `value` to the stream.
* `int[][] getIntervals()` Returns a summary of the integers in the stream currently as a list of disjoint intervals `[starti, endi]`. The answer should be sorted by `starti`.
### Examples
```
Input
['SummaryRanges', 'addNum', 'getIntervals', 'addNum', 'getIntervals', 'addNum', 'getIntervals', 'addNum', 'getIntervals', 'addNum', 'getIntervals']
[[], [1], [], [3], [], [7], [], [2], [], [6], []]
Output
[None, None, [[1, 1]], None, [[1, 1], [3, 3]], None, [[1, 1], [3, 3], [7, 7]], None, [[1, 3], [7, 7]], None, [[1, 3], [6, 7]]]
Explanation
SummaryRanges summaryRanges = new SummaryRanges();
summaryRanges.addNum(1); // arr = [1]
summaryRanges.getIntervals(); // return [[1, 1]]
summaryRanges.addNum(3); // arr = [1, 3]
summaryRanges.getIntervals(); // return [[1, 1], [3, 3]]
summaryRanges.addNum(7); // arr = [1, 3, 7]
summaryRanges.getIntervals(); // return [[1, 1], [3, 3], [7, 7]]
summaryRanges.addNum(2); // arr = [1, 2, 3, 7]
summaryRanges.getIntervals(); // return [[1, 3], [7, 7]]
summaryRanges.addNum(6); // arr = [1, 2, 3, 6, 7]
summaryRanges.getIntervals(); // return [[1, 3], [6, 7]]
```
### Constraints
* 0 \<= value \<= 10\4\
* At most 3 \* 10\4\ calls will be made to `addNum` and `getIntervals`.
* At most 10\2\ calls will be made to `getIntervals`.
**Follow up:** What if there are lots of merges and the number of disjoint intervals is small compared to the size of the data stream?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/data_stream_as_disjoint_intervals/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/data_stream_as_disjoint_intervals/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_left
class SummaryRanges:
# Maintains starts sorted; interval i covers [starts[i], ends[i]].
# add_num: O(log n) lookup + O(n) list insert; get_intervals: O(k).
# Space: O(n)
def __init__(self) -> None:
self._starts: list[int] = []
self._ends: list[int] = []
def add_num(self, value: int) -> None:
index = bisect_left(self._starts, value)
if index < len(self._starts) and self._starts[index] == value:
return # duplicate
# value lands strictly between interval index-1 and index
left_adjacent = index > 0 and self._ends[index - 1] == value - 1
right_adjacent = index < len(self._starts) and self._starts[index] == value + 1
if left_adjacent and right_adjacent:
# bridge the two intervals
self._ends[index - 1] = self._ends[index]
del self._starts[index]
del self._ends[index]
elif left_adjacent:
self._ends[index - 1] = value
elif right_adjacent:
self._starts[index] = value
else:
self._starts.insert(index, value)
self._ends.insert(index, value)
def get_intervals(self) -> list[list[int]]:
return [[start, end] for start, end in zip(self._starts, self._ends, strict=True)]
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Decode String Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/decode-string
Tested Python solution for LeetCode 394 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 394, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/decode-string/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 394 # by problem number
lcpy gen -s decode_string # by problem name
```
## Problem
Given an encoded string, return its decoded string.
The encoding rule is: `k[encoded_string]`, where the `encoded_string` inside the square brackets is being repeated exactly `k` times. Note that `k` is guaranteed to be a positive integer.
You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, `k`. For example, there will not be input like `3a` or `2[4]`.
The test cases are generated so that the length of the output will never exceed 10^5.
### Examples
```
Input: s = "3[a]2[bc]"
Output: "aaabcbc"
```
```
Input: s = "3[a2[c]]"
Output: "accaccacc"
```
```
Input: s = "2[abc]3[cd]ef"
Output: "abcabccdcdcdef"
```
### Constraints
* 1 \<= s.length \<= 30
* s consists of lowercase English letters, digits, and square brackets '\[]'
* s is guaranteed to be a valid input
* All the integers in s are in the range \[1, 300]
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decode_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decode_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) - single pass through string
# Space: O(n) - stack storage for nested brackets
def decode_string(self, s: str) -> str:
"""
Decode string using stack for nested brackets.
Example: s = "2[b3[a]]" → "baaabaaa"
Process: 2 [ b 3 [ a ] ]
char='2': num=2
char='[': push('', 2), reset
char='b': str='b'
char='3': num=3
char='[': push('b', 3), reset
char='a': str='a'
char=']': pop('b', 3) → str = 'b' + 'a'*3 = 'baaa'
char=']': pop('', 2) → str = '' + 'baaa'*2 = 'baaabaaa'
"""
stack = []
current_str = ""
current_num = 0
for char in s:
if char.isdigit():
current_num = current_num * 10 + int(char)
elif char == "[":
# Push current state and reset
stack.append((current_str, current_num))
current_str = ""
current_num = 0
elif char == "]":
# Pop and construct
prev_str, repeat_count = stack.pop()
current_str = prev_str + current_str * repeat_count
else:
current_str += char
return current_str
```
## Complexity
| Time | Space |
| --------------------------------- | ---------------------------------------- |
| O(n) - single pass through string | O(n) - stack storage for nested brackets |
## Tags
[Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Decode Ways Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/decode-ways
Tested Python solution for LeetCode 91 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 91, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/decode-ways/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 91 # by problem number
lcpy gen -s decode_ways # by problem name
```
## Problem
You have intercepted a secret message encoded as a string of numbers. The message is decoded via the mapping: `"1" -> 'A', "2" -> 'B', ..., "26" -> 'Z'`. Given a string `s` containing only digits, return the number of ways to decode it. Return `0` if it cannot be decoded.
### Examples
```
Input: s = "12"
Output: 2
Explanation: "12" could be decoded as "AB" (1 2) or "L" (12).
```
```
Input: s = "226"
Output: 3
Explanation: "226" could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
```
```
Input: s = "06"
Output: 0
Explanation: leading zero makes it invalid.
```
### Constraints
* 1 \<= s.length \<= 100
* s contains only digits and may contain leading zero(s)
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decode_ways/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decode_ways/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def num_decodings(self, s: str) -> int:
if not s:
return 0
num_ways_two_steps_behind: int = 1
num_ways_one_step_behind: int = 0 if s[0] == "0" else 1
for index in range(1, len(s)):
current_char: str = s[index]
previous_char: str = s[index - 1]
current_num_ways: int = 0
if current_char != "0":
current_num_ways += num_ways_one_step_behind
two_digit_value: int = int(previous_char + current_char)
if previous_char != "0" and 10 <= two_digit_value <= 26:
current_num_ways += num_ways_two_steps_behind
num_ways_two_steps_behind, num_ways_one_step_behind = (
num_ways_one_step_behind,
current_num_ways,
)
return num_ways_one_step_behind
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Decode Ways II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/decode-ways-ii
Tested Python solution for LeetCode 639 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 639, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/decode-ways-ii/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 639 # by problem number
lcpy gen -s decode_ways_ii # by problem name
```
## Problem
A message containing letters from A-Z can be encoded into numbers using the following mapping:
```
'A' -> "1"
'B' -> "2"
...
'Z' -> "26"
```
To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, "11106" can be mapped into:
* "AAJF" with the grouping (1 1 10 6)
* "KJF" with the grouping (11 10 6)
Note that the grouping (1 11 06) is invalid because "06" cannot be mapped into 'F' since "6" is different from "06".
In addition to the mapping above, an encoded message may contain the '*' character, which can represent any digit from '1' to '9' ('0' is excluded). For example, the encoded message "1*" may represent any of the encoded messages "11", "12", "13", "14", "15", "16", "17", "18", or "19". Decoding "1\*" is equivalent to decoding any of the encoded messages it can represent.
Given a string s consisting of digits and '\*' characters, return the number of ways to decode it.
Since the answer may be very large, return it modulo 10^9 + 7.
### Examples
```
Input: s = "*"
Output: 9
Explanation: The encoded message can represent any of the encoded messages "1" through "9". Each of these can be decoded to the strings "A" through "I" respectively. Hence, there are a total of 9 ways to decode "*".
```
```
Input: s = "1*"
Output: 18
Explanation: The encoded message can represent any of the encoded messages "11" through "19". Each of these encoded messages have 2 ways to be decoded (e.g. "11" can be decoded to "AA" or "K"). Hence, there are a total of 9 * 2 = 18 ways to decode "1*".
```
```
Input: s = "2*"
Output: 15
Explanation: The encoded message can represent any of the encoded messages "21" through "29". "21" through "26" have 2 ways of being decoded, but "27" through "29" only have 1 way. Hence, there are a total of (6 * 2) + (3 * 1) = 15 ways to decode "2*".
```
### Constraints
* 1 \<= s.length \<= 10^5
* s\[i] is a digit or '\*'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decode_ways_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decode_ways_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def num_decodings(self, s: str) -> int:
mod = 1_000_000_007
prev = 1
curr = self._ways_single(s[0])
for i in range(1, len(s)):
pair = self._ways_pair(s[i - 1], s[i])
prev, curr = curr, (curr * self._ways_single(s[i]) + prev * pair) % mod
return curr
def _ways_single(self, ch: str) -> int:
if ch == "*":
return 9
return 0 if ch == "0" else 1
def _ways_pair(self, a: str, b: str) -> int:
if a == "*":
if b == "*":
return 15
return 2 if b <= "6" else 1
if b == "*":
return 9 if a == "1" else (6 if a == "2" else 0)
if a == "0":
return 0
return 1 if int(a + b) <= 26 else 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Decoded String at Index Python Solution
Source: https://leetcode-py.wisl.dev/problems/decoded-string-at-index
Tested Python solution for LeetCode 880 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 880, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/decoded-string-at-index/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 880 # by problem number
lcpy gen -s decoded_string_at_index # by problem name
```
## Problem
You are given an encoded string `s`. To decode the string to a tape, the encoded string is read one character at a time and the following steps are taken:
* If the character read is a letter, that letter is written onto the tape.
* If the character read is a digit `d`, the entire current tape is repeatedly written `d - 1` more times in total.
Given an integer `k`, return the `k^th` letter (**1-indexed**) in the decoded string.
### Examples
```
Input: s = "leet2code3", k = 10
Output: "o"
Explanation: The decoded string is "leetleetcodeleetleetcodeleetleetcode".
The 10th letter in the string is "o".
```
```
Input: s = "ha22", k = 5
Output: "h"
Explanation: The decoded string is "hahahaha".
The 5th letter is "h".
```
```
Input: s = "a2345678999999999999999", k = 1
Output: "a"
Explanation: The decoded string is "a" repeated 8301530446056247680 times.
The 1st letter is "a".
```
### Constraints
* 2 \<= s.length \<= 100
* s consists of lowercase English letters and digits 2 through 9.
* s starts with a letter.
* 1 \<= k \<= 10^9
* It is guaranteed that k is less than or equal to the length of the decoded string.
* The decoded string is guaranteed to have less than 2^63 letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decoded_string_at_index/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/decoded_string_at_index/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def decode_at_index(self, s: str, k: int) -> str:
size = 0
for char in s:
size = size * int(char) if char.isdigit() else size + 1
for char in reversed(s):
k %= size
if k == 0 and char.isalpha():
return char
if char.isdigit():
size //= int(char)
else:
size -= 1
raise ValueError("k out of range")
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Defuse the Bomb Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/defuse-the-bomb
Tested Python solution for LeetCode 1652 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 1652, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/defuse-the-bomb/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1652 # by problem number
lcpy gen -s defuse_the_bomb # by problem name
```
## Problem
You have a bomb to defuse, and your time is running out! Your informer will provide you with a **circular** array `code` of length of `n` and a key `k`.
To decrypt the code, you must replace every number. All the numbers are replaced **simultaneously**.
* If `k > 0`, replace the `ith` number with the sum of the **next** `k` numbers.
* If `k < 0`, replace the `ith` number with the sum of the **previous** `-k` numbers.
* If `k == 0`, replace the `ith` number with `0`.
As `code` is circular, the next element of `code[n-1]` is `code[0]`, and the previous element of `code[0]` is `code[n-1]`.
Given the **circular** array `code` and an integer key `k`, return *the decrypted code to defuse the bomb*!
### Examples
```
Input: code = [5,7,1,4], k = 3
Output: [12,10,16,13]
Explanation: Each number is replaced by the sum of the next 3 numbers. The decrypted code is [7+1+4, 1+4+5, 4+5+7, 5+7+1]. Notice that the numbers wrap around.
```
```
Input: code = [1,2,3,4], k = 0
Output: [0,0,0,0]
Explanation: When k is zero, the numbers are replaced by 0.
```
```
Input: code = [2,4,9,3], k = -2
Output: [12,5,6,13]
Explanation: The decrypted code is [3+9, 2+3, 4+2, 9+4]. Notice that the numbers wrap around again. If k is negative, the sum is of the previous numbers.
```
### Constraints
* n == code.length
* 1 \<= n \<= 100
* 1 \<= code\[i] \<= 100
* -(n - 1) \<= k \<= n - 1
**Follow up:** Could you solve it in `O(n)` time without scanning the window from scratch for every index?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/defuse_the_bomb/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/defuse_the_bomb/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) extra (output excluded)
def decrypt(self, code: list[int], k: int) -> list[int]:
n = len(code)
if k == 0:
return [0] * n
window = abs(k)
offset = 1 if k > 0 else -window
total = sum(code[(offset + j) % n] for j in range(window))
result = [0] * n
for i in range(n):
result[i] = total
total += code[(i + offset + window) % n] - code[(i + offset) % n]
return result
```
## Complexity
| Time | Space |
| ---- | ---------------------------- |
| O(n) | O(1) extra (output excluded) |
## Tags
[NeetCode All](/catalog/neetcode).
# Degree of an Array Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/degree-of-an-array
Tested Python solution for LeetCode 697 with 40 pytest cases. Generate a practice environment with lcpy.
LeetCode 697, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/degree-of-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 40 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 697 # by problem number
lcpy gen -s degree_of_an_array # by problem name
```
## Problem
Given a non-empty array of non-negative integers `nums`, the **degree** of this array is defined as the maximum frequency of any one of its elements.
Your task is to find the smallest possible length of a (contiguous) subarray of `nums`, that has the same degree as `nums`.
### Examples
```
Input: nums = [1,2,2,3,1]
Output: 2
Explanation:
The input array has a degree of 2 because both elements 1 and 2 appear twice.
Of the subarrays that have the same degree:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
The shortest length is 2. So return 2.
```
```
Input: nums = [1,2,2,3,1,4,2]
Output: 6
Explanation:
The degree is 3 because the element 2 is repeated 3 times.
So [2,2,3,1,4,2] is the shortest subarray, therefore returning 6.
```
### Constraints
* 1 \<= nums.length \<= 5 \* 10^4
* 0 \<= nums\[i] \<= 5 \* 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/degree_of_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/degree_of_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def find_shortest_sub_array(self, nums: list[int]) -> int:
first: dict[int, int] = {}
last: dict[int, int] = {}
count: dict[int, int] = {}
for i, num in enumerate(nums):
if num not in first:
first[num] = i
last[num] = i
count[num] = count.get(num, 0) + 1
degree = max(count.values())
return min(last[num] - first[num] + 1 for num in count if count[num] == degree)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Delete and Earn Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/delete-and-earn
Tested Python solution for LeetCode 740 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 740, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/delete-and-earn/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 740 # by problem number
lcpy gen -s delete_and_earn # by problem name
```
## Problem
You are given an integer array `nums`. You want to maximize the number of points you get by performing the following operation any number of times:
* Pick any `nums[i]` and delete it to earn `nums[i]` points. Afterwards, you must delete every element equal to `nums[i] - 1` and every element equal to `nums[i] + 1`.
Return the maximum number of points you can earn by applying the above operation some number of times.
### Examples
```
Input: nums = [3,4,2]
Output: 6
Explanation: You can perform the following operations:
- Delete 4 to earn 4 points. Consequently, 3 is also deleted. nums = [2].
- Delete 2 to earn 2 points. nums = [].
You earn a total of 6 points.
```
```
Input: nums = [2,2,3,3,3,4]
Output: 9
Explanation: You can perform the following operations:
- Delete a 3 to earn 3 points. All 2's and 4's are also deleted. nums = [3,3].
- Delete a 3 again to earn 3 points. nums = [3].
- Delete a 3 once more to earn 3 points. nums = [].
You earn a total of 9 points.
```
### Constraints
* 1 \<= nums.length \<= 2 \* 10^4
* 1 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_and_earn/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_and_earn/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Reduces to house robber over consecutive value runs
# Time: O(n + m log m) where m = number of distinct values
# Space: O(m)
def delete_and_earn(self, nums: list[int]) -> int:
counts = Counter(nums)
take = skip = 0
previous = None
for value in sorted(counts):
gain = value * counts[value]
if previous == value - 1:
take, skip = skip + gain, max(take, skip)
else:
take, skip = max(take, skip) + gain, max(take, skip)
previous = value
return max(take, skip)
```
## Complexity
| Time | Space |
| -------------------------------------------------- | ----- |
| O(n + m log m) where m = number of distinct values | O(m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Delete Columns to Make Sorted Python Solution
Source: https://leetcode-py.wisl.dev/problems/delete-columns-to-make-sorted
Tested Python solution for LeetCode 944 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 944, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/delete-columns-to-make-sorted/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 944 # by problem number
lcpy gen -s delete_columns_to_make_sorted # by problem name
```
## Problem
You are given an array of `n` strings `strs`, all of the same length.
The strings can be arranged such that there is one on each line, making a grid.
* For example, `strs = ["abc", "bce", "cae"]` can be arranged as follows:
```
abc
bce
cae
```
You want to **delete** the columns that are **not sorted lexicographically**. In the above example (**0-indexed**), columns 0 (`'a'`, `'b'`, `'c'`) and 2 (`'c'`, `'e'`, `'e'`) are sorted, while column 1 (`'b'`, `'c'`, `'a'`) is not, so you would delete column 1.
Return *the number of columns that you will delete*.
### Examples
```
Input: strs = ["cba","daf","ghi"]
Output: 1
Explanation: The grid looks as follows:
cba
daf
ghi
Columns 0 and 2 are sorted, but column 1 is not, so you only need to delete 1 column.
```
```
Input: strs = ["a","b"]
Output: 0
Explanation: The grid looks as follows:
a
b
Column 0 is the only column and is sorted, so you will not delete any columns.
```
```
Input: strs = ["zyx","wvu","tsr"]
Output: 3
Explanation: The grid looks as follows:
zyx
wvu
tsr
All 3 columns are not sorted, so you will delete all 3.
```
### Constraints
* n == strs.length
* 1 \<= n \<= 100
* 1 \<= strs\[i].length \<= 1000
* strs\[i] consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_columns_to_make_sorted/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_columns_to_make_sorted/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m) where n = len(strs), m = len(strs[0])
# Space: O(1)
def min_deletion_size(self, strs: list[str]) -> int:
return sum(
any(strs[row][col] < strs[row - 1][col] for row in range(1, len(strs)))
for col in range(len(strs[0]))
)
```
## Complexity
| Time | Space |
| ------------------------------------------------ | ----- |
| O(n \* m) where n = len(strs), m = len(strs\[0]) | O(1) |
## Tags
# Delete Columns to Make Sorted II
Source: https://leetcode-py.wisl.dev/problems/delete-columns-to-make-sorted-ii
Tested Python solution for LeetCode 955 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 955, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/delete-columns-to-make-sorted-ii/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 955 # by problem number
lcpy gen -s delete_columns_to_make_sorted_ii # by problem name
```
## Problem
You are given an array of `n` strings `strs`, all of the same length.
We may choose any deletion indices, and we delete all the characters in those indices for each string.
For example, if we have `strs = ["abcdef","uvwxyz"]` and deletion indices `{0, 2, 3}`, then the final array after deletions is `["bef", "vyz"]`.
Suppose we chose a set of deletion indices `answer` such that after deletions, the final array has its elements in **lexicographic** order (i.e., `strs[0] <= strs[1] <= strs[2] <= ... <= strs[n - 1]`). Return *the minimum possible value of* `answer.length`.
### Examples
```
Input: strs = ["ca","bb","ac"]
Output: 1
Explanation: After deleting the first column, strs = ["a", "b", "c"]. Now strs is in lexicographic order (ie. strs[0] <= strs[1] <= strs[2]). We require at least 1 deletion since initially strs was not in lexicographic order, so the answer is 1.
```
```
Input: strs = ["xc","yb","za"]
Output: 0
Explanation: strs is already in lexicographic order, so we do not need to delete anything.
Note that the rows of strs are not necessarily in lexicographic order:
i.e., it is NOT necessarily true that (strs[0][0] <= strs[0][1] <= ...)
```
```
Input: strs = ["zyx","wvu","tsr"]
Output: 3
Explanation: We have to delete every column.
```
### Constraints
* n == strs.length
* 1 \<= n \<= 100
* 1 \<= strs\[i].length \<= 100
* strs\[i] consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_columns_to_make_sorted_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_columns_to_make_sorted_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * w^2)
# Space: O(n * w)
def min_deletion_size(self, strs: list[str]) -> int:
keep = [""] * len(strs)
deleted = 0
for j in range(len(strs[0])):
candidate = [row + s[j] for row, s in zip(keep, strs, strict=True)]
if all(candidate[i] <= candidate[i + 1] for i in range(len(candidate) - 1)):
keep = candidate
else:
deleted += 1
return deleted
```
## Complexity
| Time | Space |
| ----------- | --------- |
| O(n \* w^2) | O(n \* w) |
## Tags
# Delete Columns to Make Sorted III
Source: https://leetcode-py.wisl.dev/problems/delete-columns-to-make-sorted-iii
Tested Python solution for LeetCode 960 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 960, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/delete-columns-to-make-sorted-iii/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 960 # by problem number
lcpy gen -s delete_columns_to_make_sorted_iii # by problem name
```
## Problem
You are given an array of `n` strings `strs`, all of the same length.
We may choose any deletion indices, and we delete all the characters in those indices for each string.
For example, if we have `strs = ["abcdef","uvwxyz"]` and deletion indices `{0, 2, 3}`, then the final array after deletions is `["bef", "vyz"]`.
Suppose we chose a set of deletion indices `answer` such that after deletions, the final array has **every string (row) in lexicographic** order. (i.e., `(strs[0][0] <= strs[0][1] <= ... <= strs[0][strs[0].length - 1])`, and `(strs[1][0] <= strs[1][1] <= ... <= strs[1][strs[1].length - 1])`, and so on). Return *the minimum possible value of* `answer.length`.
### Examples
```
Input: strs = ["babca","bbazb"]
Output: 3
Explanation: After deleting columns 0, 1, and 4, the final array is strs = ["bc", "az"].
Both these rows are individually in lexicographic order (ie. strs[0][0] <= strs[0][1] and strs[1][0] <= strs[1][1]).
Note that strs[0] > strs[1] - the array strs is not necessarily in lexicographic order.
```
```
Input: strs = ["edcba"]
Output: 4
Explanation: If we delete less than 4 columns, the only row will not be lexicographically sorted.
```
```
Input: strs = ["ghi","def","abc"]
Output: 0
Explanation: All rows are already lexicographically sorted.
```
### Constraints
* n == strs.length
* 1 \<= n \<= 100
* 1 \<= strs\[i].length \<= 100
* strs\[i] consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_columns_to_make_sorted_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_columns_to_make_sorted_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m^2 * n) where m is column count and n is row count
# Space: O(m)
def min_deletion_size(self, strs: list[str]) -> int:
rows = len(strs)
cols = len(strs[0])
# best[j] = max number of columns we can keep ending with column j
best = [1] * cols
for j in range(cols):
for i in range(j):
if all(strs[r][i] <= strs[r][j] for r in range(rows)):
best[j] = max(best[j], best[i] + 1)
return cols - max(best)
```
## Complexity
| Time | Space |
| ------------------------------------------------------ | ----- |
| O(m^2 \* n) where m is column count and n is row count | O(m) |
## Tags
# Delete Leaves With a Given Value
Source: https://leetcode-py.wisl.dev/problems/delete-leaves-with-a-given-value
Tested Python solution for LeetCode 1325 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1325, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/delete-leaves-with-a-given-value/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1325 # by problem number
lcpy gen -s delete_leaves_with_a_given_value # by problem name
```
## Problem
Given a binary tree `root` and an integer `target`, delete all the **leaf nodes** with value `target`.
Note that once you delete a leaf node with value `target`, if its parent node becomes a leaf node and has the value `target`, it should also be deleted (you need to continue doing that until you cannot).
### Examples

```
Input: root = [1,2,3,2,null,2,4], target = 2
Output: [1,null,3,null,4]
Explanation: Leaf nodes in green with value (target = 2) are removed (Picture in left).
After removing, new nodes become leaf nodes with value (target = 2) (Picture in center).
```

```
Input: root = [1,3,3,3,2], target = 3
Output: [1,3,null,null,2]
```

```
Input: root = [1,2,null,2,null,2], target = 2
Output: [1]
Explanation: Leaf nodes in green with value (target = 2) are removed at each step.
```
### Constraints
* The number of nodes in the tree is in the range `[1, 3000]`
* `1 <= Node.val, target <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_leaves_with_a_given_value/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_leaves_with_a_given_value/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) — visits each node once in post-order
# Space: O(h) recursion stack, h = tree height
def remove_leaf_nodes(self, root: TreeNode[int] | None, target: int) -> TreeNode[int] | None:
if root is None:
return None
root.left = self.remove_leaf_nodes(root.left, target)
root.right = self.remove_leaf_nodes(root.right, target)
# Post-order: decide after children are pruned, so a node whose children
# were just removed can itself qualify as a target leaf.
if root.left is None and root.right is None and root.val == target:
return None
return root
```
## Complexity
| Time | Space |
| ------------------------------------------ | ------------------------------------- |
| O(n) — visits each node once in post-order | O(h) recursion stack, h = tree height |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Delete N Nodes After M Nodes of a Linked List
Source: https://leetcode-py.wisl.dev/problems/delete-n-nodes-after-m-nodes-of-a-linked-list
Tested Python solution for LeetCode 1474 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1474, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/delete-n-nodes-after-m-nodes-of-a-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1474 # by problem number
lcpy gen -s delete_n_nodes_after_m_nodes_of_a_linked_list # by problem name
```
## Problem
You are given the `head` of a linked list and two integers `m` and `n`.
Traverse the linked list and remove some nodes in the following way:
* Start with the head as the current node.
* Keep the first `m` nodes starting with the current node.
* Remove the next `n` nodes
* Keep repeating steps 2 and 3 until you reach the end of the list.
Return *the head of the modified list after removing the mentioned nodes*.
### Examples

```
Input: head = [1,2,3,4,5,6,7,8,9,10,11,12,13], m = 2, n = 3
Output: [1,2,6,7,11,12]
Explanation: Keep the first (m = 2) nodes starting from the head of the linked List (1 -> 2) show in black nodes.
Delete the next (n = 3) nodes (3 -> 4 -> 5) show in red nodes.
Continue with the same procedure until reaching the tail of the Linked List.
Head of the linked list after removing nodes is returned.
```

```
Input: head = [1,2,3,4,5,6,7,8,9,10,11], m = 1, n = 3
Output: [1,5,9]
Explanation: Head of linked list after removing nodes is returned.
```
### Constraints
* The number of nodes in the list is in the range `[1, 10^4]`.
* `1 <= Node.val <= 10^6`
* `1 <= m, n <= 1000`
**Follow up:** Could you solve this problem by modifying the list in-place?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_n_nodes_after_m_nodes_of_a_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_n_nodes_after_m_nodes_of_a_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(len(head))
# Space: O(1)
def delete_nodes(self, head: ListNode[int] | None, m: int, n: int) -> ListNode[int] | None:
pre = head
while pre:
for _ in range(m - 1):
if pre.next:
pre = pre.next
cur = pre
for _ in range(n):
if cur.next:
cur = cur.next
pre.next = cur.next
pre = pre.next
return head
```
## Complexity
| Time | Space |
| ------------ | ----- |
| O(len(head)) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Delete Node in a BST Python Solution
Source: https://leetcode-py.wisl.dev/problems/delete-node-in-a-bst
Tested Python solution for LeetCode 450 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 450, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/delete-node-in-a-bst/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 450 # by problem number
lcpy gen -s delete_node_in_a_bst # by problem name
```
## Problem
Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return *the **root node reference** (possibly updated) of the BST*.
Basically, the deletion can be divided into two stages:
1. Search for a node to remove.
2. If the node is found, delete the node.
Note: When a node with two children is deleted, replacing it with either its inorder successor or predecessor is accepted.
### Examples

```
Input: root = [5,3,6,2,4,null,7], key = 3
Output: [5,4,6,2,null,null,7]
Explanation: One valid answer is [5,4,6,2,null,null,7]; [5,2,6,null,4,null,7] is also accepted.
```
```
Input: root = [5,3,6,2,4,null,7], key = 0
Output: [5,3,6,2,4,null,7]
Explanation: The tree does not contain a node with value = 0.
```
```
Input: root = [], key = 0
Output: []
```
### Constraints
* The number of nodes in the tree is in the range \[0, 10^4].
* -10^5 \<= Node.val \<= 10^5
* Each node has a unique value.
* `root` is a valid binary search tree.
* -10^5 \<= key \<= 10^5
**Follow up:** Could you solve it with time complexity O(height of tree)?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_node_in_a_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_node_in_a_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(h) where h is the height of the tree
# Space: O(h) recursion stack
def delete_node(self, root: TreeNode[int] | None, key: int) -> TreeNode[int] | None:
if root is None:
return None
if key < root.val:
root.left = self.delete_node(root.left, key)
elif key > root.val:
root.right = self.delete_node(root.right, key)
else:
# Node found: handle deletion by child count.
if root.left is None:
return root.right
if root.right is None:
return root.left
# Two children: replace value with inorder successor, delete successor.
successor = root.right
while successor.left is not None:
successor = successor.left
root.val = successor.val
root.right = self.delete_node(root.right, successor.val)
return root
```
## Complexity
| Time | Space |
| -------------------------------------- | -------------------- |
| O(h) where h is the height of the tree | O(h) recursion stack |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Delete Node in a Linked List Python Solution
Source: https://leetcode-py.wisl.dev/problems/delete-node-in-a-linked-list
Tested Python solution for LeetCode 237 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 237, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/delete-node-in-a-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 237 # by problem number
lcpy gen -s delete_node_in_a_linked_list # by problem name
```
## Problem
There is a singly-linked list `head` and we want to delete a node `node` in it.
You are given the node to be deleted `node`. You will **not be given access** to the first node of `head`.
All the values of the linked list are **unique**, and it is guaranteed that the given node `node` is not the last node in the linked list.
Delete the given node. Note that by deleting the node, we do not mean removing it from memory. We mean:
* The value of the given node should not exist in the linked list.
* The number of nodes in the linked list should decrease by one.
* All the values before `node` should be in the same order.
* All the values after `node` should be in the same order.
**Custom testing:**
* For the input, you should provide the entire linked list `head` and the node to be given `node`. `node` should not be the last node of the list and should be an actual node in the list.
* We will build the linked list and pass the node to your function.
* The output will be the entire list after calling your function.
### Examples

```
Input: head = [4,5,1,9], node = 5
Output: [4,1,9]
Explanation: You are given the second node with value 5, the linked list should become 4 -> 1 -> 9 after calling your function.
```

```
Input: head = [4,5,1,9], node = 1
Output: [4,5,9]
Explanation: You are given the third node with value 1, the linked list should become 4 -> 5 -> 9 after calling your function.
```
### Constraints
* The number of the nodes in the given list is in the range `[2, 1000]`.
* `-1000 <= Node.val <= 1000`
* The value of each node in the list is **unique**.
* The `node` to be deleted is **in the list** and is **not a tail** node.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_node_in_a_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_node_in_a_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(1)
# Space: O(1)
def delete_node(self, node: ListNode[int]) -> None:
# Given node is never the tail, so copy the successor into it and skip it
nxt = node.next
if nxt is None:
return
node.val = nxt.val
node.next = nxt.next
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
# Delete Nodes And Return Forest Python Solution
Source: https://leetcode-py.wisl.dev/problems/delete-nodes-and-return-forest
Tested Python solution for LeetCode 1110 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 1110, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/delete-nodes-and-return-forest/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1110 # by problem number
lcpy gen -s delete_nodes_and_return_forest # by problem name
```
## Problem
Given the \root\ of a binary tree, each node in the tree has a \distinct\ value.
After deleting all nodes with a value in \to\_delete\, we are left with a forest (a disjoint union of trees).
Return the roots of the trees in the remaining forest. You may return them in any order.
### Examples

```
Input: root = [1,2,3,4,5,6,7], to_delete = [3,5]
Output: [[1,2,null,4],[6],[7]]
```
```
Input: root = [1,2,4,null,3], to_delete = [3]
Output: [[1,2,4]]
```
### Constraints
* The number of nodes in the given tree is at most \1000\.
* Each node has a \distinct\ value between \1\ and \1000\.
* \to\_delete.length \<= 1000\
* \to\_delete\ contains distinct values between \1\ and \1000\.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_nodes_and_return_forest/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_nodes_and_return_forest/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(n)
def del_nodes(self, root: TreeNode[int] | None, to_delete: list[int]) -> list[TreeNode[int]]:
delete = set(to_delete)
forest: list[TreeNode[int]] = []
def dfs(node: TreeNode[int] | None, is_root: bool) -> TreeNode[int] | None:
if node is None:
return None
deleted = node.val in delete
if is_root and not deleted:
forest.append(node)
node.left = dfs(node.left, deleted)
node.right = dfs(node.right, deleted)
return None if deleted else node
dfs(root, True)
return forest
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Delete Nodes From Linked List Present in Array
Source: https://leetcode-py.wisl.dev/problems/delete-nodes-from-linked-list-present-in-array
Tested Python solution for LeetCode 3217 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 3217, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/delete-nodes-from-linked-list-present-in-array/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3217 # by problem number
lcpy gen -s delete_nodes_from_linked_list_present_in_array # by problem name
```
## Problem
You are given an array of integers `nums` and the `head` of a linked list. Return the `head` of the modified linked list after \removing\ all nodes from the linked list that have a value that exists in `nums`.
### Examples

```
Input: nums = [1,2,3], head = [1,2,3,4,5]
Output: [4,5]
Explanation: Remove the nodes with values 1, 2, and 3.
```

```
Input: nums = [1], head = [1,2,1,2,1,2]
Output: [2,2,2]
Explanation: Remove the nodes with value 1.
```

```
Input: nums = [5], head = [1,2,3,4]
Output: [1,2,3,4]
Explanation: No node has value 5.
```
### Constraints
* 1 \<= nums.length \<= 10\5\
* 1 \<= nums\[i] \<= 10\5\
* All elements in nums are unique.
* The number of nodes in the given list is in the range \[1, 10\5\].
* 1 \<= Node.val \<= 10\5\
* The input is generated such that there is at least one node in the linked list that has a value not present in nums.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_nodes_from_linked_list_present_in_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_nodes_from_linked_list_present_in_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n + m) where n = len(nums), m = list length
# Space: O(n) for the value set
def modified_list(self, nums: list[int], head: ListNode[int] | None) -> ListNode[int] | None:
drop = set(nums)
dummy: ListNode[int] = ListNode(0)
tail = dummy
node = head
while node is not None:
nxt = node.next
if node.val not in drop:
tail.next = node
tail = node
node.next = None
node = nxt
return dummy.next
```
## Complexity
| Time | Space |
| --------------------------------------------- | ---------------------- |
| O(n + m) where n = len(nums), m = list length | O(n) for the value set |
## Tags
[NeetCode All](/catalog/neetcode).
# Delete Operation for Two Strings
Source: https://leetcode-py.wisl.dev/problems/delete-operation-for-two-strings
Tested Python solution for LeetCode 583 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 583, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), Longest Common Subsequence. [View on LeetCode](https://leetcode.com/problems/delete-operation-for-two-strings/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 583 # by problem number
lcpy gen -s delete_operation_for_two_strings # by problem name
```
## Problem
Given two strings `word1` and `word2`, return *the minimum number of steps* required to make `word1` and `word2` the same.
In one step, you can delete exactly one character in either string.
### Examples
```
Input: word1 = "sea", word2 = "eat"
Output: 2
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
```
```
Input: word1 = "leetcode", word2 = "etco"
Output: 4
```
### Constraints
* 1 \<= word1.length, word2.length \<= 500
* word1 and word2 consist of only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_operation_for_two_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_operation_for_two_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m)
# Space: O(m)
def min_distance(self, word1: str, word2: str) -> int:
m = len(word2)
prev = list(range(m + 1))
for i in range(1, len(word1) + 1):
curr = [i] + [0] * m
for j in range(1, m + 1):
if word1[i - 1] == word2[j - 1]:
curr[j] = prev[j - 1]
else:
curr[j] = 1 + min(prev[j], curr[j - 1])
prev = curr
return prev[m]
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(n \* m) | O(m) |
## Tags
# Delete Tree Nodes Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/delete-tree-nodes
Tested Python solution for LeetCode 1273 with 38 pytest cases. Generate a practice environment with lcpy.
LeetCode 1273, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Array](/catalog/topics/array), Tree DP. [View on LeetCode](https://leetcode.com/problems/delete-tree-nodes/description/).
Generate this problem as a practice environment: tested reference solution, 38 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1273 # by problem number
lcpy gen -s delete_tree_nodes # by problem name
```
## Problem
A tree rooted at node 0 is given as follows:
\nodes\;\i\th\\ node is \value\[i]\;\i\th\\ node is \parent\[i]\.\Remove every subtree whose sum of values of nodes is zero.\
\Return \the number of the remaining nodes in the tree\.\
### Examples  ``` Input: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-1] Output: 2 ``` ``` Input: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-2] Output: 6 ``` ### Constraints * 1 \<= nodes \<= 10^4 * parent.length == nodes * 0 \<= parent\[i] \<= nodes - 1 * parent\[0] == -1 which indicates that 0 is the root. * value.length == nodes * -10^5 \<= value\[i] \<= 10^5 * The given input is \guaranteed\ to represent a \valid tree\. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_tree_nodes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/delete_tree_nodes/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(nodes) # Space: O(nodes) def delete_tree_nodes(self, nodes: int, parent: list[int], value: list[int]) -> int: children: list[list[int]] = [[] for _ in range(nodes)] for i in range(1, nodes): children[parent[i]].append(i) # Iterative post-order keeps deep chains within the recursion limit. subtree_sums = [0] * nodes subtree_counts = [0] * nodes stack: list[tuple[int, bool]] = [(0, False)] while stack: node, processed = stack.pop() if processed: total, count = value[node], 1 for child in children[node]: total += subtree_sums[child] count += subtree_counts[child] if total == 0: count = 0 subtree_sums[node], subtree_counts[node] = total, count else: stack.append((node, True)) stack.extend((child, False) for child in children[node]) return subtree_counts[0] ``` ## Complexity | Time | Space | | -------- | -------- | | O(nodes) | O(nodes) | ## Tags # Design a Food Rating System Python Solution Source: https://leetcode-py.wisl.dev/problems/design-a-food-rating-system Tested Python solution for LeetCode 2353 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 2353, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Design](/catalog/topics/design), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/design-a-food-rating-system/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2353 # by problem number lcpy gen -s design_a_food_rating_system # by problem name ``` ## Problem Design a food rating system that can do the following: * Modify the rating of a food item listed in the system. * Return the highest-rated food item for a type of cuisine in the system. Implement the `FoodRatings` class: * `FoodRatings(String[] foods, String[] cuisines, int[] ratings)` Initializes the system. The food items are described by `foods`, `cuisines`, and `ratings`, all of which have a length of `n`. * `foods[i]` is the name of the `i`th food, * `cuisines[i]` is the type of cuisine of the `i`th food, and * `ratings[i]` is the initial rating of the `i`th food. * `void changeRating(String food, int newRating)` Changes the rating of the food item with the name `food`. * `String highestRated(String cuisine)` Returns the name of the food item that has the highest rating for the given type of cuisine. If there is a tie, return the item with the **lexicographically smaller** name. Note that a string `x` is lexicographically smaller than string `y` if `x` comes before `y` in dictionary order, that is, either `x` is a prefix of `y`, or if `i` is the first position such that `x[i] != y[i]`, then `x[i]` comes before `y[i]` in alphabetic order. ### Examples ``` Input ["FoodRatings", "highestRated", "highestRated", "changeRating", "highestRated", "changeRating", "highestRated"] [[["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]], ["korean"], ["japanese"], ["sushi", 16], ["japanese"], ["ramen", 16], ["japanese"]] Output [null, "kimchi", "ramen", null, "sushi", null, "ramen"] Explanation foodRatings.highestRated("korean"); // return "kimchi" // "kimchi" is the highest rated korean food with a rating of 9. foodRatings.highestRated("japanese"); // return "ramen" // "ramen" is the highest rated japanese food with a rating of 14. foodRatings.changeRating("sushi", 16); // "sushi" now has a rating of 16. foodRatings.highestRated("japanese"); // return "sushi" foodRatings.changeRating("ramen", 16); // "ramen" now has a rating of 16. foodRatings.highestRated("japanese"); // return "ramen" // Both "sushi" and "ramen" have a rating of 16. // However, "ramen" is lexicographically smaller than "sushi". ``` ### Constraints * `1 <= n <= 2 * 10^4` * `n == foods.length == cuisines.length == ratings.length` * `1 <= foods[i].length, cuisines[i].length <= 10` * `foods[i]`, `cuisines[i]` consist of lowercase English letters. * `1 <= ratings[i] <= 10^8` * All the strings in `foods` are **distinct**. * `food` will be the name of a food item in the system across all calls to `changeRating`. * `cuisine` will be a type of cuisine of **at least one** food item in the system across all calls to `highestRated`. * At most `2 * 10^4` calls **in total** will be made to `changeRating` and `highestRated`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_a_food_rating_system/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_a_food_rating_system/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import heapq class FoodRatings: # Time: init O(n), change_rating O(log n), highest_rated amortized O(log n) # Space: O(n) for the rating/cuisine maps and one lazy heap per cuisine def __init__(self, foods: list[str], cuisines: list[str], ratings: list[int]) -> None: self.rating: dict[str, int] = dict(zip(foods, ratings, strict=True)) self.cuisine = dict(zip(foods, cuisines, strict=True)) self.heaps: dict[str, list[tuple[int, str]]] = {} for food, cuisine, rating in zip(foods, cuisines, ratings, strict=True): self.heaps.setdefault(cuisine, []).append((-rating, food)) for heap in self.heaps.values(): heapq.heapify(heap) # Time: O(log n) # Space: O(1) amortized (each pushed entry is popped at most once) def change_rating(self, food: str, new_rating: int) -> None: self.rating[food] = new_rating # The old entry for this food is left behind as stale; highest_rated # discards entries whose rating no longer matches the current one. heapq.heappush(self.heaps[self.cuisine[food]], (-new_rating, food)) # Time: O(log n) amortized # Space: O(1) def highest_rated(self, cuisine: str) -> str: heap = self.heaps[cuisine] while True: neg_rating, food = heap[0] if -neg_rating == self.rating[food]: return food heapq.heappop(heap) ``` ## Complexity | Time | Space | | --------------------------------------------------------------------- | -------------------------------------------------------------- | | init O(n), change\_rating O(log n), highest\_rated amortized O(log n) | O(n) for the rating/cuisine maps and one lazy heap per cuisine | ## Tags [NeetCode All](/catalog/neetcode). # Design A Leaderboard Python Solution Source: https://leetcode-py.wisl.dev/problems/design-a-leaderboard Tested Python solution for LeetCode 1244 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 1244, [Medium](/catalog/medium). Topics: [Design](/catalog/topics/design), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/design-a-leaderboard/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1244 # by problem number lcpy gen -s design_a_leaderboard # by problem name ``` ## Problem Design a Leaderboard class, which has 3 functions: * `addScore(playerId, score)`: Update the leaderboard by adding `score` to the given player's score. If there is no player with such id in the leaderboard, add him to the leaderboard with the given `score`. * `top(K)`: Return the score sum of the top `K` players. * `reset(playerId)`: Reset the score of the player with the given id to 0 (in other words erase it from the leaderboard). It is guaranteed that the player was added to the leaderboard before calling this function. Initially, the leaderboard is empty. ### Examples ``` Input: ["Leaderboard","addScore","addScore","addScore","addScore","addScore","top","reset","reset","addScore","top"] [[],[1,73],[2,56],[3,39],[4,51],[5,4],[1],[1],[2],[2,51],[3]] Output: [null,null,null,null,null,null,73,null,null,null,141] Explanation Leaderboard leaderboard = new Leaderboard(); leaderboard.addScore(1,73); // leaderboard = [[1,73]]; leaderboard.addScore(2,56); // leaderboard = [[1,73],[2,56]]; leaderboard.addScore(3,39); // leaderboard = [[1,73],[2,56],[3,39]]; leaderboard.addScore(4,51); // leaderboard = [[1,73],[2,56],[3,39],[4,51]]; leaderboard.addScore(5,4); // leaderboard = [[1,73],[2,56],[3,39],[4,51],[5,4]]; leaderboard.top(1); // returns 73; leaderboard.reset(1); // leaderboard = [[2,56],[3,39],[4,51],[5,4]]; leaderboard.reset(2); // leaderboard = [[3,39],[4,51],[5,4]]; leaderboard.addScore(2,51); // leaderboard = [[2,51],[3,39],[4,51],[5,4]]; leaderboard.top(3); // returns 141 = 51 + 51 + 39; ``` ### Constraints * `1 <= playerId, K <= 10^4` * It's guaranteed that `K` is less than or equal to the current number of players. * `1 <= score <= 100` * At most `1000` function calls will be made. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_a_leaderboard/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_a_leaderboard/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import heapq class Leaderboard: # Time: add_score O(1), top O(n log k), reset O(1) # Space: O(n) where n is the number of players on the leaderboard def __init__(self) -> None: self.scores: dict[int, int] = {} # Time: O(1) # Space: O(1) def add_score(self, player_id: int, score: int) -> None: self.scores[player_id] = self.scores.get(player_id, 0) + score # Time: O(n log k) # Space: O(k) def top(self, k: int) -> int: return sum(heapq.nlargest(k, self.scores.values())) # Time: O(1) # Space: O(1) def reset(self, player_id: int) -> None: del self.scores[player_id] ``` ## Complexity | Time | Space | | ------------------------------------------- | -------------------------------------------------------- | | add\_score O(1), top O(n log k), reset O(1) | O(n) where n is the number of players on the leaderboard | ## Tags [NeetCode All](/catalog/neetcode). # Design Add and Search Words Data Structure Source: https://leetcode-py.wisl.dev/problems/design-add-and-search-words-data-structure Tested Python solution for LeetCode 211 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 211, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Depth-First Search](/catalog/topics/depth-first-search), [Design](/catalog/topics/design), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/design-add-and-search-words-data-structure/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 211 # by problem number lcpy gen -s design_add_and_search_words_data_structure # by problem name ``` ## Problem Design a data structure that supports adding new words and finding if a string matches any previously added string. Implement the `WordDictionary` class: * `WordDictionary()` Initializes the object. * `void addWord(word)` Adds `word` to the data structure, it can be matched later. * `bool search(word)` Returns `true` if there is any string in the data structure that matches `word` or `false` otherwise. `word` may contain dots `'.'` where dots can be matched with any letter. ### Examples ``` Input ["WordDictionary","addWord","addWord","addWord","search","search","search","search"] [[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]] Output [null,null,null,null,false,true,true,true] Explanation WordDictionary wordDictionary = new WordDictionary(); wordDictionary.addWord("bad"); wordDictionary.addWord("dad"); wordDictionary.addWord("mad"); wordDictionary.search("pad"); // return False wordDictionary.search("bad"); // return True wordDictionary.search(".ad"); // return True wordDictionary.search("b.."); // return True ``` ### Constraints * `1 <= word.length <= 25` * `word` in `addWord` consists of lowercase English letters. * `word` in `search` consist of `'.'` or lowercase English letters. * There will be at most `2` dots in `word` for `search` queries. * At most `10^4` calls will be made to `addWord` and `search`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_add_and_search_words_data_structure/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_add_and_search_words_data_structure/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from typing import Any class WordDictionary: # Time: O(1) # Space: O(1) def __init__(self) -> None: self.root: dict[str, Any] = {} # Time: O(m) where m = len(word) # Space: O(m) for new word def add_word(self, word: str) -> None: node = self.root for char in word: if char not in node: node[char] = {} node = node[char] node["#"] = True # Time: O(n * 26^k) where n = len(word), k = number of dots # Space: O(n) for recursion stack def search(self, word: str) -> bool: def dfs(i: int, node: dict[str, Any]) -> bool: if i == len(word): return "#" in node char = word[i] if char == ".": return any(key != "#" and dfs(i + 1, node[key]) for key in node) else: return char in node and dfs(i + 1, node[char]) return dfs(0, self.root) ``` ## Complexity | Time | Space | | ---- | ----- | | O(1) | O(1) | ## Tags [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Design Browser History Python Solution Source: https://leetcode-py.wisl.dev/problems/design-browser-history Tested Python solution for LeetCode 1472 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 1472, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Linked List](/catalog/topics/linked-list), [Stack](/catalog/topics/stack), [Design](/catalog/topics/design), Doubly-Linked List, [Data Stream](/catalog/topics/data-stream). [View on LeetCode](https://leetcode.com/problems/design-browser-history/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1472 # by problem number lcpy gen -s design_browser_history # by problem name ``` ## Problem You have a **browser** of one tab where you start on the `homepage` and you can visit another `url`, get back in the history number of `steps` or move forward in the history number of `steps`. Implement the `BrowserHistory` class: * `BrowserHistory(string homepage)` Initializes the object with the `homepage` of the browser. * `void visit(string url)` Visits `url` from the current page. It clears up all the forward history. * `string back(int steps)` Move `steps` back in history. If you can only return `x` steps in the history and `steps > x`, you will return only `x` steps. Return the current `url` after moving back in history **at most** `steps`. * `string forward(int steps)` Move `steps` forward in history. If you can only forward `x` steps in the history and `steps > x`, you will forward only `x` steps. Return the current `url` after forwarding in history **at most** `steps`. ### Examples ``` Input ["BrowserHistory","visit","visit","visit","back","back","forward","visit","forward","back","back"] [["leetcode.com"],["google.com"],["facebook.com"],["youtube.com"],[1],[1],[1],["linkedin.com"],[2],[2],[7]] Output [null,null,null,null,"facebook.com","google.com","facebook.com",null,"linkedin.com","google.com","leetcode.com"] ``` **Explanation:** ``` BrowserHistory browserHistory = new BrowserHistory("leetcode.com"); browserHistory.visit("google.com"); // You are in "leetcode.com". Visit "google.com" browserHistory.visit("facebook.com"); // You are in "google.com". Visit "facebook.com" browserHistory.visit("youtube.com"); // You are in "facebook.com". Visit "youtube.com" browserHistory.back(1); // You are in "youtube.com", move back to "facebook.com" return "facebook.com" browserHistory.back(1); // You are in "facebook.com", move back to "google.com" return "google.com" browserHistory.forward(1); // You are in "google.com", move forward to "facebook.com" return "facebook.com" browserHistory.visit("linkedin.com"); // You are in "facebook.com". Visit "linkedin.com" browserHistory.forward(2); // You are in "linkedin.com", you cannot move forward any steps. browserHistory.back(2); // You are in "linkedin.com", move back two steps to "facebook.com" then to "google.com". return "google.com" browserHistory.back(7); // You are in "google.com", you can move back only one step to "leetcode.com". return "leetcode.com" ``` ### Constraints * `1 <= homepage.length <= 20` * `1 <= url.length <= 20` * `1 <= steps <= 100` * `homepage` and `url` consist of `'.'` or lower case English letters. * At most `5000` calls will be made to `visit`, `back`, and `forward`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_browser_history/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_browser_history/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class BrowserHistory: # Time: __init__ O(1), visit O(n), back O(steps), forward O(steps) # Space: O(n) def __init__(self, homepage: str) -> None: self.history: list[str] = [homepage] self.cur = 0 def visit(self, url: str) -> None: del self.history[self.cur + 1 :] self.history.append(url) self.cur += 1 def back(self, steps: int) -> str: self.cur = max(0, self.cur - steps) return self.history[self.cur] def forward(self, steps: int) -> str: self.cur = min(len(self.history) - 1, self.cur + steps) return self.history[self.cur] ``` ## Complexity | Time | Space | | ---------------------------------------------------------- | ----- | | **init** O(1), visit O(n), back O(steps), forward O(steps) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Design Circular Deque Python Solution Source: https://leetcode-py.wisl.dev/problems/design-circular-deque Tested Python solution for LeetCode 641 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 641, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Linked List](/catalog/topics/linked-list), [Design](/catalog/topics/design), [Queue](/catalog/topics/queue). [View on LeetCode](https://leetcode.com/problems/design-circular-deque/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 641 # by problem number lcpy gen -s design_circular_deque # by problem name ``` ## Problem Design your implementation of the circular double-ended queue (deque). Implement the `MyCircularDeque` class: * `MyCircularDeque(int k)` Initializes the deque with a maximum size of `k`. * `boolean insertFront()` Adds an item at the front of Deque. Returns `true` if the operation is successful, or `false` otherwise. * `boolean insertLast()` Adds an item at the rear of Deque. Returns `true` if the operation is successful, or `false` otherwise. * `boolean deleteFront()` Deletes an item from the front of Deque. Returns `true` if the operation is successful, or `false` otherwise. * `boolean deleteLast()` Deletes an item from the rear of Deque. Returns `true` if the operation is successful, or `false` otherwise. * `int getFront()` Returns the front item from the Deque. Returns `-1` if the deque is empty. * `int getRear()` Returns the last item from Deque. Returns `-1` if the deque is empty. * `boolean isEmpty()` Returns `true` if the deque is empty, or `false` otherwise. * `boolean isFull()` Returns `true` if the deque is full, or `false` otherwise. ### Examples ``` Input ["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"] [[3], [1], [2], [3], [4], [], [], [], [4], []] Output [null, true, true, true, false, 2, true, true, true, 4] Explanation MyCircularDeque myCircularDeque = new MyCircularDeque(3); myCircularDeque.insertLast(1); // return True myCircularDeque.insertLast(2); // return True myCircularDeque.insertFront(3); // return True myCircularDeque.insertFront(4); // return False, the queue is full. myCircularDeque.getRear(); // return 2 myCircularDeque.isFull(); // return True myCircularDeque.deleteLast(); // return True myCircularDeque.insertFront(4); // return True myCircularDeque.getFront(); // return 4 ``` ### Constraints * `1 <= k <= 1000` * `0 <= value <= 1000` * At most `2000` calls will be made to `insertFront`, `insertLast`, `deleteFront`, `deleteLast`, `getFront`, `getRear`, `isEmpty`, `isFull`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_circular_deque/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_circular_deque/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class MyCircularDeque: # Fixed-size ring buffer: head is the front slot, size tracks occupancy. # All operations are O(1) time and the buffer holds at most k ints. def __init__(self, k: int) -> None: self.buf: list[int] = [-1] * k self.capacity = k self.size = 0 self.head = 0 def insert_front(self, value: int) -> bool: if self.is_full(): return False self.head = (self.head - 1) % self.capacity self.buf[self.head] = value self.size += 1 return True def insert_last(self, value: int) -> bool: if self.is_full(): return False self.buf[(self.head + self.size) % self.capacity] = value self.size += 1 return True def delete_front(self) -> bool: if self.is_empty(): return False self.head = (self.head + 1) % self.capacity self.size -= 1 return True def delete_last(self) -> bool: if self.is_empty(): return False self.size -= 1 return True def get_front(self) -> int: if self.is_empty(): return -1 return self.buf[self.head] def get_rear(self) -> int: if self.is_empty(): return -1 return self.buf[(self.head + self.size - 1) % self.capacity] def is_empty(self) -> bool: return self.size == 0 def is_full(self) -> bool: return self.size == self.capacity ``` ## Complexity | Time | Space | | ---- | ----- | | - | - | ## Tags # Design Circular Queue Python Solution Source: https://leetcode-py.wisl.dev/problems/design-circular-queue Tested Python solution for LeetCode 622 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 622, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Linked List](/catalog/topics/linked-list), [Design](/catalog/topics/design), [Queue](/catalog/topics/queue). [View on LeetCode](https://leetcode.com/problems/design-circular-queue/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 622 # by problem number lcpy gen -s design_circular_queue # by problem name ``` ## Problem Design your implementation of the circular queue. The circular queue is a linear data structure that operates on the FIFO (First In First Out) principle, with the last position connected back to the first to form a circle (a "Ring Buffer"). Implement the `MyCircularQueue` class: * `MyCircularQueue(k)` Initializes the object with the queue size `k`. * `int Front()` Gets the front item; returns `-1` if empty. * `int Rear()` Gets the last item; returns `-1` if empty. * `boolean enQueue(int value)` Inserts an element. Returns `true` if successful. * `boolean deQueue()` Deletes an element from the queue. Returns `true` if successful. * `boolean isEmpty()` Checks whether the queue is empty. * `boolean isFull()` Checks whether the queue is full. You must solve the problem without using the built-in queue data structure. ### Examples ``` Input ["MyCircularQueue", "enQueue", "enQueue", "enQueue", "enQueue", "Rear", "isFull", "deQueue", "enQueue", "Rear"] [[3], [1], [2], [3], [4], [], [], [], [4], []] Output [null, true, true, true, false, 3, true, true, true, 4] Explanation myCircularQueue = MyCircularQueue(3); myCircularQueue.enQueue(1); // True myCircularQueue.enQueue(2); // True myCircularQueue.enQueue(3); // True myCircularQueue.enQueue(4); // False, queue is full myCircularQueue.Rear(); // 3 myCircularQueue.isFull(); // True myCircularQueue.deQueue(); // True myCircularQueue.enQueue(4); // True myCircularQueue.Rear(); // 4 ``` ### Constraints * 1 \<= k \<= 1000 * 0 \<= value \<= 1000 * At most 3000 calls will be made to enQueue, deQueue, Front, Rear, isEmpty, and isFull. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_circular_queue/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_circular_queue/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class MyCircularQueue: # Time: O(1) per operation # Space: O(k) def __init__(self, k: int) -> None: self.capacity = k self.data: list[int] = [0] * k self.head = 0 self.size = 0 # Time: O(1) # Space: O(1) def en_queue(self, value: int) -> bool: if self.is_full(): return False tail_index = (self.head + self.size) % self.capacity self.data[tail_index] = value self.size += 1 return True # Time: O(1) # Space: O(1) def de_queue(self) -> bool: if self.is_empty(): return False self.head = (self.head + 1) % self.capacity self.size -= 1 return True # Time: O(1) # Space: O(1) def front(self) -> int: if self.is_empty(): return -1 return self.data[self.head] # Time: O(1) # Space: O(1) def rear(self) -> int: if self.is_empty(): return -1 tail_index = (self.head + self.size - 1) % self.capacity return self.data[tail_index] # Time: O(1) # Space: O(1) def is_empty(self) -> bool: return self.size == 0 # Time: O(1) # Space: O(1) def is_full(self) -> bool: return self.size == self.capacity ``` ## Complexity | Time | Space | | ------------------ | ----- | | O(1) per operation | O(k) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Design Compressed String Iterator Source: https://leetcode-py.wisl.dev/problems/design-compressed-string-iterator Tested Python solution for LeetCode 604 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 604, [Easy](/catalog/easy). Topics: [Design](/catalog/topics/design), [Array](/catalog/topics/array), [String](/catalog/topics/string), Iterator. [View on LeetCode](https://leetcode.com/problems/design-compressed-string-iterator/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 604 # by problem number lcpy gen -s design_compressed_string_iterator # by problem name ``` ## Problem Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string. Implement the `StringIterator` class: * `next()` Returns **the next character** if the original string still has uncompressed characters, otherwise returns a **white space**. * `has_next()` Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns `false`. ### Examples ``` Input ["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"] [["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []] Output [null, "L", "e", "e", "t", "C", "o", true, "d", true] Explanation StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1"); stringIterator.next(); // return "L" stringIterator.next(); // return "e" stringIterator.next(); // return "e" stringIterator.next(); // return "t" stringIterator.next(); // return "C" stringIterator.next(); // return "o" stringIterator.hasNext(); // return True stringIterator.next(); // return "d" stringIterator.hasNext(); // return True ``` ### Constraints * `1 <= compressedString.length <= 1000` * `compressedString` consists of lower-case an upper-case English letters and digits. * The number of a single character repetitions in `compressedString` is in the range `[1, 10^9]`. * At most `100` calls will be made to `next` and `hasNext`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_compressed_string_iterator/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_compressed_string_iterator/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class StringIterator: # Time: next/has_next O(1) amortized # Space: O(k) for k letter-count pairs def __init__(self, compressed_string: str) -> None: self.pairs: list[tuple[str, int]] = [] i = 0 while i < len(compressed_string): ch = compressed_string[i] i += 1 num = 0 while i < len(compressed_string) and compressed_string[i].isdigit(): num = num * 10 + int(compressed_string[i]) i += 1 self.pairs.append((ch, num)) self.idx = 0 def next(self) -> str: if self.idx >= len(self.pairs): return " " ch = self.pairs[self.idx][0] ch, count = self.pairs[self.idx] if count == 1: self.idx += 1 else: self.pairs[self.idx] = (ch, count - 1) return ch def has_next(self) -> bool: return self.idx < len(self.pairs) ``` ## Complexity | Time | Space | | ----------------------------- | ----------------------------- | | next/has\_next O(1) amortized | O(k) for k letter-count pairs | ## Tags [NeetCode All](/catalog/neetcode). # Design Excel Sum Formula Python Solution Source: https://leetcode-py.wisl.dev/problems/design-excel-sum-formula Tested Python solution for LeetCode 631 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 631, [Hard](/catalog/hard). Topics: [Graph](/catalog/topics/graph), [Design](/catalog/topics/design), [Topological Sort](/catalog/topics/topological-sort), [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/design-excel-sum-formula/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 631 # by problem number lcpy gen -s design_excel_sum_formula # by problem name ``` ## Problem Design the basic function of **Excel** and implement the function of the sum formula. Implement the `Excel` class: * `Excel(int height, char width)` Initializes the object with the `height` and the `width` of the sheet. The sheet is an integer matrix `mat` of size `height x width` with the row index in the range `[1, height]` and the column index in the range `['A', width]`. All the values should be **zero** initially. * `void set(int row, char column, int val)` Changes the value at `mat[row][column]` to be `val`. * `int get(int row, char column)` Returns the value at `mat[row][column]`. * `int sum(int row, char column, ListThe demons had captured the princess and imprisoned her in \the bottom-right corner\ of a \dungeon\. The \dungeon\ consists of \m x n\ rooms laid out in a 2D grid. Our valiant knight was initially positioned in \the top-left room\ and must fight his way through \dungeon\ to rescue the princess.\
The knight has an initial health point represented by a positive integer. If at any point his health point drops to \0\ or below, he dies immediately.\
Some of the rooms are guarded by demons (represented by negative integers), so the knight loses health upon entering these rooms; other rooms are either empty (represented as 0) or contain magic orbs that increase the knight's health (represented by positive integers).\
\To reach the princess as quickly as possible, the knight decides to move only \rightward\ or \downward\ in each step.\
\Return \the knight's minimum initial health so that he can rescue the princess\.\
\\Note\ that any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.\
### Examples  ``` Input: dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]] Output: 7 Explanation: The initial health of the knight must be at least 7 if he follows the optimal path: RIGHT -> RIGHT -> DOWN -> DOWN. ``` ``` Input: dungeon = [[0]] Output: 1 ``` ### Constraints * m == dungeon.length * n == dungeon\[i].length * 1 \<= m, n \<= 200 * -1000 \<= dungeon\[i]\[j] \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/dungeon_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/dungeon_game/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(n) def calculate_minimum_hp(self, dungeon: list[list[int]]) -> int: m, n = len(dungeon), len(dungeon[0]) # need[j]: minimum health required upon entering cell (i, j); right # sentinel need[n] = INF means "no cell to the right" outside the grid. need = [10**9] * (n + 1) need[n - 1] = 1 for i in range(m - 1, -1, -1): need[n] = 10**9 for j in range(n - 1, -1, -1): need[j] = max(1, min(need[j], need[j + 1]) - dungeon[i][j]) return need[0] ``` ## Complexity | Time | Space | | --------- | ----- | | O(m \* n) | O(n) | ## Tags # Edit Distance Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/edit-distance Tested Python solution for LeetCode 72 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 72, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/edit-distance/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 72 # by problem number lcpy gen -s edit_distance # by problem name ``` ## Problem Given two strings `word1` and `word2`, return *the minimum number of operations required to convert* `word1` *to* `word2`. You have the following three operations permitted on a word: * Insert a character * Delete a character * Replace a character ### Examples ``` Input: word1 = "horse", word2 = "ros" Output: 3 Explanation: horse -> rorse (replace 'h' with 'r') rorse -> rose (remove 'r') rose -> ros (remove 'e') ``` ``` Input: word1 = "intention", word2 = "execution" Output: 5 Explanation: intention -> inention (remove 't') inention -> enention (replace 'i' with 'e') enention -> exention (replace 'n' with 'x') exention -> exection (replace 'n' with 'c') exection -> execution (insert 'u') ``` ### Constraints * 0 \<= word1.length, word2.length \<= 500 * word1 and word2 consist of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/edit_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/edit_distance/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(n) using a single rolling row def min_distance(self, word1: str, word2: str) -> int: m, n = len(word1), len(word2) # dp[j] = edit distance between word1 prefix (current row) and word2[:j] prev = list(range(n + 1)) for i in range(1, m + 1): curr = [i] + [0] * n for j in range(1, n + 1): if word1[i - 1] == word2[j - 1]: curr[j] = prev[j - 1] else: curr[j] = 1 + min(prev[j], curr[j - 1], prev[j - 1]) prev = curr return prev[n] ``` ## Complexity | Time | Space | | --------- | ------------------------------- | | O(m \* n) | O(n) using a single rolling row | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Eliminate Maximum Number of Monsters Source: https://leetcode-py.wisl.dev/problems/eliminate-maximum-number-of-monsters Tested Python solution for LeetCode 1921 with 34 pytest cases. Generate a practice environment with lcpy. LeetCode 1921, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/eliminate-maximum-number-of-monsters/description/). Generate this problem as a practice environment: tested reference solution, 34 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1921 # by problem number lcpy gen -s eliminate_maximum_number_of_monsters # by problem name ``` ## Problem You are playing a video game where you are defending your city from a group of `n` monsters. You are given a **0-indexed** integer array `dist` of size `n`, where `dist[i]` is the **initial distance** in kilometers of the `i`th monster from the city. The monsters walk toward the city at a **constant** speed. The speed of each monster is given to you in an integer array `speed` of size `n`, where `speed[i]` is the speed of the `i`th monster in kilometers per minute. You have a weapon that, once fully charged, can eliminate a **single** monster. However, the weapon takes **one minute** to charge. The weapon is fully charged at the very start. You lose when any monster reaches your city. If a monster reaches the city at the exact moment the weapon is fully charged, it counts as a **loss**, and the game ends before you can use your weapon. Return the maximum number of monsters that you can eliminate before you lose, or `n` if you can eliminate all the monsters before they reach the city. ### Examples ``` Input: dist = [1,3,4], speed = [1,1,1] Output: 3 Explanation: In the beginning, the distances of the monsters are [1,3,4]. You eliminate the first monster. After a minute, the distances of the monsters are [X,2,3]. You eliminate the second monster. After a minute, the distances of the monsters are [X,X,2]. You eliminate the third monster. All 3 monsters can be eliminated. ``` ``` Input: dist = [1,1,2,3], speed = [1,1,1,1] Output: 1 Explanation: In the beginning, the distances of the monsters are [1,1,2,3]. You eliminate the first monster. After a minute, the distances of the monsters are [X,0,1,2], so you lose. You can only eliminate 1 monster. ``` ``` Input: dist = [3,2,4], speed = [5,3,2] Output: 1 Explanation: In the beginning, the distances of the monsters are [3,2,4]. You eliminate the first monster. After a minute, the distances of the monsters are [X,0,2], so you lose. You can only eliminate 1 monster. ``` ### Constraints * n == dist.length == speed.length * 1 \<= n \<= 10^5 * 1 \<= dist\[i], speed\[i] \<= 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/eliminate_maximum_number_of_monsters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/eliminate_maximum_number_of_monsters/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) def eliminate_maximum(self, dist: list[int], speed: list[int]) -> int: arrival = sorted(-(-d // s) for d, s in zip(dist, speed, strict=True)) for minute, time in enumerate(arrival): if time <= minute: return minute return len(arrival) ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Elimination Game Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/elimination-game Tested Python solution for LeetCode 390 with 34 pytest cases. Generate a practice environment with lcpy. LeetCode 390, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/elimination-game/description/). Generate this problem as a practice environment: tested reference solution, 34 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 390 # by problem number lcpy gen -s elimination_game # by problem name ``` ## Problem You have a list \arr\ of all integers in the range \\[1, n]\ sorted in a strictly increasing order. Apply the following algorithm on \arr\:
\Given the integer \n\, return \the last number that remains in\ \arr\.\
n\, return \the number of trailing zeroes in \\n!\.
\Note that \n! = n \* (n - 1) \* (n - 2) \* ... \* 3 \* 2 \* 1\.\
\Follow up:\ Could you write a solution that works in logarithmic time complexity?\
## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/factorial_trailing_zeroes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/factorial_trailing_zeroes/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log n) (base 5) # Space: O(1) def trailing_zeroes(self, n: int) -> int: zero_count = 0 while n > 0: n //= 5 zero_count += n return zero_count ``` ## Complexity | Time | Space | | ----------------- | ----- | | O(log n) (base 5) | O(1) | ## Tags # Fair Candy Swap Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/fair-candy-swap Tested Python solution for LeetCode 888 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 888, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/fair-candy-swap/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 888 # by problem number lcpy gen -s fair_candy_swap # by problem name ``` ## Problem Alice and Bob have a different total number of candies. You are given two integer arrays `aliceSizes` and `bobSizes` where `aliceSizes[i]` is the number of candies of the `i`th box of candy that Alice has and `bobSizes[j]` is the number of candies of the `j`th box of candy that Bob has. Since they are friends, they would like to exchange one candy box each so that after the exchange, they both have the same total amount of candy. The total amount of candy a person has is the sum of the number of candies in each box they have. Return an integer array `answer` where `answer[0]` is the number of candies in the box that Alice must exchange, and `answer[1]` is the number of candies in the box that Bob must exchange. If there are multiple answers, you may return any one of them. It is guaranteed that at least one answer exists. ### Examples ``` Input: aliceSizes = [1,1], bobSizes = [2,2] Output: [1,2] ``` ``` Input: aliceSizes = [1,2], bobSizes = [2,3] Output: [1,2] ``` ``` Input: aliceSizes = [2], bobSizes = [1,3] Output: [2,3] ``` ### Constraints * `1 <= aliceSizes.length, bobSizes.length <= 10^4` * `1 <= aliceSizes[i], bobSizes[j] <= 10^5` * Alice and Bob have a different total number of candies. * There will be at least one valid answer for the given input. **Follow up:** Can you solve it in `O(n)` time complexity? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/fair_candy_swap/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/fair_candy_swap/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n + m) # Space: O(m) def fair_candy_swap(self, alice_sizes: list[int], bob_sizes: list[int]) -> list[int]: delta = (sum(alice_sizes) - sum(bob_sizes)) // 2 bob_set = set(bob_sizes) for x in alice_sizes: y = x - delta if y in bob_set: return [x, y] return [] # unreachable: a valid answer is guaranteed ``` ## Complexity | Time | Space | | -------- | ----- | | O(n + m) | O(m) | ## Tags # Falling Squares Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/falling-squares Tested Python solution for LeetCode 699 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 699, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Segment Tree](/catalog/topics/segment-tree), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/falling-squares/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 699 # by problem number lcpy gen -s falling_squares # by problem name ``` ## Problem There are several squares being dropped onto the X-axis of a 2D plane. You are given a 2D integer array \positions\ where \positions\[i] = \[left\i\, sideLength\i\]\ represents the \i\th\\ square with a side length of \sideLength\i\\ that is dropped with its left edge aligned with X-coordinate \left\i\\.
Each square is dropped one at a time from a height above any landed squares. It then falls downward (negative Y direction) until it either lands \on the top side of another square\ or \on the X-axis\. A square brushing the left/right side of another square does not count as landing on it. Once it lands, it freezes in place and cannot be moved.
After each square is dropped, you must record the \height of the current tallest stack of squares\.
Return \an integer array \\ans\\ where \\ans\[i]\\ represents the height described above after dropping the \i\th\\\ square\.
### Examples

```
Input: positions = [[1,2],[2,3],[6,1]]
Output: [2,5,5]
```
**Explanation:** After the first drop, the tallest stack is square 1 with a height of 2. After the second drop, the tallest stack is squares 1 and 2 with a height of 5. After the third drop, the tallest stack is still squares 1 and 2 with a height of 5. Thus, we return an answer of \[2, 5, 5].
```
Input: positions = [[100,100],[200,100]]
Output: [100,100]
```
**Explanation:** After the first drop, the tallest stack is square 1 with a height of 100. After the second drop, the tallest stack is either square 1 or square 2, both with heights of 100. Thus, we return an answer of \[100, 100]. Note that square 2 only brushes the right side of square 1, which does not count as landing on it.
### Constraints
* `1 <= positions.length <= 1000`
* `1 <= lefti <= 10^8`
* `1 <= sideLengthi <= 10^6`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/falling_squares/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/falling_squares/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class _MaxSegmentTree:
"""Segment tree supporting range chmax updates and range max queries."""
def __init__(self, size: int) -> None:
self.size = size
self.tree = [0] * (4 * size)
self.lazy = [0] * (4 * size)
def _push_down(self, node: int) -> None:
pending = self.lazy[node]
if pending == 0:
return
for child in (2 * node, 2 * node + 1):
if self.tree[child] < pending:
self.tree[child] = pending
if self.lazy[child] < pending:
self.lazy[child] = pending
self.lazy[node] = 0
def update(self, left: int, right: int, value: int) -> None:
self._update(1, 0, self.size - 1, left, right, value)
def _update(self, node: int, start: int, end: int, left: int, right: int, value: int) -> None:
if right < start or end < left:
return
if left <= start and end <= right:
if self.tree[node] < value:
self.tree[node] = value
if self.lazy[node] < value:
self.lazy[node] = value
return
self._push_down(node)
mid = (start + end) // 2
self._update(2 * node, start, mid, left, right, value)
self._update(2 * node + 1, mid + 1, end, left, right, value)
self.tree[node] = max(self.tree[2 * node], self.tree[2 * node + 1])
def query(self, left: int, right: int) -> int:
return self._query(1, 0, self.size - 1, left, right)
def _query(self, node: int, start: int, end: int, left: int, right: int) -> int:
if right < start or end < left:
return 0
if left <= start and end <= right:
return self.tree[node]
self._push_down(node)
mid = (start + end) // 2
return max(
self._query(2 * node, start, mid, left, right),
self._query(2 * node + 1, mid + 1, end, left, right),
)
class Solution:
# Time: O(n log n) with coordinate compression
# Space: O(n)
def falling_squares(self, positions: list[list[int]]) -> list[int]:
coords: set[int] = set()
for left, side in positions:
coords.add(left)
coords.add(left + side - 1)
axis = sorted(coords)
rank = {value: index for index, value in enumerate(axis)}
tree = _MaxSegmentTree(len(axis))
ans: list[int] = []
tallest = 0
for left, side in positions:
lo = rank[left]
hi = rank[left + side - 1]
height = tree.query(lo, hi) + side
tree.update(lo, hi, height)
tallest = max(tallest, height)
ans.append(tallest)
return ans
```
## Complexity
| Time | Space |
| -------------------------------------- | ----- |
| O(n log n) with coordinate compression | O(n) |
## Tags
# Fibonacci Number Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/fibonacci-number
Tested Python solution for LeetCode 509 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 509, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Recursion](/catalog/topics/recursion), [Memoization](/catalog/topics/memoization). [View on LeetCode](https://leetcode.com/problems/fibonacci-number/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 509 # by problem number
lcpy gen -s fibonacci_number # by problem name
```
## Problem
The \Fibonacci numbers\, commonly denoted \F(n)\ form a sequence, called the \Fibonacci sequence\, such that each number is the sum of the two preceding ones, starting from \0\ and \1\. That is,
\F(0) = 0, F(1) = 1 F(n) = F(n - 1) + F(n - 2), for n > 1. \\
Given \n\, calculate \F(n)\.\
books\ where \books\[i] = \[thickness\i\, height\i\]\ indicates the thickness and height of the \i\th\\ book. You are also given an integer \shelfWidth\.
We want to place these books in order onto bookcase shelves that have a total width \shelfWidth\.
We choose some of the books to place on this shelf such that the sum of their thickness is less than or equal to \shelfWidth\, then build another level of the shelf of the bookcase so that the total height of the bookcase has increased by the maximum height of the books we just put down. We repeat this process until there are no more books to place.
Note that at each step of the above process, the order of the books we place is the same order as the given sequence of books.
For example, if we have an ordered list of \5\ books, we might place the first and second book onto the first shelf, the third book on the second shelf, and the fourth and fifth book on the last shelf.
Return \the minimum possible height that the total bookshelf can be after placing shelves in this manner\.
### Examples

```
Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4
Output: 6
Explanation: The sum of the heights of the 3 shelves is 1 + 3 + 2 = 6. Notice that book number 2 does not have to be on the first shelf.
```
```
Input: books = [[1,3],[2,4],[3,2]], shelfWidth = 6
Output: 4
```
### Constraints
* \1 \<= books.length \<= 1000\
* \1 \<= thickness\i\ \<= shelfWidth \<= 1000\
* \1 \<= height\i\ \<= 1000\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/filling_bookcase_shelves/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/filling_bookcase_shelves/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * W)
# Space: O(n)
def min_height_shelves(self, books: list[list[int]], shelf_width: int) -> int:
n = len(books)
dp = [0] + [10**9] * n
for i in range(1, n + 1):
total_w = 0
max_h = 0
for j in range(i, 0, -1):
total_w += books[j - 1][0]
if total_w > shelf_width:
break
max_h = max(max_h, books[j - 1][1])
dp[i] = min(dp[i], max_h + dp[j - 1])
return dp[n]
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(n \* W) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Final Array State After K Multiplication
Source: https://leetcode-py.wisl.dev/problems/final-array-state-after-k-multiplication-operations-i
Tested Python solution for LeetCode 3264 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 3264, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/final-array-state-after-k-multiplication-operations-i/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3264 # by problem number
lcpy gen -s final_array_state_after_k_multiplication_operations_i # by problem name
```
## Problem
You are given an integer array `nums`, an integer `k`, and an integer `multiplier`.
You need to perform `k` operations on `nums`. In each operation:
* Find the **minimum** value `x` in `nums`. If there are multiple occurrences of the minimum value, select the one that appears **first**.
* Replace the selected minimum value `x` with `x * multiplier`.
Return an integer array denoting the final state of `nums` after performing all `k` operations.
### Examples
```
Input: nums = [2,1,3,5,6], k = 5, multiplier = 2
Output: [8,4,6,5,6]
```
**Explanation:**
| Operation | Result |
| ----------------- | ---------------- |
| After operation 1 | \[2, 2, 3, 5, 6] |
| After operation 2 | \[4, 2, 3, 5, 6] |
| After operation 3 | \[4, 4, 3, 5, 6] |
| After operation 4 | \[4, 4, 6, 5, 6] |
| After operation 5 | \[8, 4, 6, 5, 6] |
```
Input: nums = [1,2], k = 3, multiplier = 4
Output: [16,8]
```
**Explanation:**
| Operation | Result |
| ----------------- | -------- |
| After operation 1 | \[4, 2] |
| After operation 2 | \[4, 8] |
| After operation 3 | \[16, 8] |
### Constraints
* 1 \<= nums.length \<= 100
* 1 \<= nums\[i] \<= 100
* 1 \<= k \<= 10
* 1 \<= multiplier \<= 5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/final_array_state_after_k_multiplication_operations_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/final_array_state_after_k_multiplication_operations_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n + k * log n)
# Space: O(n)
def get_final_state(self, nums: list[int], k: int, multiplier: int) -> list[int]:
heap = [(value, index) for index, value in enumerate(nums)]
heapq.heapify(heap)
for _ in range(k):
value, index = heapq.heappop(heap)
heapq.heappush(heap, (value * multiplier, index))
result = [0] * len(nums)
while heap:
value, index = heapq.heappop(heap)
result[index] = value
return result
```
## Complexity
| Time | Space |
| ----------------- | ----- |
| O(n + k \* log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Final Prices With a Special Discount in a Shop
Source: https://leetcode-py.wisl.dev/problems/final-prices-with-a-special-discount-in-a-shop
Tested Python solution for LeetCode 1475 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1475, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/final-prices-with-a-special-discount-in-a-shop/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1475 # by problem number
lcpy gen -s final_prices_with_a_special_discount_in_a_shop # by problem name
```
## Problem
Given an integer array `prices` where `prices[i]` is the price of the `ith` item in a shop.
There is a special discount for items in the shop. If you buy the `ith` item, then you will receive a discount equivalent to `prices[j]` where `j` is the minimum index such that `j > i` and `prices[j] <= prices[i]`. Otherwise, you will not receive any discount at all.
Return an integer array `answer` where `answer[i]` is the final price you will pay for the `ith` item of the shop, considering the special discount.
### Examples
```
Input: prices = [8,4,6,2,3]
Output: [4,2,4,2,3]
Explanation:
For item 0 with price[0]=8 you will receive a discount equivalent to prices[1]=4, therefore, the final price you will pay is 8 - 4 = 4.
For item 1 with price[1]=4 you will receive a discount equivalent to prices[3]=2, therefore, the final price you will pay is 4 - 2 = 2.
For item 2 with price[2]=6 you will receive a discount equivalent to prices[3]=2, therefore, the final price you will pay is 6 - 2 = 4.
For items 3 and 4 you will not receive any discount at all.
```
```
Input: prices = [1,2,3,4,5]
Output: [1,2,3,4,5]
Explanation: In this case, for all items, you will not receive any discount at all.
```
```
Input: prices = [10,1,1,6]
Output: [9,0,1,6]
```
### Constraints
* `1 <= prices.length <= 500`
* `1 <= prices[i] <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/final_prices_with_a_special_discount_in_a_shop/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/final_prices_with_a_special_discount_in_a_shop/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) - each index is pushed and popped at most once
# Space: O(n) - for the index stack
def final_prices(self, prices: list[int]) -> list[int]:
answer = list(prices)
stack: list[int] = []
for i, price in enumerate(prices):
while stack and prices[stack[-1]] >= price:
answer[stack.pop()] -= price
stack.append(i)
return answer
```
## Complexity
| Time | Space |
| --------------------------------------------------- | -------------------------- |
| O(n) - each index is pushed and popped at most once | O(n) - for the index stack |
## Tags
[NeetCode All](/catalog/neetcode).
# Find All Anagrams in a String Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-all-anagrams-in-a-string
Tested Python solution for LeetCode 438 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 438, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/find-all-anagrams-in-a-string/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 438 # by problem number
lcpy gen -s find_all_anagrams_in_a_string # by problem name
```
## Problem
Given two strings `s` and `p`, return an array of all the start indices of `p`'s anagrams in `s`. You may return the answer in any order.
An **anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
### Examples
```
Input: s = "cbaebabacd", p = "abc"
Output: [0,6]
```
**Explanation:**
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".
```
Input: s = "abab", p = "ab"
Output: [0,1,2]
```
**Explanation:**
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".
### Constraints
* 1 \<= s.length, p.length \<= 3 \* 10^4
* s and p consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_anagrams_in_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_anagrams_in_a_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
"""
Sliding Window with Character Frequency Counting
Algorithm:
1. Count character frequencies in pattern p
2. Use sliding window of size len(p) on string s
3. Maintain frequency count of current window
4. When frequencies match, record start index
ASCII Visualization:
s = "cbaebabacd", p = "abc" (need: a=1, b=1, c=1)
Window positions:
[cba]ebabacd -> {c:1, b:1, a:1} ✓ matches -> index 0
c[bae]babacd -> {b:1, a:1, e:1} ✗
cb[aeb]abacd -> {a:1, e:1, b:1} ✗
cba[eba]bacd -> {e:1, b:1, a:1} ✗
cbae[bab]acd -> {b:2, a:1} ✗
cbaeb[aba]cd -> {a:2, b:1} ✗
cbaeba[bac]d -> {b:1, a:1, c:1} ✓ matches -> index 6
"""
# Time: O(n) where n is length of s
# Space: O(1) - at most 26 lowercase letters
def find_anagrams(self, s: str, p: str) -> list[int]:
if len(p) > len(s):
return []
result = []
p_count = Counter(p)
window_count = Counter(s[: len(p)])
# Check first window
if window_count == p_count:
result.append(0)
# Slide window
for i in range(len(p), len(s)):
# Add new character
window_count[s[i]] += 1
# Remove old character
left_char = s[i - len(p)]
window_count[left_char] -= 1
if window_count[left_char] == 0:
del window_count[left_char]
# Check if current window is anagram
if window_count == p_count:
result.append(i - len(p) + 1)
return result
```
## Complexity
| Time | Space |
| --------------------------- | ----------------------------------- |
| O(n) where n is length of s | O(1) - at most 26 lowercase letters |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Find All Duplicates in an Array
Source: https://leetcode-py.wisl.dev/problems/find-all-duplicates-in-an-array
Tested Python solution for LeetCode 442 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 442, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-all-duplicates-in-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 442 # by problem number
lcpy gen -s find_all_duplicates_in_an_array # by problem name
```
## Problem
Given an integer array `nums` of length `n` where all the integers of `nums` are in the range `[1, n]` and each integer appears **at most** **twice**, return *an array of all the integers that appears **twice***.
You must write an algorithm that runs in `O(n)` time and uses only *constant* auxiliary space, excluding the space needed to store the output
### Examples
```
Input: nums = [4,3,2,7,8,2,3,1]
Output: [2,3]
```
```
Input: nums = [1,1,2]
Output: [1]
```
```
Input: nums = [1]
Output: []
```
### Constraints
* `n == nums.length`
* `1 <= n <= 10^5`
* `1 <= nums[i] <= n`
* Each element in `nums` appears **once** or **twice**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_duplicates_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_duplicates_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_duplicates(self, nums: list[int]) -> list[int]:
result: list[int] = []
for num in nums:
idx = abs(num) - 1
if nums[idx] < 0:
result.append(abs(num))
else:
nums[idx] = -nums[idx]
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find All Numbers Disappeared in an Array
Source: https://leetcode-py.wisl.dev/problems/find-all-numbers-disappeared-in-an-array
Tested Python solution for LeetCode 448 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 448, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 448 # by problem number
lcpy gen -s find_all_numbers_disappeared_in_an_array # by problem name
```
## Problem
Given an array `nums` of `n` integers where `nums[i]` is in the range `[1, n]`, return *an array of all the integers in the range* `[1, n]` *that do not appear in* `nums`.
### Examples
```
Input: nums = [4,3,2,7,8,2,3,1]
Output: [5,6]
```
```
Input: nums = [1,1]
Output: [2]
```
### Constraints
* `n == nums.length`
* `1 <= n <= 10^5`
* `1 <= nums[i] <= n`
**Follow up:** Could you do it without extra space and in `O(n)` runtime? You may assume the returned list does not count as extra space.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_numbers_disappeared_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_numbers_disappeared_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) excluding the output list
def find_disappeared_numbers(self, nums: list[int]) -> list[int]:
for num in nums:
index = abs(num) - 1
if nums[index] > 0:
nums[index] = -nums[index]
return [i + 1 for i, num in enumerate(nums) if num > 0]
```
## Complexity
| Time | Space |
| ---- | ------------------------------ |
| O(n) | O(1) excluding the output list |
## Tags
[NeetCode All](/catalog/neetcode).
# Find All People With Secret Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-all-people-with-secret
Tested Python solution for LeetCode 2092 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2092, [Hard](/catalog/hard). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-all-people-with-secret/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2092 # by problem number
lcpy gen -s find_all_people_with_secret # by problem name
```
## Problem
You are given an integer `n` indicating there are `n` people numbered from `0` to `n - 1`. You are also given a **0-indexed** 2D integer array `meetings` where `meetings[i] = [xi, yi, timei]` indicates that person `xi` and person `yi` have a meeting at `timei`. A person may attend **multiple meetings** at the same time. Finally, you are given an integer `firstPerson`.
Person `0` has a **secret** and initially shares the secret with a person `firstPerson` at time `0`. This secret is then shared every time a meeting takes place with a person that has the secret. More formally, for every meeting, if a person `xi` has the secret at `timei`, then they will share the secret with person `yi`, and vice versa.
The secrets are shared **instantaneously**. That is, a person may receive the secret and share it with people in other meetings within the same time frame.
Return a list of all the people that have the secret after all the meetings have taken place. You may return the answer in **any order**.
### Examples
```
Input: n = 6, meetings = [[1,2,5],[2,3,8],[1,5,10]], firstPerson = 1
Output: [0,1,2,3,5]
Explanation:
At time 0, person 0 shares the secret with person 1.
At time 5, person 1 shares the secret with person 2.
At time 8, person 2 shares the secret with person 3.
At time 10, person 1 shares the secret with person 5.
Thus, people 0, 1, 2, 3, and 5 know the secret after all the meetings.
```
```
Input: n = 4, meetings = [[3,1,3],[1,2,2],[0,3,3]], firstPerson = 3
Output: [0,1,3]
Explanation:
At time 0, person 0 shares the secret with person 3.
At time 2, neither person 1 nor person 2 know the secret.
At time 3, person 3 shares the secret with person 0 and person 1.
Thus, people 0, 1, and 3 know the secret after all the meetings.
```
```
Input: n = 5, meetings = [[3,4,2],[1,2,1],[2,3,1]], firstPerson = 1
Output: [0,1,2,3,4]
Explanation:
At time 0, person 0 shares the secret with person 1.
At time 1, person 1 shares the secret with person 2, and person 2 shares the secret with person 3.
Note that person 2 can share the secret at the same time as receiving it.
At time 2, person 3 shares the secret with person 4.
Thus, people 0, 1, 2, 3, and 4 know the secret after all the meetings.
```
### Constraints
* `2 <= n <= 10^5`
* `1 <= meetings.length <= 10^5`
* `meetings[i].length == 3`
* `0 <= xi, yi <= n - 1`
* `xi != yi`
* `1 <= timei <= 10^5`
* `1 <= firstPerson <= n - 1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_people_with_secret/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_people_with_secret/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m log m) for sorting meetings plus near-linear union-find passes
# Space: O(n) for the parent array
def find_all_people(self, n: int, meetings: list[list[int]], first_person: int) -> list[int]:
parent = list(range(n))
def find(node: int) -> int:
while parent[node] != node:
parent[node] = parent[parent[node]]
node = parent[node]
return node
def union(a: int, b: int) -> None:
root_a, root_b = find(a), find(b)
if root_a != root_b:
parent[root_a] = root_b
known = {0, first_person}
sorted_meetings = sorted(meetings, key=lambda meeting: meeting[2])
i = 0
total = len(sorted_meetings)
while i < total:
time = sorted_meetings[i][2]
participants: set[int] = set()
while i < total and sorted_meetings[i][2] == time:
x, y, _ = sorted_meetings[i]
union(x, y)
participants.update((x, y))
i += 1
knower_roots = {find(p) for p in participants if p in known}
for person in participants:
if find(person) in knower_roots:
known.add(person)
for person in participants:
parent[person] = person
return list(known)
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------ | ------------------------- |
| O(m log m) for sorting meetings plus near-linear union-find passes | O(n) for the parent array |
## Tags
[NeetCode All](/catalog/neetcode).
# Find All Possible Recipes from Given Supplies
Source: https://leetcode-py.wisl.dev/problems/find-all-possible-recipes-from-given-supplies
Tested Python solution for LeetCode 2115 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 2115, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), Directed Acyclic Graph. [View on LeetCode](https://leetcode.com/problems/find-all-possible-recipes-from-given-supplies/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2115 # by problem number
lcpy gen -s find_all_possible_recipes_from_given_supplies # by problem name
```
## Problem
You have information about `n` different recipes. You are given a string array `recipes` and a 2D string array `ingredients`. The `i`th recipe has the name `recipes[i]`, and you can **create** it if you have **all** the needed ingredients from `ingredients[i]`. A recipe can also be an ingredient for **other** recipes, i.e., `ingredients[i]` may contain a string that is in `recipes`.
You are also given a string array `supplies` containing all the ingredients that you initially have, and you have an infinite supply of all of them.
Return *a list of all the recipes that you can create.* You may return the answer in **any order**.
Note that two recipes may contain each other in their ingredients.
### Examples
```
Input: recipes = ["bread"], ingredients = [["yeast","flour"]], supplies = ["yeast","flour","corn"]
Output: ["bread"]
Explanation:
We can create "bread" since we have the ingredients "yeast" and "flour".
```
```
Input: recipes = ["bread","sandwich"], ingredients = [["yeast","flour"],["bread","meat"]], supplies = ["yeast","flour","meat"]
Output: ["bread","sandwich"]
Explanation:
We can create "bread" since we have the ingredients "yeast" and "flour".
We can create "sandwich" since we have the ingredient "meat" and can create the ingredient "bread".
```
```
Input: recipes = ["bread","sandwich","burger"], ingredients = [["yeast","flour"],["bread","meat"],["sandwich","meat","bread"]], supplies = ["yeast","flour","meat"]
Output: ["bread","sandwich","burger"]
Explanation:
We can create "bread" since we have the ingredients "yeast" and "flour".
We can create "sandwich" since we have the ingredient "meat" and can create the ingredient "bread".
We can create "burger" since we have the ingredient "meat" and can create the ingredients "bread" and "sandwich".
```
### Constraints
* `n == recipes.length == ingredients.length`
* `1 <= n <= 100`
* `1 <= ingredients[i].length, supplies.length <= 100`
* `1 <= recipes[i].length, ingredients[i][j].length, supplies[k].length <= 10`
* `recipes[i]`, `ingredients[i][j]`, and `supplies[k]` consist only of lowercase English letters.
* All the values of `recipes` and `supplies` combined are unique.
* Each `ingredients[i]` does not contain any duplicate values.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_possible_recipes_from_given_supplies/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_all_possible_recipes_from_given_supplies/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(V + E) over recipes and ingredient references
# Space: O(V + E)
def find_all_recipes(
self, recipes: list[str], ingredients: list[list[str]], supplies: list[str]
) -> list[str]:
recipe_set = set(recipes)
remaining = {r: len(ings) for r, ings in zip(recipes, ingredients, strict=True)}
dependents: dict[str, list[str]] = {}
for recipe, ings in zip(recipes, ingredients, strict=True):
for ing in ings:
dependents.setdefault(ing, []).append(recipe)
made: list[str] = []
queue: deque[str] = deque(supplies)
queue.extend(recipe for recipe in recipes if remaining[recipe] == 0)
while queue:
item = queue.popleft()
if item in recipe_set:
made.append(item)
for recipe in dependents.get(item, ()):
remaining[recipe] -= 1
if remaining[recipe] == 0:
queue.append(recipe)
return made
```
## Complexity
| Time | Space |
| ----------------------------------------------- | -------- |
| O(V + E) over recipes and ingredient references | O(V + E) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Anagram Mappings Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-anagram-mappings
Tested Python solution for LeetCode 760 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 760, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/find-anagram-mappings/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 760 # by problem number
lcpy gen -s find_anagram_mappings # by problem name
```
## Problem
You are given two integer arrays `nums1` and `nums2` where `nums2` is an anagram of `nums1`. Both arrays may contain duplicates.
Return an index mapping array `mapping` from `nums1` to `nums2` where `mapping[i] = j` means the `ith` element in `nums1` appears in `nums2` at index `j`. If there are multiple answers, return any of them.
An array `a` is an anagram of an array `b` means `b` is made by randomizing the order of the elements in `a`.
### Examples
```
Input: nums1 = [12,28,46,32,50], nums2 = [50,12,32,46,28]
Output: [1,4,3,2,0]
Explanation: As mapping[0] = 1 because the 0th element of nums1 appears at nums2[1], and mapping[1] = 4 because the 1st element of nums1 appears at nums2[4], and so on.
```
```
Input: nums1 = [84,46], nums2 = [84,46]
Output: [0,1]
```
### Constraints
* 1 \<= nums1.length \<= 100
* nums2.length == nums1.length
* 0 \<= nums1\[i], nums2\[i] \<= 10^5
* nums2 is an anagram of nums1.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_anagram_mappings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_anagram_mappings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def anagram_mappings(self, nums1: list[int], nums2: list[int]) -> list[int]:
index = {x: i for i, x in enumerate(nums2)}
return [index[x] for x in nums1]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find And Replace in String Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-and-replace-in-string
Tested Python solution for LeetCode 833 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 833, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-and-replace-in-string/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 833 # by problem number
lcpy gen -s find_and_replace_in_string # by problem name
```
## Problem
You are given a 0-indexed string `s` that you must perform `k` replacement operations on. The replacement operations are given as three 0-indexed parallel arrays, `indices`, `sources`, and `targets`, all of length `k`.
To complete the `ith` replacement operation:
* Check if the substring `sources[i]` occurs at index `indices[i]` in the original string `s`.
* If it does not occur, do nothing.
* Otherwise if it does occur, replace that substring with `targets[i]`.
For example, if `s = "abcd"`, `indices[i] = 0`, `sources[i] = "ab"`, and `targets[i] = "eee"`, then the result of this replacement will be `"eeecd"`.
All replacement operations must occur simultaneously, meaning the replacement operations should not affect the indexing of each other. The testcases will be generated such that the replacements will not overlap.
* For example, a testcase with `s = "abc"`, `indices = [0, 1]`, and `sources = ["ab","bc"]` will not be generated because the `"ab"` and `"bc"` replacements overlap.
Return the resulting string after performing all replacement operations on `s`.
A substring is a contiguous sequence of characters in a string.
### Examples

```
Input: s = "abcd", indices = [0, 2], sources = ["a", "cd"], targets = ["eee", "ffff"]
Output: "eeebffff"
Explanation:
"a" occurs at index 0 in s, so we replace it with "eee".
"cd" occurs at index 2 in s, so we replace it with "ffff".
```

```
Input: s = "abcd", indices = [0, 2], sources = ["ab","ec"], targets = ["eee","ffff"]
Output: "eeecd"
Explanation:
"ab" occurs at index 0 in s, so we replace it with "eee".
"ec" does not occur at index 2 in s, so we do nothing.
```
### Constraints
* 1 \<= s.length \<= 1000
* k == indices.length == sources.length == targets.length
* 1 \<= k \<= 100
* 0 \<= indices\[i] \< s.length
* 1 \<= sources\[i].length, targets\[i].length \<= 50
* s consists of only lowercase English letters.
* sources\[i] and targets\[i] consist of only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_and_replace_in_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_and_replace_in_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + sum(len(sources[i]) + len(targets[i])))
# Space: O(n)
def find_replace_string(
self, s: str, indices: list[int], sources: list[str], targets: list[str]
) -> str:
match_at: dict[int, int] = {}
for i, idx in enumerate(indices):
if s.startswith(sources[i], idx):
match_at[idx] = i
pieces: list[str] = []
i = 0
while i < len(s):
j = match_at.get(i)
if j is None:
pieces.append(s[i])
i += 1
else:
pieces.append(targets[j])
i += len(sources[j])
return "".join(pieces)
```
## Complexity
| Time | Space |
| ----------------------------------------------- | ----- |
| O(n + sum(len(sources\[i]) + len(targets\[i]))) | O(n) |
## Tags
# Find and Replace Pattern Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-and-replace-pattern
Tested Python solution for LeetCode 890 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 890, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/find-and-replace-pattern/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 890 # by problem number
lcpy gen -s find_and_replace_pattern # by problem name
```
## Problem
Given a list of strings `words` and a string `pattern`, return *a list of* `words[i]` *that match* `pattern`. You may return the answer in **any order**.
A word matches the pattern if there exists a permutation of letters `p` so that after replacing every letter `x` in the pattern with `p(x)`, we get the desired word.
Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.
### Examples
```
Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
Output: ["mee","aqq"]
Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}.
"ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation, since a and b map to the same letter.
```
```
Input: words = ["a","b","c"], pattern = "a"
Output: ["a","b","c"]
```
### Constraints
* `1 <= pattern.length <= 20`
* `1 <= words.length <= 50`
* `words[i].length == pattern.length`
* `pattern` and `words[i]` are lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_and_replace_pattern/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_and_replace_pattern/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m) where n = len(words), m = len(pattern)
# Space: O(m)
def find_and_replace_pattern(self, words: list[str], pattern: str) -> list[str]:
def matches(word: str) -> bool:
if len(word) != len(pattern):
return False
p_to_w: dict[str, str] = {}
w_to_p: dict[str, str] = {}
for pc, wc in zip(pattern, word, strict=True):
if p_to_w.setdefault(pc, wc) != wc or w_to_p.setdefault(wc, pc) != pc:
return False
return True
return [word for word in words if matches(word)]
```
## Complexity
| Time | Space |
| ------------------------------------------------ | ----- |
| O(n \* m) where n = len(words), m = len(pattern) | O(m) |
## Tags
# Find Bottom Left Tree Value Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-bottom-left-tree-value
Tested Python solution for LeetCode 513 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 513, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/find-bottom-left-tree-value/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 513 # by problem number
lcpy gen -s find_bottom_left_tree_value # by problem name
```
## Problem
Given the `root` of a binary tree, return *the leftmost value in the last row of the tree*.
### Examples

```
Input: root = [2,1,3]
Output: 1
```

```
Input: root = [1,2,3,4,null,5,6,null,null,7]
Output: 7
```
### Constraints
* The number of nodes in the tree is in the range `[1, 10^4]`.
* `-2^31 <= Node.val <= 2^31 - 1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_bottom_left_tree_value/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_bottom_left_tree_value/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(n)
def find_bottom_left_value(self, root: TreeNode[int]) -> int:
queue: deque[TreeNode[int]] = deque([root])
leftmost = root.val
while queue:
leftmost = queue[0].val
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return leftmost
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Building Where Alice and Bob Can Meet
Source: https://leetcode-py.wisl.dev/problems/find-building-where-alice-and-bob-can-meet
Tested Python solution for LeetCode 2940 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2940, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Stack](/catalog/topics/stack), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/find-building-where-alice-and-bob-can-meet/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2940 # by problem number
lcpy gen -s find_building_where_alice_and_bob_can_meet # by problem name
```
## Problem
You are given a **0-indexed** array `heights` of positive integers, where `heights[i]` represents the height of the `i`th building.
If a person is in building `i`, they can move to any other building `j` if and only if `i < j` and `heights[i] < heights[j]`.
You are also given another array `queries` where `queries[i] = [a_i, b_i]`. On the `i`th query, Alice is in building `a_i` while Bob is in building `b_i`.
Return *an array* `ans` where `ans[i]` is **the index of the leftmost building** where Alice and Bob can meet on the `i`th query. If Alice and Bob cannot move to a common building on query `i`, set `ans[i]` to `-1`.
### Examples
```
Input: heights = [6,4,8,5,2,7], queries = [[0,1],[0,3],[2,4],[3,4],[2,2]]
Output: [2,5,-1,5,2]
Explanation: In the first query, Alice and Bob can move to building 2 since heights[0] < heights[2] and heights[1] < heights[2].
In the second query, Alice and Bob can move to building 5 since heights[0] < heights[5] and heights[3] < heights[5].
In the third query, Alice cannot meet Bob since Alice cannot move to any other building.
In the fourth query, Alice and Bob can move to building 5 since heights[3] < heights[5] and heights[4] < heights[5].
In the fifth query, Alice and Bob are already in the same building.
For ans[i] != -1, It can be shown that ans[i] is the leftmost building where Alice and Bob can meet.
For ans[i] == -1, It can be shown that there is no building where Alice and Bob can meet.
```
```
Input: heights = [5,3,8,2,6,1,4,6], queries = [[0,7],[3,5],[5,2],[3,0],[1,6]]
Output: [7,6,-1,4,6]
Explanation: In the first query, Alice can directly move to Bob's building since heights[0] < heights[7].
In the second query, Alice and Bob can move to building 6 since heights[3] < heights[6] and heights[5] < heights[6].
In the third query, Alice cannot meet Bob since Bob cannot move to any other building.
In the fourth query, Alice and Bob can move to building 4 since heights[3] < heights[4] and heights[0] < heights[4].
In the fifth query, Alice can directly move to Bob's building since heights[1] < heights[6].
For ans[i] != -1, It can be shown that ans[i] is the leftmost building where Alice and Bob can meet.
For ans[i] == -1, It can be shown that there is no building where Alice and Bob can meet.
```
### Constraints
* 1 \<= heights.length \<= 5 \* 10^4
* 1 \<= heights\[i] \<= 10^9
* 1 \<= queries.length \<= 5 \* 10^4
* queries\[i] = \[a\_i, b\_i]
* 0 \<= a\_i, b\_i \<= heights.length - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_building_where_alice_and_bob_can_meet/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_building_where_alice_and_bob_can_meet/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O((n + q) log n) - one build pass over the tree plus a descent per query
# Space: O(n) - segment tree over the building heights
def leftmost_building_queries(self, heights: list[int], queries: list[list[int]]) -> list[int]:
n = len(heights)
size = 1
while size < n:
size <<= 1
tree = [0] * (2 * size)
tree[size : size + n] = heights
for i in range(size - 1, 0, -1):
tree[i] = max(tree[2 * i], tree[2 * i + 1])
def next_greater(start: int, limit: int) -> int:
def descend(node: int, node_lo: int, node_hi: int) -> int:
if node_hi <= start or tree[node] <= limit:
return -1
if node_lo == node_hi:
return node_lo
mid = (node_lo + node_hi) // 2
found = descend(2 * node, node_lo, mid)
return found if found != -1 else descend(2 * node + 1, mid + 1, node_hi)
if start >= n:
return -1
return descend(1, 0, size - 1)
result: list[int] = []
for query in queries:
left, right = query[0], query[1]
if left > right:
left, right = right, left
if left == right:
result.append(left)
elif heights[left] < heights[right]:
result.append(right)
else:
result.append(next_greater(right, heights[left]))
return result
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------------ | --------------------------------------------- |
| O((n + q) log n) - one build pass over the tree plus a descent per query | O(n) - segment tree over the building heights |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Champion II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-champion-ii
Tested Python solution for LeetCode 2924 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2924, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/find-champion-ii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2924 # by problem number
lcpy gen -s find_champion_ii # by problem name
```
## Problem
There are `n` teams numbered from `0` to `n - 1` in a tournament; each team is also a node in a \DAG\.
You are given the integer `n` and a \0-indexed\ 2D integer array `edges` of length `m` representing the \DAG\, where `edges[i] = [u_i, v_i]` indicates that there is a directed edge from team `u_i` to team `v_i` in the graph.
A directed edge from `a` to `b` in the graph means that team `a` is \stronger\ than team `b` and team `b` is \weaker\ than team `a`.
Team `a` will be the \champion\ of the tournament if there is no team `b` that is \stronger\ than team `a`.
Return \the team that will be the \champion\ of the tournament if there is a \unique\ champion, otherwise, return \\-1\\.\
### Examples

```
Input: n = 3, edges = [[0,1],[1,2]]
Output: 0
Explanation: Team 1 is weaker than team 0. Team 2 is weaker than team 1. So the champion is team 0.
```

```
Input: n = 4, edges = [[0,2],[1,3],[1,2]]
Output: -1
Explanation: Team 2 is weaker than team 0 and team 1. Team 3 is weaker than team 1. But team 1 and team 0 are not weaker than any other teams. So the answer is -1.
```
### Constraints
* 1 \<= n \<= 100
* m == edges.length
* 0 \<= m \<= n \* (n - 1) / 2
* `edges[i].length == 2`
* 0 \<= edges\[i]\[j] \<= n - 1
* `edges[i][0] != edges[i][1]`
* The input is generated such that if team `a` is stronger than team `b`, team `b` is not stronger than team `a`.
* The input is generated such that if team `a` is stronger than team `b` and team `b` is stronger than team `c`, then team `a` is stronger than team `c`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_champion_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_champion_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(n)
def find_champion(self, n: int, edges: list[list[int]]) -> int:
weaker_count = [0] * n
for _stronger, weaker in edges:
weaker_count[weaker] += 1
champions = [team for team in range(n) if weaker_count[team] == 0]
return champions[0] if len(champions) == 1 else -1
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + m) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Closest Node to Given Two Nodes
Source: https://leetcode-py.wisl.dev/problems/find-closest-node-to-given-two-nodes
Tested Python solution for LeetCode 2359 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2359, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/find-closest-node-to-given-two-nodes/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2359 # by problem number
lcpy gen -s find_closest_node_to_given_two_nodes # by problem name
```
## Problem
You are given a **directed** graph of `n` nodes numbered from `0` to `n - 1`, where each node has **at most one** outgoing edge.
The graph is represented with a given **0-indexed** array `edges` of size `n`, indicating that there is a directed edge from node `i` to node `edges[i]`. If there is no outgoing edge from `i`, then `edges[i] == -1`.
You are also given two integers `node1` and `node2`.
Return the **index** of the node that can be reached from both `node1` and `node2`, such that the **maximum** between the distance from `node1` to that node, and from `node2` to that node is **minimized**. If there are multiple answers, return the node with the **smallest** index, and if no possible answer exists, return `-1`.
Note that `edges` may contain cycles.
### Examples

```
Input: edges = [2,2,3,-1], node1 = 0, node2 = 1
Output: 2
Explanation: The distance from node 0 to node 2 is 1, and the distance from node 1 to node 2 is 1. The maximum of those two distances is 1. It can be proven that we cannot get a node with a smaller maximum distance than 1, so we return node 2.
```

```
Input: edges = [1,2,-1], node1 = 0, node2 = 2
Output: 2
Explanation: The distance from node 0 to node 2 is 2, and the distance from node 2 to itself is 0. The maximum of those two distances is 2. It can be proven that we cannot get a node with a smaller maximum distance than 2, so we return node 2.
```
### Constraints
* `n == edges.length`
* `2 <= n <= 10^5`
* `-1 <= edges[i] < n`
* `edges[i] != i`
* `0 <= node1, node2 < n`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_closest_node_to_given_two_nodes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_closest_node_to_given_two_nodes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def closest_meeting_node(self, edges: list[int], node1: int, node2: int) -> int:
def distances(start: int) -> list[int]:
dist = [-1] * len(edges)
node = start
step = 0
while node != -1 and dist[node] == -1:
dist[node] = step
node = edges[node]
step += 1
return dist
dist1 = distances(node1)
dist2 = distances(node2)
best_node = -1
best_max = -1
for i in range(len(edges)):
if dist1[i] == -1 or dist2[i] == -1:
continue
curr_max = max(dist1[i], dist2[i])
if best_node == -1 or curr_max < best_max:
best_node = i
best_max = curr_max
return best_node
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Common Characters Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-common-characters
Tested Python solution for LeetCode 1002 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1002, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/find-common-characters/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1002 # by problem number
lcpy gen -s find_common_characters # by problem name
```
## Problem
Given a string array `words`, return *an array of all characters that show up in all strings within the* `words` *(including duplicates)*. You may return the answer in **any order**.
### Examples
```
Input: words = ["bella","label","roller"]
Output: ["e","l","l"]
```
```
Input: words = ["cool","lock","cook"]
Output: ["c","o"]
```
### Constraints
* `1 <= words.length <= 100`
* `1 <= words[i].length <= 100`
* `words[i]` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_common_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_common_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(sum len(words))
# Space: O(1) for the counter (26 letters)
def common_chars(self, words: list[str]) -> list[str]:
common = Counter(words[0])
for word in words[1:]:
common &= Counter(word)
return list(common.elements())
```
## Complexity
| Time | Space |
| ----------------- | --------------------------------- |
| O(sum len(words)) | O(1) for the counter (26 letters) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Critical and Pseudo-Critical Edges in
Source: https://leetcode-py.wisl.dev/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree
Tested Python solution for LeetCode 1489 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1489, [Hard](/catalog/hard). Topics: [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory), [Sorting](/catalog/topics/sorting), Minimum Spanning Tree, Strongly Connected Component. [View on LeetCode](https://leetcode.com/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1489 # by problem number
lcpy gen -s find_critical_and_pseudo_critical_edges_in_minimum_spanning_tree # by problem name
```
## Problem
Given a weighted undirected connected graph with `n` vertices numbered from `0` to `n - 1`, and an array `edges` where `edges[i] = [ai, bi, weighti]` represents a bidirectional and weighted edge between nodes `ai` and `bi`. A minimum spanning tree (MST) is a subset of the graph's edges that connects all vertices without cycles and with the minimum possible total edge weight.
Find *all the critical and pseudo-critical edges in the given graph's minimum spanning tree (MST)*. An MST edge whose deletion from the graph would cause the MST weight to increase is called a *critical edge*. On the other hand, a pseudo-critical edge is that which can appear in some MSTs but not all.
Note that you can return the indices of the edges in any order.
### Examples

```
Input: n = 5, edges = [[0,1,1],[1,2,1],[2,3,2],[0,3,2],[0,4,3],[3,4,3],[1,4,6]]
Output: [[0,1],[2,3,4,5]]
Explanation: The two edges 0 and 1 appear in all MSTs, therefore they are critical edges.
The edges 2, 3, 4, and 5 are only part of some MSTs, therefore they are considered pseudo-critical edges.
```


```
Input: n = 4, edges = [[0,1,1],[1,2,1],[2,3,1],[0,3,1]]
Output: [[],[0,1,2,3]]
Explanation: Since all 4 edges have equal weight, choosing any 3 edges from the given 4 will yield an MST. Therefore all 4 edges are pseudo-critical.
```
### Constraints
* `2 <= n <= 100`
* `1 <= edges.length <= min(200, n * (n - 1) / 2)`
* `edges[i].length == 3`
* `0 <= ai < bi < n`
* `1 <= weighti <= 1000`
* All pairs `(ai, bi)` are **distinct**
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_critical_and_pseudo_critical_edges_in_minimum_spanning_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_critical_and_pseudo_critical_edges_in_minimum_spanning_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m^2 * alpha(n)) where m = edges; runs Kruskal once + 2m times
# Space: O(n + m)
def find_critical_and_pseudo_critical_edges(
self, n: int, edges: list[list[int]]
) -> list[list[int]]:
m = len(edges)
# Sort edges by (weight, original index) so tie-breaks are deterministic.
order = sorted(range(m), key=lambda i: (edges[i][2], i))
inf = 10**12
def kruskal(skip: int = -1, force: int = -1) -> int:
parent = list(range(n))
def find(x: int) -> int:
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
weight = 0
components = n
if force != -1:
u, v, w = edges[force]
parent[find(u)] = find(v)
weight += w
components -= 1
for i in order:
if i in (skip, force):
continue
u, v, w = edges[i]
ru, rv = find(u), find(v)
if ru != rv:
parent[ru] = rv
weight += w
components -= 1
if components == 1:
break
return weight if components == 1 else inf
base = kruskal()
critical: list[int] = []
pseudo: list[int] = []
for i in range(m):
# Excluding edge i: if the MST gets heavier (or impossible), it is critical.
if kruskal(skip=i) > base:
critical.append(i)
# Forcing edge i into the MST: if weight is unchanged, it is in some MST.
elif kruskal(force=i) == base:
pseudo.append(i)
return [critical, pseudo]
```
## Complexity
| Time | Space |
| ---------------------------------------------------------------- | -------- |
| O(m^2 \* alpha(n)) where m = edges; runs Kruskal once + 2m times | O(n + m) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find Duplicate File in System Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-duplicate-file-in-system
Tested Python solution for LeetCode 609 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 609, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/find-duplicate-file-in-system/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 609 # by problem number
lcpy gen -s find_duplicate_file_in_system # by problem name
```
## Problem
Given a list `paths` of directory info, including the directory path, and all the files with contents in this directory, return *all the duplicate files in the file system in terms of their paths*. You may return the answer in **any order**.
A group of duplicate files consists of at least two files that have the same content.
A single directory info string in the input list has the following format:
```
"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"
```
It means there are `n` files `(f1.txt, f2.txt ... fn.txt)` with content `(f1_content, f2_content ... fn_content)` respectively in the directory `root/d1/d2/.../dm`. Note that `n >= 1` and `m >= 0`. If `m = 0`, it means the directory is just the root directory.
The output is a list of groups of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:
```
"directory_path/file_name.txt"
```
### Examples
```
Input: paths = ["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)","root 4.txt(efgh)"]
Output: [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
```
```
Input: paths = ["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)"]
Output: [["root/a/2.txt","root/c/d/4.txt"],["root/a/1.txt","root/c/3.txt"]]
```
### Constraints
* `1 <= paths.length <= 2 * 10^4`
* `1 <= paths[i].length <= 3000`
* `1 <= sum(paths[i].length) <= 5 * 10^5`
* `paths[i]` consist of English letters, digits, `'/'`, `'.'`, `'('`, `')'`, and `' '`.
* You may assume no files or directories share the same name in the same directory.
* You may assume each given directory info represents a unique directory. A single blank space separates the directory path and file info.
**Follow up:**
* Imagine you are given a real file system, how will you search files? DFS or BFS?
* If the file content is very large (GB level), how will you modify your solution?
* If you can only read the file by 1kb each time, how will you modify your solution?
* What is the time complexity of your modified solution? What is the most time-consuming part and memory-consuming part of it? How to optimize?
* How to make sure the duplicated files you find are not false positive?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_duplicate_file_in_system/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_duplicate_file_in_system/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
class Solution:
# Time: O(total characters across all paths)
# Space: O(total characters) for the content-to-paths map
def find_duplicate(self, paths: list[str]) -> list[list[str]]:
groups: dict[str, list[str]] = defaultdict(list)
for info in paths:
dir_path, _, files = info.partition(" ")
for token in files.split(" "):
name, content = token[:-1].split("(", 1)
groups[content].append(f"{dir_path}/{name}")
return [group for group in groups.values() if len(group) > 1]
```
## Complexity
| Time | Space |
| ------------------------------------ | ------------------------------------------------ |
| O(total characters across all paths) | O(total characters) for the content-to-paths map |
## Tags
# Find Duplicate Subtrees Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-duplicate-subtrees
Tested Python solution for LeetCode 652 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 652, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/find-duplicate-subtrees/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 652 # by problem number
lcpy gen -s find_duplicate_subtrees # by problem name
```
## Problem
Given the `root` of a binary tree, return all **duplicate subtrees**.
For each kind of duplicate subtrees, you only need to return the root node of any one **of them**.
Two trees are **duplicate** if they have the **same structure** with the **same node values**.
### Examples

```
Input: root = [1,2,3,4,null,2,4,null,null,4]
Output: [[2,4],[4]]
```

```
Input: root = [2,1,1]
Output: [[1]]
```

```
Input: root = [2,2,2,3,null,3,null]
Output: [[2,3],[3]]
```
### Constraints
* The number of the nodes in the tree will be in the range \[1, 5000]
* -200 \<= Node.val \<= 200
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_duplicate_subtrees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_duplicate_subtrees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
from leetcode_py import TreeNode
class Solution:
# Time: O(n^2) worst case for string serializations
# Space: O(n^2)
def find_duplicate_subtrees(self, root: TreeNode[int] | None) -> list[TreeNode[int] | None]:
counts: Counter[str] = Counter()
result: list[TreeNode[int] | None] = []
def serialize(node: TreeNode[int] | None) -> str:
if node is None:
return "#"
key = f"{node.val},{serialize(node.left)},{serialize(node.right)}"
counts[key] += 1
if counts[key] == 2:
result.append(node)
return key
serialize(root)
return result
```
## Complexity
| Time | Space |
| ------------------------------------------- | ------ |
| O(n^2) worst case for string serializations | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Eventual Safe States Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-eventual-safe-states
Tested Python solution for LeetCode 802 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 802, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/find-eventual-safe-states/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 802 # by problem number
lcpy gen -s find_eventual_safe_states # by problem name
```
## Problem
There is a directed graph of `n` nodes with each node labeled from `0` to `n - 1`. The graph is represented by a **0-indexed** 2D integer array `graph` where `graph[i]` is an integer array of nodes adjacent to node `i`, meaning there is an edge from node `i` to each node in `graph[i]`.
A node is a **terminal node** if there are no outgoing edges. A node is a **safe node** if every possible path starting from that node leads to a **terminal node** (or another safe node).
Return *an array containing all the safe nodes of the graph. The answer should be sorted in ascending order.*
### Examples
```
Input: graph = [[1,2],[2,3],[5],[0],[5],[],[]]
Output: [2,4,5,6]
Explanation: The given graph is shown above.
Nodes 5 and 6 are terminal nodes as there are no outgoing edges from either of them.
Every path starting at nodes 2, 4, 5, and 6 all lead to either node 5 or 6.
```
```
Input: graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
Output: [4]
Explanation:
Only node 4 is a terminal node, and every path starting at node 4 leads to node 4.
```
### Constraints
* n == graph.length
* 1 \<= n \<= 10^4
* 0 \<= graph\[i].length \<= n
* 0 \<= graph\[i]\[j] \<= n - 1
* graph\[i] is sorted in a strictly increasing order.
* The graph may contain self-loops.
* The number of edges in the graph will be in the range \[1, 4 \* 10^4].
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_eventual_safe_states/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_eventual_safe_states/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n + e)
# Space: O(n + e)
def eventual_safe_nodes(self, graph: list[list[int]]) -> list[int]:
n = len(graph)
# Trim nodes in reverse topological order: a node is safe once all
# its outgoing edges point at confirmed safe nodes
out_degree = [len(edges) for edges in graph]
reverse: list[list[int]] = [[] for _ in range(n)]
for u, edges in enumerate(graph):
for v in edges:
reverse[v].append(u)
queue = deque(i for i in range(n) if out_degree[i] == 0)
safe = [False] * n
while queue:
v = queue.popleft()
safe[v] = True
for u in reverse[v]:
out_degree[u] -= 1
if out_degree[u] == 0:
queue.append(u)
return [i for i in range(n) if safe[i]]
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + e) | O(n + e) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find First and Last Position of Element in
Source: https://leetcode-py.wisl.dev/problems/find-first-and-last-position-of-element-in-sorted-array
Tested Python solution for LeetCode 34 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 34, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 34 # by problem number
lcpy gen -s find_first_and_last_position_of_element_in_sorted_array # by problem name
```
## Problem
Given an array of integers `nums` sorted in non-decreasing order, find the starting and ending position of a given `target` value.
If `target` is not found in the array, return `[-1, -1]`.
You must write an algorithm with `O(log n)` runtime complexity.
### Examples
```
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
```
```
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
```
```
Input: nums = [], target = 0
Output: [-1,-1]
```
### Constraints
* `0 <= nums.length <= 10^5`
* `-10^9 <= nums[i] <= 10^9`
* `nums` is a non-decreasing array.
* `-10^9 <= target <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_first_and_last_position_of_element_in_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_first_and_last_position_of_element_in_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def search_range(self, nums: list[int], target: int) -> list[int]:
def find_left(nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left if left < len(nums) and nums[left] == target else -1
def find_right(nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] <= target:
left = mid + 1
else:
right = mid - 1
return right if right >= 0 and nums[right] == target else -1
if not nums:
return [-1, -1]
left_pos = find_left(nums, target)
if left_pos == -1:
return [-1, -1]
right_pos = find_right(nums, target)
return [left_pos, right_pos]
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Find First Palindromic String in the Array
Source: https://leetcode-py.wisl.dev/problems/find-first-palindromic-string-in-the-array
Tested Python solution for LeetCode 2108 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2108, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/find-first-palindromic-string-in-the-array/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2108 # by problem number
lcpy gen -s find_first_palindromic_string_in_the_array # by problem name
```
## Problem
Given an array of strings `words`, return the first **palindromic** string in the array. If there is no such string, return an **empty string** `""`.
A string is **palindromic** if it reads the same forward and backward.
### Examples
```
Input: words = ["abc","car","ada","racecar","cool"]
Output: "ada"
```
**Explanation:** The first string that is palindromic is "ada". Note that "racecar" is also palindromic, but it is not the first.
```
Input: words = ["notapalindrome","racecar"]
Output: "racecar"
```
**Explanation:** The first and only string that is palindromic is "racecar".
```
Input: words = ["def","ghi"]
Output: ""
```
**Explanation:** There are no palindromic strings, so the empty string is returned.
### Constraints
* `1 <= words.length <= 100`
* `1 <= words[i].length <= 100`
* `words[i]` consists only of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_first_palindromic_string_in_the_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_first_palindromic_string_in_the_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(total characters)
# Space: O(1)
def first_palindrome(self, words: list[str]) -> str:
for word in words:
if word == word[::-1]:
return word
return ""
```
## Complexity
| Time | Space |
| ------------------- | ----- |
| O(total characters) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find if Array Can Be Sorted Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-if-array-can-be-sorted
Tested Python solution for LeetCode 3011 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 3011, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-if-array-can-be-sorted/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3011 # by problem number
lcpy gen -s find_if_array_can_be_sorted # by problem name
```
## Problem
You are given a 0-indexed array of positive integers `nums`.
In one operation, you can swap any two adjacent elements if they have the same number of set bits. You are allowed to do this operation any number of times (including zero).
Return `true` if you can sort the array in ascending order, else return `false`.
### Examples
```
Input: nums = [8,4,2,30,15]
Output: true
Explanation: Let's look at the binary representation of every element. The numbers 2, 4, and 8 have one set bit each with binary representation "10", "100", and "1000" respectively. The numbers 15 and 30 have four set bits each with binary representation "1111" and "11110".
We can sort the array using 4 operations:
- Swap nums[0] with nums[1]. This operation is valid because 8 and 4 have one set bit each. The array becomes [4,8,2,30,15].
- Swap nums[1] with nums[2]. This operation is valid because 8 and 2 have one set bit each. The array becomes [4,2,8,30,15].
- Swap nums[0] with nums[1]. This operation is valid because 4 and 2 have one set bit each. The array becomes [2,4,8,30,15].
- Swap nums[3] with nums[4]. This operation is valid because 30 and 15 have four set bits each. The array becomes [2,4,8,15,30].
The array has become sorted, hence we return true.
Note that there may be other sequences of operations which also sort the array.
```
```
Input: nums = [1,2,3,4,5]
Output: true
Explanation: The array is already sorted, hence we return true.
```
```
Input: nums = [3,16,8,4,2]
Output: false
Explanation: It can be shown that it is not possible to sort the input array using any number of operations.
```
### Constraints
* 1 \<= nums.length \<= 100
* 1 \<= nums\[i] \<= 2^8
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_if_array_can_be_sorted/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_if_array_can_be_sorted/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2) worst case from sorting each segment
# Space: O(n) for the working copy
def can_sort_array(self, nums: list[int]) -> bool:
arr = list(nums)
n = len(arr)
i = 0
while i < n:
bits = arr[i].bit_count()
j = i
while j < n and arr[j].bit_count() == bits:
j += 1
arr[i:j] = sorted(arr[i:j])
i = j
return arr == sorted(nums)
```
## Complexity
| Time | Space |
| ------------------------------------------- | ------------------------- |
| O(n^2) worst case from sorting each segment | O(n) for the working copy |
## Tags
[NeetCode All](/catalog/neetcode).
# Find in Mountain Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-in-mountain-array
Tested Python solution for LeetCode 1095 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1095, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/find-in-mountain-array/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1095 # by problem number
lcpy gen -s find_in_mountain_array # by problem name
```
## Problem
(This problem is an **interactive problem**.)
You may recall that an array `arr` is a **mountain array** if and only if:
* `arr.length >= 3`
* There exists some `i` with `0 < i < arr.length - 1` such that:
* `arr[0] < arr[1] < ... < arr[i - 1] < arr[i]`
* `arr[i] > arr[i + 1] > ... > arr[arr.length - 1]`
Given a mountain array `mountainArr`, return **the minimum** `index` such that `mountainArr.get(index) == target`. If such an `index` does not exist, return `-1`.
**You cannot access the mountain array directly.** You may only access the array using a `MountainArray` interface:
* `MountainArray.get(k)` returns the element of the array at index `k` (0-indexed).
* `MountainArray.length()` returns the length of the array.
Submissions making more than `100` calls to `MountainArray.get` will be judged *Wrong Answer*.
### Examples
```
Input: mountainArr = [1,2,3,4,5,3,1], target = 3
Output: 2
Explanation: 3 exists in the array, at index=2 and index=5. Return the minimum index, which is 2.
```
```
Input: mountainArr = [0,1,2,4,2,1], target = 3
Output: -1
Explanation: 3 does not exist in the array, so we return -1.
```
### Constraints
* `3 <= mountainArr.length() <= 10^4`
* `0 <= target <= 10^9`
* `0 <= mountainArr.get(index) <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_in_mountain_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_in_mountain_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class MountainArray:
def get(self, index: int) -> int:
raise NotImplementedError
def length(self) -> int:
raise NotImplementedError
class Solution:
# Time: O(log n) — three binary searches (peak, ascending side, descending side)
# Space: O(1)
def find_in_mountain_array(self, target: int, mountain_arr: MountainArray) -> int:
n = mountain_arr.length()
# 1. Find the peak index (mountainArr is strictly increasing then decreasing).
lo, hi = 1, n - 2
while lo < hi:
mid = (lo + hi) // 2
if mountain_arr.get(mid) < mountain_arr.get(mid + 1):
lo = mid + 1
else:
hi = mid
peak = lo
# 2. Binary search the strictly ascending left slope for target (min index).
lo, hi = 0, peak
while lo <= hi:
mid = (lo + hi) // 2
value = mountain_arr.get(mid)
if value == target:
return mid
if value < target:
lo = mid + 1
else:
hi = mid - 1
# 3. Binary search the strictly descending right slope for target.
lo, hi = peak + 1, n - 1
while lo <= hi:
mid = (lo + hi) // 2
value = mountain_arr.get(mid)
if value == target:
return mid
if value > target:
lo = mid + 1
else:
hi = mid - 1
return -1
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------------ | ----- |
| O(log n) — three binary searches (peak, ascending side, descending side) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find K Closest Elements Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-k-closest-elements
Tested Python solution for LeetCode 658 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 658, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sliding Window](/catalog/topics/sliding-window), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/find-k-closest-elements/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 658 # by problem number
lcpy gen -s find_k_closest_elements # by problem name
```
## Problem
Given a **sorted** integer array `arr`, two integers `k` and `x`, return the `k` closest integers to `x` in the array. The result should also be sorted in ascending order.
An integer `a` is closer to `x` than an integer `b` if:
* `|a - x| < |b - x|`, or
* `|a - x| == |b - x|` and `a < b`
### Examples
```
Input: arr = [1,2,3,4,5], k = 4, x = 3
Output: [1,2,3,4]
```
```
Input: arr = [1,1,2,3,4,5], k = 4, x = -1
Output: [1,1,2,3]
```
### Constraints
* `1 <= k <= arr.length`
* `1 <= arr.length <= 10^4`
* `arr` is sorted in **ascending** order.
* `-10^4 <= arr[i], x <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_closest_elements/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_closest_elements/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log(n-k))
# Space: O(1)
def find_closest_elements(self, arr: list[int], k: int, x: int) -> list[int]:
"""
Find k closest elements to x using binary search on window positions.
Time: O(log(n-k)) - Binary search on n-k possible window positions
Space: O(1) - Only using constant extra variables
Algorithm:
- Search space: all possible left boundaries for k-element window [0, n-k]
- For each position mid, compare window boundaries: arr[mid] vs arr[mid+k]
- If arr[mid] farther from x, move search right; otherwise move left
- Leverages sorted array property for O(log) efficiency vs O(n) linear scan
Example: arr=[0,1,2,3,4], k=3, x=3
Windows: [0,1,2], [1,2,3], [2,3,4]
Distances: max(2,1), max(0,1), max(1,1) → choose [1,2,3]
"""
# Binary search to find the left boundary of the k-element window
left, right = 0, len(arr) - k
while left < right:
mid = (left + right) // 2
# Compare distances: arr[mid] vs arr[mid + k]
# If arr[mid] is farther from x than arr[mid + k], move left boundary right
if x - arr[mid] > arr[mid + k] - x:
left = mid + 1
else:
right = mid
return arr[left : left + k]
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(log(n-k)) | O(1) |
## Tags
[Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find K-Length Substrings With No Repeated
Source: https://leetcode-py.wisl.dev/problems/find-k-length-substrings-with-no-repeated-characters
Tested Python solution for LeetCode 1100 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1100, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/find-k-length-substrings-with-no-repeated-characters/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1100 # by problem number
lcpy gen -s find_k_length_substrings_with_no_repeated_characters # by problem name
```
## Problem
Given a string `s` and an integer `k`, return *the number of substrings in* `s` *of length* `k` *with no repeated characters*.
### Examples
```
Input: s = "havefunonleetcode", k = 5
Output: 6
Explanation: There are 6 substrings they are: 'havef','avefu','vefun','efuno','etcod','tcode'.
```
```
Input: s = "home", k = 5
Output: 0
Explanation: Notice k can be larger than the length of s. In this case, it is not possible to find any substring.
```
### Constraints
* 1 \<= s.length \<= 10^4
* s consists of lowercase English letters.
* 1 \<= k \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_length_substrings_with_no_repeated_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_length_substrings_with_no_repeated_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(1) - at most 26 distinct letters
def num_k_len_substr_no_repeats(self, s: str, k: int) -> int:
if k > len(s):
return 0
cnt = Counter(s[:k])
ans = int(len(cnt) == k)
for i in range(k, len(s)):
cnt[s[i]] += 1
cnt[s[i - k]] -= 1
if cnt[s[i - k]] == 0:
cnt.pop(s[i - k])
ans += int(len(cnt) == k)
return ans
```
## Complexity
| Time | Space |
| ---- | ---------------------------------- |
| O(n) | O(1) - at most 26 distinct letters |
## Tags
[NeetCode All](/catalog/neetcode).
# Find K Pairs with Smallest Sums
Source: https://leetcode-py.wisl.dev/problems/find-k-pairs-with-smallest-sums
Tested Python solution for LeetCode 373 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 373, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/find-k-pairs-with-smallest-sums/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 373 # by problem number
lcpy gen -s find_k_pairs_with_smallest_sums # by problem name
```
## Problem
You are given two integer arrays `nums1` and `nums2` sorted in **non-decreasing order** and an integer `k`.
Define a pair `(u, v)` which consists of one element from the first array and one element from the second array.
Return the `k` pairs `(u1, v1), (u2, v2), ..., (uk, vk)` with the smallest sums.
### Examples
```
Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
Output: [[1,2],[1,4],[1,6]]
Explanation: The first 3 pairs are returned from the sequence: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
```
```
Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
Output: [[1,1],[1,1]]
Explanation: The first 2 pairs are returned from the sequence: [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 10^5
* -10^9 \<= nums1\[i], nums2\[i] \<= 10^9
* nums1 and nums2 both are sorted in non-decreasing order.
* 1 \<= k \<= 10^4
* k \<= nums1.length \* nums2.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_pairs_with_smallest_sums/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_pairs_with_smallest_sums/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(k log min(k, len(nums1)))
# Space: O(min(k, len(nums1)))
def k_smallest_pairs(self, nums1: list[int], nums2: list[int], k: int) -> list[list[int]]:
result: list[list[int]] = []
heap: list[tuple[int, int, int]] = []
for i in range(min(len(nums1), k)):
heapq.heappush(heap, (nums1[i] + nums2[0], i, 0))
while heap and len(result) < k:
_, i, j = heapq.heappop(heap)
result.append([nums1[i], nums2[j]])
if j + 1 < len(nums2):
heapq.heappush(heap, (nums1[i] + nums2[j + 1], i, j + 1))
return result
```
## Complexity
| Time | Space |
| --------------------------- | --------------------- |
| O(k log min(k, len(nums1))) | O(min(k, len(nums1))) |
## Tags
# Find K-th Smallest Pair Distance
Source: https://leetcode-py.wisl.dev/problems/find-k-th-smallest-pair-distance
Tested Python solution for LeetCode 719 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 719, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-k-th-smallest-pair-distance/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 719 # by problem number
lcpy gen -s find_k_th_smallest_pair_distance # by problem name
```
## Problem
The distance of a pair of integers `a` and `b` is defined as the absolute difference between `a` and `b`.
Given an integer array `nums` and an integer `k`, return the `kth` smallest distance among all the pairs `nums[i]` and `nums[j]` where `0 <= i < j < nums.length`.
### Examples
```
Input: nums = [1,3,1], k = 1
Output: 0
Explanation: Here are all the pairs:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
Then the 1st smallest distance pair is (1,1), and its distance is 0.
```
```
Input: nums = [1,1,1], k = 2
Output: 0
```
```
Input: nums = [1,6,1], k = 3
Output: 5
```
### Constraints
* n == nums.length
* 2 \<= n \<= 10^4
* 0 \<= nums\[i] \<= 10^6
* 1 \<= k \<= n \* (n - 1) / 2
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_th_smallest_pair_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_k_th_smallest_pair_distance/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_right
class Solution:
# Time: O(n log n + n log W) where W = max(nums) - min(nums)
# Space: O(n)
def smallest_distance_pair(self, nums: list[int], k: int) -> int:
nums = sorted(nums)
n = len(nums)
def count_pairs_within(dist: int) -> int:
count = 0
for i in range(n):
count += bisect_right(nums, nums[i] + dist, lo=i + 1) - (i + 1)
return count
low, high = 0, nums[-1] - nums[0]
while low < high:
mid = (low + high) // 2
if count_pairs_within(mid) >= k:
high = mid
else:
low = mid + 1
return low
```
## Complexity
| Time | Space |
| ---------------------------------------------------- | ----- |
| O(n log n + n log W) where W = max(nums) - min(nums) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Kth Bit in Nth Binary String
Source: https://leetcode-py.wisl.dev/problems/find-kth-bit-in-nth-binary-string
Tested Python solution for LeetCode 1545 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1545, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Recursion](/catalog/topics/recursion), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/find-kth-bit-in-nth-binary-string/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1545 # by problem number
lcpy gen -s find_kth_bit_in_nth_binary_string # by problem name
```
## Problem
Given two positive integers `n` and `k`, the binary string `S_n` is formed as follows:
* `S_1 = "0"`
* `S_i = S_i - 1 + "1" + reverse(invert(S_i - 1))` for `i > 1`
Where `+` denotes the concatenation operation, `reverse(x)` returns the reversed string `x`, and `invert(x)` inverts all the bits in `x` (`0` changes to `1` and `1` changes to `0`).
For example, the first four strings in the above sequence are:
* `S_1 = "0"`
* `S_2 = "011"`
* `S_3 = "0111001"`
* `S_4 = "011100110110001"`
Return *the* `k^th` *bit* *in* `S_n`. It is guaranteed that `k` is valid for the given `n`.
### Examples
```
Input: n = 3, k = 1
Output: "0"
Explanation: S3 is "0111001".
The 1st bit is "0".
```
```
Input: n = 4, k = 11
Output: "1"
Explanation: S4 is "011100110110001".
The 11th bit is "1".
```
### Constraints
* `1 <= n <= 20`
* `1 <= k <= 2^n - 1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_kth_bit_in_nth_binary_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_kth_bit_in_nth_binary_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log k)
# Space: O(log k)
def find_kth_bit(self, n: int, k: int) -> str:
if k == 1:
return "0"
half = 1
while half * 2 + 1 < k:
half = half * 2 + 1
mid = half + 1
if k == mid:
return "1"
mirrored = self.find_kth_bit(n, mid - (k - mid))
return "0" if mirrored == "1" else "1"
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(log k) | O(log k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Largest Value in Each Tree Row
Source: https://leetcode-py.wisl.dev/problems/find-largest-value-in-each-tree-row
Tested Python solution for LeetCode 515 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 515, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/find-largest-value-in-each-tree-row/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 515 # by problem number
lcpy gen -s find_largest_value_in_each_tree_row # by problem name
```
## Problem
Given the `root` of a binary tree, return *an array of the largest value in each row* of the tree **(0-indexed)**.
### Examples

```
Input: root = [1,3,2,5,3,null,9]
Output: [1,3,9]
```
```
Input: root = [1,2,3]
Output: [1,3]
```
### Constraints
* The number of nodes in the tree will be in the range `[0, 10^4]`.
* `-2^31 <= Node.val <= 2^31 - 1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_largest_value_in_each_tree_row/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_largest_value_in_each_tree_row/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(n)
def largest_values(self, root: TreeNode[int] | None) -> list[int]:
if root is None:
return []
result: list[int] = []
queue: deque[TreeNode[int]] = deque([root])
while queue:
result.append(max(node.val for node in queue))
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Leaves of Binary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-leaves-of-binary-tree
Tested Python solution for LeetCode 366 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 366, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/find-leaves-of-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 366 # by problem number
lcpy gen -s find_leaves_of_binary_tree # by problem name
```
## Problem
Given the `root` of a binary tree, collect a tree's nodes as if you were doing this:
* Collect all the leaf nodes.
* Remove all the leaf nodes.
* Repeat until the tree is empty.
### Examples

```
Input: root = [1,2,3,4,5]
Output: [[4,5,3],[2],[1]]
Explanation:
[[3,5,4],[2],[1]] and [[3,4,5],[2],[1]] are also considered correct answers since per each level it does not matter the order on which elements are returned.
```
```
Input: root = [1]
Output: [[1]]
```
### Constraints
* The number of nodes in the tree is in the range `[1, 100]`.
* `-100 <= Node.val <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_leaves_of_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_leaves_of_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) — every node visited once
# Space: O(h) — recursion depth equals tree height
def find_leaves(self, root: TreeNode[int] | None) -> list[list[int]]:
result: list[list[int]] = []
def height(node: TreeNode[int] | None) -> int:
if node is None:
return 0
h = 1 + max(height(node.left), height(node.right))
while len(result) < h:
result.append([])
result[h - 1].append(node.val)
return h
height(root)
return result
```
## Complexity
| Time | Space |
| ------------------------------ | ----------------------------------------- |
| O(n) — every node visited once | O(h) — recursion depth equals tree height |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Lucky Integer in an Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-lucky-integer-in-an-array
Tested Python solution for LeetCode 1394 with 27 pytest cases. Generate a practice environment with lcpy.
LeetCode 1394, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/find-lucky-integer-in-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1394 # by problem number
lcpy gen -s find_lucky_integer_in_an_array # by problem name
```
## Problem
Given an array of integers `arr`, a **lucky integer** is an integer that has a frequency in the array equal to its value.
Return *the largest **lucky integer** in the array*. If there is no **lucky integer** return `-1`.
### Examples
```
Input: arr = [2,2,3,4]
Output: 2
Explanation: The only lucky number in the array is 2 because frequency[2] == 2.
```
```
Input: arr = [1,2,2,3,3,3]
Output: 3
Explanation: 1, 2 and 3 are all lucky numbers, return the largest of them.
```
```
Input: arr = [2,2,2,3,3]
Output: -1
Explanation: There are no lucky numbers in the array.
```
### Constraints
* 1 \<= arr.length \<= 500
* 1 \<= arr\[i] \<= 500
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_lucky_integer_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_lucky_integer_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def find_lucky(self, arr: list[int]) -> int:
counts: dict[int, int] = {}
for value in arr:
counts[value] = counts.get(value, 0) + 1
result = -1
for value, count in counts.items():
if value == count:
result = max(result, value)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Median from Data Stream Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-median-from-data-stream
Tested Python solution for LeetCode 295 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 295, [Hard](/catalog/hard). Topics: [Two Pointers](/catalog/topics/two-pointers), [Design](/catalog/topics/design), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Data Stream](/catalog/topics/data-stream). [View on LeetCode](https://leetcode.com/problems/find-median-from-data-stream/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 295 # by problem number
lcpy gen -s find_median_from_data_stream # by problem name
```
## Problem
The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.
* For example, for `arr = [2,3,4]`, the median is `3`.
* For example, for `arr = [2,3]`, the median is `(2 + 3) / 2 = 2.5`.
Implement the MedianFinder class:
* `MedianFinder()` initializes the `MedianFinder` object.
* `void addNum(int num)` adds the integer `num` from the data stream to the data structure.
* `double findMedian()` returns the median of all elements so far. Answers within `10^-5` of the actual answer will be accepted.
### Examples
```
Input
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
Output
[null, null, null, 1.5, null, 2.0]
```
**Explanation:**
```
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.addNum(2); // arr = [1, 2]
medianFinder.findMedian(); // return 1.5 (i.e., (1 + 2) / 2)
medianFinder.addNum(3); // arr = [1, 2, 3]
medianFinder.findMedian(); // return 2.0
```
### Constraints
* `-10^5 <= num <= 10^5`
* There will be at least one element in the data structure before calling `findMedian`.
* At most `5 * 10^4` calls will be made to `addNum` and `findMedian`.
**Follow up:**
* If all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?
* If `99%` of all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_median_from_data_stream/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_median_from_data_stream/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class MedianFinder:
# Two balanced heaps approach for general streaming median
# Time: O(1) init
# Space: O(n)
def __init__(self) -> None:
self.small: list[int] = [] # max heap (negated)
self.large: list[int] = [] # min heap
# Time: O(log n)
# Space: O(1)
def add_num(self, num: int) -> None:
heapq.heappush(self.small, -num)
if self.small and self.large and (-self.small[0] > self.large[0]):
heapq.heappush(self.large, -heapq.heappop(self.small))
if len(self.small) > len(self.large) + 1:
heapq.heappush(self.large, -heapq.heappop(self.small))
if len(self.large) > len(self.small) + 1:
heapq.heappush(self.small, -heapq.heappop(self.large))
# Time: O(1)
# Space: O(1)
def find_median(self) -> float:
if len(self.small) > len(self.large):
return -self.small[0]
if len(self.large) > len(self.small):
return self.large[0]
return (-self.small[0] + self.large[0]) / 2.0
class MedianFinderHybrid:
# Hybrid counting array + heaps for bounded ranges with outliers
# Time: O(1) init
# Space: O(R + k) where R = range_size, k = outliers
def __init__(self, min_val: int = 0, max_val: int = 100) -> None:
self.min_val = min_val
self.max_val = max_val
self.counts = [0] * (max_val - min_val + 1)
self.outliers_small: list[int] = [] # max heap for < min_val
self.outliers_large: list[int] = [] # min heap for > max_val
self.total = 0
# Time: O(1) for range, O(log k) for outliers
# Space: O(1)
def add_num(self, num: int) -> None:
if self.min_val <= num <= self.max_val:
self.counts[num - self.min_val] += 1
elif num < self.min_val:
heapq.heappush(self.outliers_small, -num)
else:
heapq.heappush(self.outliers_large, num)
self.total += 1
# Time: O(R + k log k) worst case, O(R) typical, O(1) if R constant
# Space: O(k) for sorting outliers
def find_median(self) -> float:
target = self.total // 2
count = 0
# Count outliers < 0
outliers_small_count = len(self.outliers_small)
if count + outliers_small_count > target:
sorted_small = sorted([-x for x in self.outliers_small])
if self.total % 2 == 1:
return sorted_small[target - count]
else:
if target - count == 0:
return (sorted_small[0] + self._get_next_value(0)) / 2.0
return (sorted_small[target - count - 1] + sorted_small[target - count]) / 2.0
count += outliers_small_count
# Count [min_val, max_val] range
for i in range(len(self.counts)):
if count + self.counts[i] > target:
val = i + self.min_val
if self.total % 2 == 1:
return val
else:
if target == count:
return (self._get_prev_value(count - 1) + val) / 2.0
return val
count += self.counts[i]
# Must be in outliers > 100
sorted_large = sorted(self.outliers_large)
idx = target - count
if self.total % 2 == 1:
return sorted_large[idx]
else:
if idx == 0:
return (self._get_prev_value(count - 1) + sorted_large[0]) / 2.0
return (sorted_large[idx - 1] + sorted_large[idx]) / 2.0
def _get_prev_value(self, pos: int) -> int:
count = 0
# Check outliers < 0
if pos < len(self.outliers_small):
return sorted([-x for x in self.outliers_small])[pos]
count += len(self.outliers_small)
# Check [min_val, max_val] range
for i in range(len(self.counts)):
if count + self.counts[i] > pos:
return i + self.min_val
count += self.counts[i]
# Must be in outliers > 100
return sorted(self.outliers_large)[pos - count]
def _get_next_value(self, pos: int) -> int:
return self._get_prev_value(pos + 1)
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(1) init | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Find Minimum Diameter After Merging Two Trees
Source: https://leetcode-py.wisl.dev/problems/find-minimum-diameter-after-merging-two-trees
Tested Python solution for LeetCode 3203 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 3203, [Hard](/catalog/hard). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/find-minimum-diameter-after-merging-two-trees/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3203 # by problem number
lcpy gen -s find_minimum_diameter_after_merging_two_trees # by problem name
```
## Problem
There exist two **undirected** trees with `n` and `m` nodes, numbered from `0` to `n - 1` and from `0` to `m - 1`, respectively. You are given two 2D integer arrays `edges1` and `edges2` of lengths `n - 1` and `m - 1`, respectively, where `edges1[i] = [ai, bi]` indicates that there is an edge between nodes `ai` and `bi` in the first tree and `edges2[i] = [ui, vi]` indicates that there is an edge between nodes `ui` and `vi` in the second tree.
You must connect one node from the first tree with another node from the second tree with an edge.
Return the **minimum** possible **diameter** of the resulting tree.
The **diameter** of a tree is the length of the longest path between any two nodes in the tree.
### Examples

```
Input: edges1 = [[0,1],[0,2],[0,3]], edges2 = [[0,1]]
Output: 3
```
**Explanation:** We can obtain a tree of diameter 3 by connecting node 0 from the first tree with any node from the second tree.

```
Input: edges1 = [[0,1],[0,2],[0,3],[2,4],[2,5],[3,6],[2,7]], edges2 = [[0,1],[0,2],[0,3],[2,4],[2,5],[3,6],[2,7]]
Output: 5
```
**Explanation:** We can obtain a tree of diameter 5 by connecting node 0 from the first tree with node 0 from the second tree.
### Constraints
* `1 <= n, m <= 10^5`
* `edges1.length == n - 1`
* `edges2.length == m - 1`
* `edges1[i].length == edges2[i].length == 2`
* `edges1[i] = [ai, bi]`
* `0 <= ai, bi < n`
* `edges2[i] = [ui, vi]`
* `0 <= ui, vi < m`
* The input is generated such that `edges1` and `edges2` represent valid trees.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_minimum_diameter_after_merging_two_trees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_minimum_diameter_after_merging_two_trees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n + m)
# Space: O(n + m)
def minimum_diameter_after_merge(self, edges1: list[list[int]], edges2: list[list[int]]) -> int:
d1 = self._diameter(len(edges1) + 1, edges1)
d2 = self._diameter(len(edges2) + 1, edges2)
return max(d1, d2, (d1 + 1) // 2 + (d2 + 1) // 2 + 1)
def _diameter(self, n: int, edges: list[list[int]]) -> int:
adj: list[list[int]] = [[] for _ in range(n)]
for a, b in edges:
adj[a].append(b)
adj[b].append(a)
def farthest(src: int) -> tuple[int, int]:
dist = [-1] * n
dist[src] = 0
queue = deque([src])
last = src
while queue:
node = queue.popleft()
last = node
for nxt in adj[node]:
if dist[nxt] == -1:
dist[nxt] = dist[node] + 1
queue.append(nxt)
return last, dist[last]
endpoint, _ = farthest(0)
_, diameter = farthest(endpoint)
return diameter
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + m) | O(n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Minimum in Rotated Sorted Array
Source: https://leetcode-py.wisl.dev/problems/find-minimum-in-rotated-sorted-array
Tested Python solution for LeetCode 153 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 153, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 153 # by problem number
lcpy gen -s find_minimum_in_rotated_sorted_array # by problem name
```
## Problem
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:
* `[4,5,6,7,0,1,2]` if it was rotated `4` times.
* `[0,1,2,4,5,6,7]` if it was rotated `7` times.
Notice 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]]`.
Given the sorted rotated array `nums` of **unique** elements, return *the minimum element of this array*.
You must write an algorithm that runs in O(log n) time.
### Examples
```
Input: nums = [3,4,5,1,2]
Output: 1
Explanation: The original array was [1,2,3,4,5] rotated 3 times.
```
```
Input: nums = [4,5,6,7,0,1,2]
Output: 0
Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
```
```
Input: nums = [11,13,15,17]
Output: 11
Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
```
### Constraints
* n == nums.length
* 1 \<= n \<= 5000
* -5000 \<= nums\[i] \<= 5000
* All the integers of nums are **unique**.
* nums is sorted and rotated between 1 and n times.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_minimum_in_rotated_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_minimum_in_rotated_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n) - binary search
# Space: O(1) - only using constant extra space
def find_min(self, nums: list[int]) -> int:
"""
Find the minimum element in a rotated sorted array using binary search.
The key insight is that in a rotated sorted array, one half is always sorted.
We can determine which half contains the minimum by comparing the middle
element with the rightmost element.
Algorithm:
1. If nums[left] < nums[right], the array is not rotated, return nums[left]
2. Otherwise, find the rotation point using binary search
3. The minimum is always at the rotation point
"""
left, right = 0, len(nums) - 1
# If the array is not rotated, the first element is the minimum
if nums[left] < nums[right]:
return nums[left]
# Binary search to find the rotation point
while left < right:
mid = left + (right - left) // 2
# If mid element is greater than right element,
# the rotation point is in the right half
if nums[mid] > nums[right]:
left = mid + 1
else:
# If mid element is less than or equal to right element,
# the rotation point is in the left half (including mid)
right = mid
return nums[left]
```
## Complexity
| Time | Space |
| ------------------------ | -------------------------------------- |
| O(log n) - binary search | O(1) - only using constant extra space |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find Minimum in Rotated Sorted Array II
Source: https://leetcode-py.wisl.dev/problems/find-minimum-in-rotated-sorted-array-ii
Tested Python solution for LeetCode 154 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 154, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 154 # by problem number
lcpy gen -s find_minimum_in_rotated_sorted_array_ii # by problem name
```
## Problem
Suppose an array of length `n` sorted in ascending order is **rotated** between `1` and `n` times. For example, the array `nums = [0,1,4,4,5,6,7]` might become:
* `[4,5,6,7,0,1,4]` if it was rotated `4` times.
* `[0,1,4,4,5,6,7]` if it was rotated `7` times.
Notice 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]]`.
Given the sorted rotated array `nums` that may contain **duplicates**, return *the minimum element of this array*.
You must decrease the overall operation steps as much as possible.
### Examples
```
Input: nums = [1,3,5]
Output: 1
```
```
Input: nums = [2,2,2,0,1]
Output: 0
```
### Constraints
* n == nums.length
* 1 \<= n \<= 5000
* -5000 \<= nums\[i] \<= 5000
* nums is sorted and rotated between 1 and n times.
**Follow up:** This problem is similar to Find Minimum in Rotated Sorted Array, but `nums` may contain duplicates. Would this affect the runtime complexity? How and why?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_minimum_in_rotated_sorted_array_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_minimum_in_rotated_sorted_array_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n) average, O(n) worst case with all-duplicate stretches
# Space: O(1)
def find_min(self, nums: list[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid + 1
elif nums[mid] < nums[right]:
right = mid
else:
right -= 1
return nums[left]
```
## Complexity
| Time | Space |
| -------------------------------------------------------------- | ----- |
| O(log n) average, O(n) worst case with all-duplicate stretches | O(1) |
## Tags
# Find Missing and Repeated Values
Source: https://leetcode-py.wisl.dev/problems/find-missing-and-repeated-values
Tested Python solution for LeetCode 2965 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 2965, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/find-missing-and-repeated-values/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2965 # by problem number
lcpy gen -s find_missing_and_repeated_values # by problem name
```
## Problem
You are given a 0-indexed 2D integer matrix `grid` of size `n * n` with values in the range `[1, n^2]`. Each integer appears exactly once except `a` which appears twice and `b` which is missing. The task is to find the repeating and missing numbers `a` and `b`.
Return a 0-indexed integer array `ans` of size 2 where `ans[0]` equals to `a` and `ans[1]` equals to `b`.
### Examples
```
Input: grid = [[1,3],[2,2]]
Output: [2,4]
Explanation: Number 2 is repeated and number 4 is missing so the answer is [2,4].
```
```
Input: grid = [[9,1,7],[8,9,2],[3,4,6]]
Output: [9,5]
Explanation: Number 9 is repeated and number 5 is missing so the answer is [9,5].
```
### Constraints
* 2 \<= n == grid.length == grid\[i].length \<= 50
* 1 \<= grid\[i]\[j] \<= n \* n
* For all x that 1 \<= x \<= n \* n there is exactly one x that is not equal to any of the grid members.
* For all x that 1 \<= x \<= n \* n there is exactly one x that is equal to exactly two of the grid members.
* For all x that 1 \<= x \<= n \* n except two of them there is exactly one pair of i, j that 0 \<= i, j \<= n - 1 and grid\[i]\[j] == x.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_missing_and_repeated_values/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_missing_and_repeated_values/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def find_missing_and_repeated_values(self, grid: list[list[int]]) -> list[int]:
n = len(grid)
counts: dict[int, int] = {}
repeated = 0
for row in grid:
for val in row:
if val in counts:
repeated = val
counts[val] = counts.get(val, 0) + 1
total = n * n
missing = total * (total + 1) // 2 - sum(counts)
return [repeated, missing]
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Missing Observations Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-missing-observations
Tested Python solution for LeetCode 2028 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2028, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/find-missing-observations/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2028 # by problem number
lcpy gen -s find_missing_observations # by problem name
```
## Problem
You have observations of `n + m` **6-sided** dice rolls with each face numbered from `1` to `6`. `n` of the observations went missing, and you only have the observations of `m` rolls. Fortunately, you have also calculated the **average value** of the `n + m` rolls.
You are given an integer array `rolls` of length `m` where `rolls[i]` is the value of the `i`th observation. You are also given the two integers `mean` and `n`.
Return an array of length `n` containing the missing observations such that the **average value** of the `n + m` rolls is **exactly** `mean`. If there are multiple valid answers, return **any of them**. If no such array exists, return an empty array.
The **average value** of a set of `k` numbers is the sum of the numbers divided by `k`.
Note that `mean` is an integer, so the sum of the `n + m` rolls should be divisible by `n + m`.
### Examples
```
Input: rolls = [3,2,4,3], mean = 4, n = 2
Output: [6,6]
Explanation: The mean of all n + m rolls is (3 + 2 + 4 + 3 + 6 + 6) / 6 = 4.
```
```
Input: rolls = [1,5,6], mean = 3, n = 4
Output: [2,3,2,2]
Explanation: The mean of all n + m rolls is (1 + 5 + 6 + 2 + 3 + 2 + 2) / 7 = 3.
```
```
Input: rolls = [1,2,3,4], mean = 6, n = 4
Output: []
Explanation: It is impossible for the mean to be 6 no matter what the 4 missing rolls are.
```
### Constraints
* `m == rolls.length`
* `1 <= n, m <= 10^5`
* `1 <= rolls[i], mean <= 6`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_missing_observations/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_missing_observations/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m + n)
# Space: O(n)
def missing_rolls(self, rolls: list[int], mean: int, n: int) -> list[int]:
target = mean * (len(rolls) + n) - sum(rolls)
if target < n or target > 6 * n:
return []
base, extra = divmod(target, n)
return [base + 1] * extra + [base] * (n - extra)
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(m + n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Mode in Binary Search Tree
Source: https://leetcode-py.wisl.dev/problems/find-mode-in-binary-search-tree
Tested Python solution for LeetCode 501 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 501, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/find-mode-in-binary-search-tree/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 501 # by problem number
lcpy gen -s find_mode_in_binary_search_tree # by problem name
```
## Problem
Given the `root` of a binary search tree (BST) with duplicates, return all the mode(s) (i.e., the most frequently occurred element) in it.
If the tree has more than one mode, return them in **any order**.
Assume a BST is defined as follows:
* The left subtree of a node contains only nodes with keys **less than or equal to** the node's key.
* The right subtree of a node contains only nodes with keys **greater than or equal to** the node's key.
* Both the left and right subtrees must also be binary search trees.
### Examples

```
Input: root = [1,null,2,2]
Output: [2]
```
```
Input: root = [0]
Output: [0]
```
### Constraints
* The number of nodes in the tree is in the range `[1, 10^4]`.
* `-10^5 <= Node.val <= 10^5`
**Follow up:** Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count.)
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_mode_in_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_mode_in_binary_search_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h) recursion stack; no counter map, only the output list
def find_mode(self, root: TreeNode[int] | None) -> list[int]:
modes: list[int] = []
max_count = 0
count = 0
prev: TreeNode[int] | None = None
def inorder(node: TreeNode[int] | None) -> None:
nonlocal max_count, count, prev
if node is None:
return
inorder(node.left)
if prev is not None and prev.val == node.val:
count += 1
else:
count = 1
if count > max_count:
max_count = count
modes.clear()
modes.append(node.val)
elif count == max_count:
modes.append(node.val)
prev = node
inorder(node.right)
inorder(root)
return modes
```
## Complexity
| Time | Space |
| ---- | ---------------------------------------------------------- |
| O(n) | O(h) recursion stack; no counter map, only the output list |
## Tags
# Find Peak Element Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-peak-element
Tested Python solution for LeetCode 162 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 162, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/find-peak-element/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 162 # by problem number
lcpy gen -s find_peak_element # by problem name
```
## Problem
A peak element is an element that is strictly greater than its neighbors.
Given a **0-indexed** integer array `nums`, find a peak element, and return its index. If the array contains multiple peaks, return the index to **any of the peaks**.
You may imagine that `nums[-1] = nums[n] = -∞`. In other words, an element is always considered to be strictly greater than a neighbor that is outside the array.
You must write an algorithm that runs in `O(log n)` time.
### Examples
```
Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.
```
```
Input: nums = [1,2,1,3,5,6,4]
Output: 5
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.
```
### Constraints
* 1 \<= nums.length \<= 1000
* -2\31\ \<= nums\[i] \<= 2\31\ - 1
* `nums[i] != nums[i + 1]` for all valid `i`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_peak_element/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_peak_element/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def find_peak_element(self, nums: list[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[mid + 1]:
right = mid
else:
left = mid + 1
return left
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Permutation Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-permutation
Tested Python solution for LeetCode 484 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 484, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/find-permutation/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 484 # by problem number
lcpy gen -s find_permutation # by problem name
```
## Problem
A permutation `perm` of `n` integers of all the integers in the range `[1, n]` can be represented as a string `s` of length `n - 1` where:
* `s[i] == 'I'` if `perm[i] < perm[i + 1]`, and
* `s[i] == 'D'` if `perm[i] > perm[i + 1]`.
Given a string `s`, reconstruct the lexicographically smallest permutation `perm` and return it.
### Examples
```
Input: s = "I"
Output: [1,2]
Explanation: [1,2] is the only legal permutation that can represented by s, where the number 1 and 2 construct an increasing relationship.
```
```
Input: s = "DI"
Output: [2,1,3]
Explanation: Both [2,1,3] and [3,1,2] can be represented as "DI", but since we want to find the smallest lexicographical permutation, you should return [2,1,3].
```
### Constraints
* `1 <= s.length <= 10^5`
* `s[i]` is either `'I'` or `'D'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_permutation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_permutation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) extra (output excluded)
def find_permutation(self, s: str) -> list[int]:
n = len(s) + 1
perm = list(range(1, n + 1))
i = 0
while i < len(s):
if s[i] == "D":
j = i
while j < len(s) and s[j] == "D":
j += 1
perm[i : j + 1] = perm[i : j + 1][::-1]
i = j
else:
i += 1
return perm
```
## Complexity
| Time | Space |
| ---- | ---------------------------- |
| O(n) | O(1) extra (output excluded) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Pivot Index Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-pivot-index
Tested Python solution for LeetCode 724 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 724, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/find-pivot-index/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 724 # by problem number
lcpy gen -s find_pivot_index # by problem name
```
## Problem
Given an array of integers `nums`, calculate the pivot index of this array.
The pivot index is the index where the sum of all the numbers strictly to the left of the index is equal to the sum of all the numbers strictly to the index's right.
If the index is on the left edge of the array, then the left sum is 0 because there are no elements to the left. This also applies to the right edge of the array.
Return the leftmost pivot index. If no such index exists, return `-1`.
### Examples
```
Input: nums = [1,7,3,6,5,6]
Output: 3
Explanation:
The pivot index is 3.
Left sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11
Right sum = nums[4] + nums[5] = 5 + 6 = 11
```
```
Input: nums = [1,2,3]
Output: -1
Explanation:
There is no index that satisfies the conditions in the problem statement.
```
```
Input: nums = [2,1,-1]
Output: 0
Explanation:
The pivot index is 0.
Left sum = 0 (no elements to the left of index 0)
Right sum = nums[1] + nums[2] = 1 + -1 = 0
```
### Constraints
* 1 \<= nums.length \<= 10^4
* -1000 \<= nums\[i] \<= 1000
**Note:** This question is the same as 1991: [Find the Middle Index in Array](https://leetcode.com/problems/find-the-middle-index-in-array/)
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_pivot_index/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_pivot_index/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def pivot_index(self, nums: list[int]) -> int:
total = sum(nums)
left_sum = 0
for i, val in enumerate(nums):
if left_sum == total - left_sum - val:
return i
left_sum += val
return -1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Polygon With the Largest Perimeter
Source: https://leetcode-py.wisl.dev/problems/find-polygon-with-the-largest-perimeter
Tested Python solution for LeetCode 2971 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2971, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Math](/catalog/topics/math), [Sorting](/catalog/topics/sorting), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/find-polygon-with-the-largest-perimeter/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2971 # by problem number
lcpy gen -s find_polygon_with_the_largest_perimeter # by problem name
```
## Problem
You are given an array of **positive** integers `nums` of length `n`.
A **polygon** is a closed plane figure that has at least `3` sides. The **longest side** of a polygon is **smaller** than the sum of its other sides.
Conversely, if you have `k` (`k >= 3`) **positive** real numbers `a1`, `a2`, `a3`, ..., `ak` where `a1 <= a2 <= a3 <= ... <= ak` and `a1 + a2 + a3 + ... + ak-1 > ak`, then there **always** exists a polygon with `k` sides whose lengths are `a1`, `a2`, `a3`, ..., `ak`.
The **perimeter** of a polygon is the sum of lengths of its sides.
Return the **largest** possible **perimeter** of a **polygon** whose sides can be formed from `nums`, or `-1` if it is not possible to create a polygon.
### Examples
```
Input: nums = [5,5,5]
Output: 15
Explanation: The only possible polygon that can be made from nums has 3 sides: 5, 5, and 5. The perimeter is 5 + 5 + 5 = 15.
```
```
Input: nums = [1,12,1,2,5,50,3]
Output: 12
Explanation: The polygon with the largest perimeter which can be made from nums has 5 sides: 1, 1, 2, 3, and 5. The perimeter is 1 + 1 + 2 + 3 + 5 = 12.
We cannot have a polygon with either 12 or 50 as the longest side because it is not possible to include 2 or more smaller sides that have a greater sum than either of them.
It can be shown that the largest possible perimeter is 12.
```
```
Input: nums = [5,5,50]
Output: -1
Explanation: There is no possible way to form a polygon from nums, as a polygon has at least 3 sides and 50 > 5 + 5.
```
### Constraints
* 3 \<= n \<= 10^5
* 1 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_polygon_with_the_largest_perimeter/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_polygon_with_the_largest_perimeter/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def largest_perimeter(self, nums: list[int]) -> int:
sides = sorted(nums)
total = sum(sides)
for i in range(len(sides) - 1, 1, -1):
if total - sides[i] > sides[i]:
return total
total -= sides[i]
return -1
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Right Interval Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-right-interval
Tested Python solution for LeetCode 436 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 436, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-right-interval/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 436 # by problem number
lcpy gen -s find_right_interval # by problem name
```
## Problem
You are given an array of intervals, where intervals\[i] = \[starti, endi] and each starti is unique.
The right interval for an interval i is an interval j such that startj >= endi and startj is minimized. Note that i may equal j.
Return an array of right interval indices for each interval i. If no right interval exists for interval i, then put -1 at index i.
### Examples
```
Input: intervals = [[1,2]]
Output: [-1]
Explanation: There is only one interval in the collection, so it outputs -1.
```
```
Input: intervals = [[3,4],[2,3],[1,2]]
Output: [-1,0,1]
Explanation: There is no right interval for [3,4].
The right interval for [2,3] is [3,4] since start0 = 3 is the smallest start that is >= end1 = 3.
The right interval for [1,2] is [2,3] since start1 = 2 is the smallest start that is >= end2 = 2.
```
```
Input: intervals = [[1,4],[2,3],[3,4]]
Output: [-1,2,-1]
Explanation: There is no right interval for [1,4] and [3,4].
The right interval for [2,3] is [3,4] since start2 = 3 is the smallest start that is >= end1 = 3.
```
### Constraints
1 \<= intervals.length \<= 2 \* 10^4
intervals\[i].length == 2
-10^6 \<= starti \<= endi \<= 10^6
The start point of each interval is unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_right_interval/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_right_interval/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import bisect
class Solution:
# Time: O(n log n)
# Space: O(n)
def find_right_interval(self, intervals: list[list[int]]) -> list[int]:
sorted_starts = sorted((interval[0], i) for i, interval in enumerate(intervals))
starts = [start for start, _ in sorted_starts]
result: list[int] = []
for interval in intervals:
pos = bisect.bisect_left(starts, interval[1])
result.append(sorted_starts[pos][1] if pos < len(starts) else -1)
return result
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
# Find Root of N-Ary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-root-of-n-ary-tree
Tested Python solution for LeetCode 1506 with 29 pytest cases. Generate a practice environment with lcpy.
LeetCode 1506, [Medium](/catalog/medium). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/find-root-of-n-ary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 29 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1506 # by problem number
lcpy gen -s find_root_of_n_ary_tree # by problem name
```
## Problem
You are given all the nodes of an **N-ary tree** as an array of `Node` objects, where each node has a **unique value**.
Return *the **root** of the N-ary tree*.
**Custom testing:**
An N-ary tree can be serialized as represented in its level order traversal where each group of children is separated by the `null` value (see examples).

For example, the above tree is serialized as `[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]`.
The testing will be done in the following way:
1. The **input data** should be provided as a serialization of the tree.
2. The driver code will construct the tree from the serialized input data and put each `Node` object into an array **in an arbitrary order**.
3. The driver code will pass the array to `findRoot`, and your function should find and return the root `Node` object in the array.
4. The driver code will take the returned `Node` object and serialize it. If the serialized value and the input data are the **same**, the test **passes**.
### Examples

```
Input: tree = [1,null,3,2,4,null,5,6]
Output: [1,null,3,2,4,null,5,6]
Explanation: The tree from the input data is shown above.
The driver code creates the tree and gives findRoot the Node objects in an arbitrary order.
For example, the passed array could be [Node(5),Node(4),Node(3),Node(6),Node(2),Node(1)] or [Node(2),Node(6),Node(1),Node(3),Node(5),Node(4)].
The findRoot function should return the root Node(1), and the driver code will serialize it and compare with the input data.
The input data and serialized Node(1) are the same, so the test passes.
```

```
Input: tree = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Output: [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
```
### Constraints
* The total number of nodes is between `[1, 5 * 10^4]`.
* Each node has a **unique** value.
**Follow up:** Could you solve this problem in constant space complexity with a linear time algorithm?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_root_of_n_ary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_root_of_n_ary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(self, val: int = 0, children: list[Node] | None = None) -> None:
self.val = val
self.children = children if children is not None else []
class Solution:
# Time: O(n)
# Space: O(1)
def find_root(self, tree: list[Node]) -> Node:
# Every value appears once as a node and once more as a child if it is
# not the root, so XOR-ing all node values with all child values leaves
# exactly the root's value.
x = 0
for node in tree:
x ^= node.val
for child in node.children:
x ^= child.val
return next(node for node in tree if node.val == x)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Smallest Common Element in All Rows
Source: https://leetcode-py.wisl.dev/problems/find-smallest-common-element-in-all-rows
Tested Python solution for LeetCode 1198 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1198, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Binary Search](/catalog/topics/binary-search), [Counting](/catalog/topics/counting), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/find-smallest-common-element-in-all-rows/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1198 # by problem number
lcpy gen -s find_smallest_common_element_in_all_rows # by problem name
```
## Problem
Given an `m x n` matrix `mat` where every row is sorted in **strictly increasing** order, return the **smallest common element** in all rows.
If there is no common element, return `-1`.
### Examples
```
Input: mat = [[1,2,3,4,5],[2,4,5,8,10],[3,5,7,9,11],[1,3,5,7,9]]
Output: 5
```
```
Input: mat = [[1,2,3],[2,3,4],[2,3,5]]
Output: 2
```
### Constraints
* m == mat.length
* n == mat\[i].length
* 1 \<= m, n \<= 500
* 1 \<= mat\[i]\[j] \<= 10^4
* mat\[i] is sorted in strictly increasing order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_smallest_common_element_in_all_rows/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_smallest_common_element_in_all_rows/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def smallest_common_element(self, mat: list[list[int]]) -> int:
counts: dict[int, int] = {}
for row in mat:
for x in row:
count = counts.get(x, 0) + 1
if count == len(mat):
return x
counts[x] = count
return -1
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find Smallest Letter Greater Than Target
Source: https://leetcode-py.wisl.dev/problems/find-smallest-letter-greater-than-target
Tested Python solution for LeetCode 744 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 744, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/find-smallest-letter-greater-than-target/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 744 # by problem number
lcpy gen -s find_smallest_letter_greater_than_target # by problem name
```
## Problem
You are given an array of characters `letters` that is sorted in **non-decreasing order**, and a character `target`. There are **at least two different** characters in `letters`.
Return *the smallest character in* `letters` *that is lexicographically greater than* `target`. If such a character does not exist, return the first character in `letters`.
### Examples
```
Input: letters = ["c","f","j"], target = "a"
Output: "c"
Explanation: The smallest character that is lexicographically greater than 'a' in letters is 'c'.
```
```
Input: letters = ["c","f","j"], target = "c"
Output: "f"
Explanation: The smallest character that is lexicographically greater than 'c' in letters is 'f'.
```
```
Input: letters = ["x","x","y","y"], target = "z"
Output: "x"
Explanation: There are no characters in letters that is lexicographically greater than 'z' so we return letters[0].
```
### Constraints
* 2 \<= letters.length \<= 10^4
* letters\[i] is a lowercase English letter.
* letters is sorted in non-decreasing order.
* letters contains at least two different characters.
* target is a lowercase English letter.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_smallest_letter_greater_than_target/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_smallest_letter_greater_than_target/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def next_greatest_letter(self, letters: list[str], target: str) -> str:
left, right = 0, len(letters)
while left < right:
mid = (left + right) // 2
if letters[mid] <= target:
left = mid + 1
else:
right = mid
return letters[left % len(letters)]
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
# Find the Celebrity Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-the-celebrity
Tested Python solution for LeetCode 277 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 277, [Medium](/catalog/medium). Topics: [Graph](/catalog/topics/graph), [Two Pointers](/catalog/topics/two-pointers), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/find-the-celebrity/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 277 # by problem number
lcpy gen -s find_the_celebrity # by problem name
```
## Problem
Suppose you are at a party with `n` people labeled from `0` to `n - 1` and among them, there may exist one celebrity. The definition of a celebrity is that all the other `n - 1` people know the celebrity, but the celebrity does not know any of them.
Now you want to find out who the celebrity is or verify that there is not one. You are only allowed to ask questions like: "Hi, A. Do you know B?" to get information about whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).
You are given an integer `n` and a helper function `bool knows(a, b)` that tells you whether `a` knows `b`. Implement a function `int findCelebrity(n)`. There will be exactly one celebrity if they are at the party.
Return *the celebrity's label if there is a celebrity at the party*. If there is no celebrity, return `-1`.
**Note** that the `n x n` 2D array `graph` given as input is **not** directly available to you, and instead **only** accessible through the helper function `knows`. `graph[i][j] == 1` represents person `i` knows person `j`, whereas `graph[i][j] == 0` represents person `i` does not know person `j`.
**Follow up:** If the maximum number of allowed calls to the API `knows` is `3 * n`, could you find a solution without exceeding the maximum number of calls?
### Examples

```
Input: graph = [[1,1,0],[0,1,0],[1,1,1]]
Output: 1
Explanation: There are three persons labeled with 0, 1 and 2. graph[i][j] = 1 means person i knows person j, otherwise graph[i][j] = 0 means person i does not know person j. The celebrity is the person labeled as 1 because both 0 and 2 know him but 1 does not know anybody.
```

```
Input: graph = [[1,0,1],[1,1,0],[0,1,1]]
Output: -1
Explanation: There is no celebrity.
```
### Constraints
* `n == graph.length == graph[i].length`
* `2 <= n <= 100`
* `graph[i][j]` is `0` or `1`.
* `graph[i][i] == 1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_celebrity/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_celebrity/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from typing import ClassVar
class Solution:
# Backing store for the knows API, injected by the test helper
graph: ClassVar[list[list[int]]] = []
# Time: O(n) knows calls
# Space: O(1)
def knows(self, a: int, b: int) -> bool:
return bool(self.graph[a][b])
# Time: O(n) knows calls
# Space: O(1)
def find_celebrity(self, n: int) -> int:
candidate = 0
for other in range(1, n):
if self.knows(candidate, other):
candidate = other
for other in range(n):
if other == candidate:
continue
if self.knows(candidate, other) or not self.knows(other, candidate):
return -1
return candidate
```
## Complexity
| Time | Space |
| ---------------- | ----- |
| O(n) knows calls | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the City With the Smallest Number of
Source: https://leetcode-py.wisl.dev/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance
Tested Python solution for LeetCode 1334 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1334, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Graph Theory](/catalog/topics/graph-theory), [Shortest Path](/catalog/topics/shortest-path), Dijkstra's Algorithm, Bellman-Ford Algorithm, Floyd-Warshall Algorithm. [View on LeetCode](https://leetcode.com/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1334 # by problem number
lcpy gen -s find_the_city_with_the_smallest_number_of_neighbors_at_a_threshold_distance # by problem name
```
## Problem
There are n cities numbered from 0 to n-1. Given the array edges where edges\[i] = \[fromi, toi, weighti] represents a bidirectional and weighted edge between cities fromi and toi, and given the integer distanceThreshold.
Return the city with the smallest number of cities that are reachable through some path and whose distance is at most distanceThreshold, If there are multiple such cities, return the city with the greatest number.
Notice that the distance of a path connecting cities i and j is equal to the sum of the edges' weights along that path.
### Examples

```
Input: n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
Output: 3
Explanation: The figure above describes the graph.
The neighboring cities at a distanceThreshold = 4 for each city are:
City 0 -> [City 1, City 2]
City 1 -> [City 0, City 2, City 3]
City 2 -> [City 0, City 1, City 3]
City 3 -> [City 1, City 2]
Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest number.
```

```
Input: n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
Output: 0
Explanation: The figure above describes the graph.
The neighboring cities at a distanceThreshold = 2 for each city are:
City 0 -> [City 1]
City 1 -> [City 0, City 4]
City 2 -> [City 3, City 4]
City 3 -> [City 2, City 4]
City 4 -> [City 1, City 2, City 3]
The city 0 has 1 neighboring city at a distanceThreshold = 2.
```
### Constraints
* 2 \<= n \<= 100
* 1 \<= edges.length \<= n \* (n - 1) / 2
* edges\[i].length == 3
* 0 \<= fromi \< toi \< n
* 1 \<= weighti, distanceThreshold \<= 10^4
* All pairs (fromi, toi) are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_city_with_the_smallest_number_of_neighbors_at_a_threshold_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_city_with_the_smallest_number_of_neighbors_at_a_threshold_distance/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def find_the_city(self, n: int, edges: list[list[int]], distance_threshold: int) -> int:
inf = 10**9
dist = [[inf] * n for _ in range(n)]
for i in range(n):
dist[i][i] = 0
for u, v, w in edges:
dist[u][v] = w
dist[v][u] = w
for k in range(n):
for i in range(n):
for j in range(n):
if dist[i][k] + dist[k][j] < dist[i][j]:
dist[i][j] = dist[i][k] + dist[k][j]
best_city, best_count = -1, n + 1
for i in range(n):
count = sum(1 for j in range(n) if j != i and dist[i][j] <= distance_threshold)
if count <= best_count:
best_count = count
best_city = i
return best_city
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Closest Palindrome Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-the-closest-palindrome
Tested Python solution for LeetCode 564 with 27 pytest cases. Generate a practice environment with lcpy.
LeetCode 564, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/find-the-closest-palindrome/description/).
Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 564 # by problem number
lcpy gen -s find_the_closest_palindrome # by problem name
```
## Problem
Given a string `n` representing an integer, return *the closest integer (not including itself), which is a palindrome*. If there is a tie, return *the smaller one*.
The closest is defined as the absolute difference minimized between two integers.
### Examples
```
Input: n = "123"
Output: "121"
```
```
Input: n = "1"
Output: "0"
```
**Explanation:** 0 and 2 are the closest palindromes but we return the smallest which is 0.
### Constraints
* `1 <= n.length <= 18`
* `n` consists of only digits.
* `n` does not have leading zeros.
* `n` is representing an integer in the range `[1, 10^18 - 1]`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_closest_palindrome/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_closest_palindrome/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(n))
# Space: O(len(n))
def nearest_palindromic(self, n: str) -> str:
num = int(n)
length = len(n)
candidates: set[int] = {10 ** (length - 1) - 1, 10**length + 1}
prefix = int(n[: (length + 1) // 2])
for p in (prefix - 1, prefix, prefix + 1):
left = str(p)
mirrored = left if length % 2 == 0 else left[:-1]
candidates.add(int(left + mirrored[::-1]))
candidates.discard(num)
best: int = candidates.pop()
for cand in candidates:
if (abs(cand - num), cand) < (abs(best - num), best):
best = cand
return str(best)
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(len(n)) | O(len(n)) |
## Tags
# Find the Derangement of An Array
Source: https://leetcode-py.wisl.dev/problems/find-the-derangement-of-an-array
Tested Python solution for LeetCode 634 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 634, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), Combinatorics. [View on LeetCode](https://leetcode.com/problems/find-the-derangement-of-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 634 # by problem number
lcpy gen -s find_the_derangement_of_an_array # by problem name
```
## Problem
In combinatorial mathematics, a **derangement** is a permutation of the elements of a set, such that no element appears in its original position.
You are given an integer `n`. There is originally an array consisting of `n` integers from `1` to `n` in ascending order, return the number of **derangements** it can generate. Since the answer may be huge, return it **modulo** `10^9 + 7`.
### Examples
```
Input: n = 3
Output: 2
Explanation: The original array is [1,2,3]. The two derangements are [2,3,1] and [3,1,2].
```
```
Input: n = 2
Output: 1
```
### Constraints
* `1 <= n <= 10^6`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_derangement_of_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_derangement_of_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_derangement(self, n: int) -> int:
mod = 1_000_000_007
if n == 1:
return 0
a, b = 1, 0 # D(1) = 0 carried via a = D(k-1)
for k in range(2, n + 1):
a, b = b, (k - 1) * (a + b) % mod
return b % mod
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Find the Difference Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-the-difference
Tested Python solution for LeetCode 389 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 389, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-the-difference/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 389 # by problem number
lcpy gen -s find_the_difference # by problem name
```
## Problem
You are given two strings `s` and `t`.
String `t` is generated by random shuffling string `s` and then add one more letter at a random position.
Return the letter that was added to `t`.
### Examples
```
Input: s = "abcd", t = "abcde"
Output: "e"
Explanation: 'e' is the letter that was added.
```
```
Input: s = "", t = "y"
Output: "y"
```
### Constraints
* `0 <= s.length <= 1000`
* `t.length == s.length + 1`
* `s` and `t` consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_difference/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_difference/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_the_difference(self, s: str, t: str) -> str:
acc = 0
for ch in s:
acc ^= ord(ch)
for ch in t:
acc ^= ord(ch)
return chr(acc)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Difference of Two Arrays
Source: https://leetcode-py.wisl.dev/problems/find-the-difference-of-two-arrays
Tested Python solution for LeetCode 2215 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2215, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/find-the-difference-of-two-arrays/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2215 # by problem number
lcpy gen -s find_the_difference_of_two_arrays # by problem name
```
## Problem
Given two **0-indexed** integer arrays `nums1` and `nums2`, return *a list* `answer` *of size* `2` where:
* `answer[0]` is a list of all **distinct** integers in `nums1` which are **not** present in `nums2`.
* `answer[1]` is a list of all **distinct** integers in `nums2` which are **not** present in `nums1`.
**Note** that the integers in the lists may be returned in **any** order.
### Examples
```
Input: nums1 = [1,2,3], nums2 = [2,4,6]
Output: [[1,3],[4,6]]
Explanation: For nums1, nums1[1] = 2 is present at index 0 of nums2, whereas nums1[0] = 1 and nums1[2] = 3 are not present in nums2. Therefore, answer[0] = [1,3]. For nums2, nums2[0] = 2 is present at index 1 of nums1, whereas nums2[1] = 4 and nums2[2] = 6 are not present in nums1. Therefore, answer[1] = [4,6].
```
```
Input: nums1 = [1,2,3,3], nums2 = [1,1,2,2]
Output: [[3],[]]
Explanation: For nums1, nums1[2] and nums1[3] are not present in nums2. Since nums1[2] == nums1[3], their value is only included once and answer[0] = [3]. Every integer in nums2 is present in nums1. Therefore, answer[1] = [].
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 1000
* -1000 \<= nums1\[i], nums2\[i] \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_difference_of_two_arrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_difference_of_two_arrays/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(n + m)
def find_difference(self, nums1: list[int], nums2: list[int]) -> list[list[int]]:
set1, set2 = set(nums1), set(nums2)
return [sorted(set1 - set2), sorted(set2 - set1)]
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + m) | O(n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Duplicate Number Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-the-duplicate-number
Tested Python solution for LeetCode 287 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 287, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/find-the-duplicate-number/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 287 # by problem number
lcpy gen -s find_the_duplicate_number # by problem name
```
## Problem
Given an array of integers `nums` containing `n + 1` integers where each integer is in the range `[1, n]` inclusive.
There is only **one repeated number** in `nums`, return *this repeated number*.
You must solve the problem **without** modifying the array `nums` and using only constant extra space.
### Examples
```
Input: nums = [1,3,4,2,2]
Output: 2
```
```
Input: nums = [3,1,3,4,2]
Output: 3
```
```
Input: nums = [3,3,3,3,3]
Output: 3
```
### Constraints
* `1 <= n <= 10^5`
* `nums.length == n + 1`
* `1 <= nums[i] <= n`
* All the integers in `nums` appear only **once** except for **precisely one integer** which appears **two or more** times.
**Follow up:**
* How can we prove that at least one duplicate number must exist in `nums`?
* Can you solve the problem in linear runtime complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_duplicate_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_duplicate_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_duplicate(self, nums: list[int]) -> int:
"""
Floyd's cycle detection - treat array as implicit linked list.
Example: nums = [1, 3, 4, 2, 2]
Array as linked list:
Index: 0 1 2 3 4
Value: [1, 3, 4, 2, 2]
↓ ↓ ↓ ↓ ↓
Points: 1 3 4 2 2
Following pointers: 0→1→3→2→4→2→4→2... (cycle!)
Visual cycle:
0
↓
1 ← start
↓
3
↓
2 ←─┐ (duplicate = cycle entrance)
↓ │
4 ──┘
Phase 1: Find intersection using slow/fast pointers
Phase 2: Find cycle entrance (duplicate) by resetting slow to start
The duplicate creates the cycle entrance because multiple indices point to it.
"""
slow = fast = nums[0]
# Find intersection point in cycle
while True:
slow = nums[slow]
fast = nums[nums[fast]]
if slow == fast:
break
# Find entrance to cycle (duplicate number)
slow = nums[0]
while slow != fast:
slow = nums[slow]
fast = nums[fast]
return slow
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find the Index of the First Occurrence in a
Source: https://leetcode-py.wisl.dev/problems/find-the-index-of-the-first-occurrence-in-a-string
Tested Python solution for LeetCode 28 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 28, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching). [View on LeetCode](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 28 # by problem number
lcpy gen -s find_the_index_of_the_first_occurrence_in_a_string # by problem name
```
## Problem
Given two strings `needle` and `haystack`, return the index of the first occurrence of `needle` in `haystack`, or `-1` if `needle` is not part of `haystack`.
### Examples
```
Input: haystack = "sadbutsad", needle = "sad"
Output: 0
Explanation: "sad" occurs at index 0 and 6.
The first occurrence is at index 0, so we return 0.
```
```
Input: haystack = "leetcode", needle = "leeto"
Output: -1
Explanation: "leeto" did not occur in "leetcode", so we return -1.
```
### Constraints
* 1 \<= haystack.length, needle.length \<= 10^4
* haystack and needle consist of only lowercase English characters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_index_of_the_first_occurrence_in_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_index_of_the_first_occurrence_in_a_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(m)
def str_str(self, haystack: str, needle: str) -> int:
m = len(needle)
if m == 0:
return 0
# Build KMP failure table: fail[i] = length of longest proper prefix
# of needle[:i+1] that is also a suffix
fail = [0] * m
k = 0
for i in range(1, m):
while k > 0 and needle[i] != needle[k]:
k = fail[k - 1]
if needle[i] == needle[k]:
k += 1
fail[i] = k
# Scan haystack using failure table to skip re-matched characters
k = 0
for i, ch in enumerate(haystack):
while k > 0 and ch != needle[k]:
k = fail[k - 1]
if ch == needle[k]:
k += 1
if k == m:
return i - m + 1
return -1
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + m) | O(m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Index of the Large Integer
Source: https://leetcode-py.wisl.dev/problems/find-the-index-of-the-large-integer
Tested Python solution for LeetCode 1533 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 1533, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/find-the-index-of-the-large-integer/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1533 # by problem number
lcpy gen -s find_the_index_of_the_large_integer # by problem name
```
## Problem
We have an integer array `arr`, where all the integers in `arr` are equal except for one integer which is **larger** than the rest of the integers. You will not be given direct access to the array, instead, you will have an **API** `ArrayReader` which has the following functions:
* `int compareSub(int l, int r, int x, int y)`: where `0 <= l, r, x, y < ArrayReader.length()`, `l <= r` and `x <= y`. The function compares the sum of sub-array `arr[l..r]` with the sum of the sub-array `arr[x..y]` and returns:
* **1** if `arr[l]+arr[l+1]+...+arr[r] > arr[x]+arr[x+1]+...+arr[y]`.
* **0** if `arr[l]+arr[l+1]+...+arr[r] == arr[x]+arr[x+1]+...+arr[y]`.
* **-1** if `arr[l]+arr[l+1]+...+arr[r] < arr[x]+arr[x+1]+...+arr[y]`.
* `int length()`: Returns the size of the array.
You are allowed to call `compareSub()` **20 times** at most. You can assume both functions work in `O(1)` time.
Return *the index of the array `arr` which has the largest integer*.
### Examples
```
Input: arr = [7,7,7,7,10,7,7,7]
Output: 4
Explanation: The following calls to the API
reader.compareSub(0, 0, 1, 1) // returns 0, this is a query comparing the sub-array (0, 0) with the sub array (1, 1), (i.e. compares arr[0] with arr[1]).
Thus we know that arr[0] and arr[1] doesn't contain the largest element.
reader.compareSub(2, 2, 3, 3) // returns 0, we can exclude arr[2] and arr[3].
reader.compareSub(4, 4, 5, 5) // returns 1, thus for sure arr[4] is the largest element in the array.
Notice that we made only 3 calls, so the answer is valid.
```
```
Input: arr = [6,6,12]
Output: 2
```
### Constraints
* `2 <= arr.length <= 5 * 10^5`
* `1 <= arr[i] <= 100`
* All elements of `arr` are equal except for one element which is larger than all other elements.
**Follow up:**
* What if there are two numbers in `arr` that are bigger than all other numbers?
* What if there is one number that is bigger than other numbers and one number that is smaller than other numbers?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_index_of_the_large_integer/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_index_of_the_large_integer/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class ArrayReader:
# Test-harness API: backs the compareSub/length interface with the array
def __init__(self, arr: list[int]) -> None:
self.arr = arr
def compare_sub(self, lo1: int, hi1: int, lo2: int, hi2: int) -> int:
left = sum(self.arr[lo1 : hi1 + 1])
right = sum(self.arr[lo2 : hi2 + 1])
return (left > right) - (left < right)
def length(self) -> int:
return len(self.arr)
class Solution:
# Time: O(log n) compare_sub calls
# Space: O(1)
def get_index(self, reader: ArrayReader) -> int:
left, right = 0, reader.length() - 1
while left < right:
# Split into two equal-size leading blocks plus a remainder block;
# equal sizes guarantee a 0 result rules out both leading blocks.
t2 = left + (right - left) // 3
t3 = left + ((right - left) // 3) * 2 + 1
cmp = reader.compare_sub(left, t2, t2 + 1, t3)
if cmp == 0:
left = t3 + 1
elif cmp == 1:
right = t2
else:
left, right = t2 + 1, t3
return left
```
## Complexity
| Time | Space |
| --------------------------- | ----- |
| O(log n) compare\_sub calls | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Length of the Longest Common Prefix
Source: https://leetcode-py.wisl.dev/problems/find-the-length-of-the-longest-common-prefix
Tested Python solution for LeetCode 3043 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 3043, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/find-the-length-of-the-longest-common-prefix/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3043 # by problem number
lcpy gen -s find_the_length_of_the_longest_common_prefix # by problem name
```
## Problem
You are given two arrays with positive integers `arr1` and `arr2`.
A prefix of a positive integer is an integer formed by one or more of its digits, starting from its leftmost digit. For example, 123 is a prefix of the integer 12345, while 234 is not.
A common prefix of two integers `a` and `b` is an integer `c`, such that `c` is a prefix of both `a` and `b`. For example, 5655359 and 56554 have common prefixes 565 and 5655 while 1223 and 43456 do not have a common prefix.
You need to find the length of the longest common prefix between all pairs of integers `(x, y)` such that `x` belongs to `arr1` and `y` belongs to `arr2`.
Return the length of the longest common prefix among all pairs. If no common prefix exists among them, return 0.
### Examples
```
Input: arr1 = [1,10,100], arr2 = [1000]
Output: 3
Explanation: There are 3 pairs (arr1[i], arr2[j]):
- The longest common prefix of (1, 1000) is 1.
- The longest common prefix of (10, 1000) is 10.
- The longest common prefix of (100, 1000) is 100.
The longest common prefix is 100 with a length of 3.
```
```
Input: arr1 = [1,2,3], arr2 = [4,4,4]
Output: 0
Explanation: There exists no common prefix for any pair (arr1[i], arr2[j]), hence we return 0.
Note that common prefixes between elements of the same array do not count.
```
### Constraints
* 1 \<= arr1.length, arr2.length \<= 5 \* 10^4
* 1 \<= arr1\[i], arr2\[i] \<= 10^8
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_length_of_the_longest_common_prefix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_length_of_the_longest_common_prefix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O((n + m) * d) where d is the max digit count
# Space: O(n * d)
def longest_common_prefix(self, arr1: list[int], arr2: list[int]) -> int:
prefixes: set[str] = set()
for x in arr1:
s = str(x)
for i in range(1, len(s) + 1):
prefixes.add(s[:i])
best = 0
for y in arr2:
s = str(y)
for i in range(best + 1, len(s) + 1):
if s[:i] in prefixes:
best = i
return best
```
## Complexity
| Time | Space |
| ---------------------------------------------- | --------- |
| O((n + m) \* d) where d is the max digit count | O(n \* d) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Longest Substring Containing Vowels
Source: https://leetcode-py.wisl.dev/problems/find-the-longest-substring-containing-vowels-in-even-counts
Tested Python solution for LeetCode 1371 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 1371, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1371 # by problem number
lcpy gen -s find_the_longest_substring_containing_vowels_in_even_counts # by problem name
```
## Problem
Given the string \s\, return the size of the longest substring containing each vowel an even number of times. That is, \'a'\, \'e'\, \'i'\, \'o'\, and \'u'\ must appear an even number of times.
### Examples
```
Input: s = "eleetminicoworoep"
Output: 13
Explanation: The longest substring is "leetminicowor" which contains two each of the vowels: e, i and o and zero of the vowels: a and u.
```
```
Input: s = "leetcodeisgreat"
Output: 5
Explanation: The longest substring is "leetc" which contains two e's.
```
```
Input: s = "bcbcbc"
Output: 6
Explanation: In this case, the given string "bcbcbc" is the longest because all vowels: a, e, i, o and u appear zero times.
```
### Constraints
* 1 \<= s.length \<= 5 x 10^5
* s contains only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_longest_substring_containing_vowels_in_even_counts/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_longest_substring_containing_vowels_in_even_counts/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) (at most 32 distinct masks)
def find_the_longest_substring(self, s: str) -> int:
# Prefix XOR bitmask over the 5 vowels; two equal prefix masks
# bracket a substring with all-even vowel counts.
first_seen = {0: -1}
mask = 0
best = 0
for i, ch in enumerate(s):
if ch == "a":
mask ^= 1
elif ch == "e":
mask ^= 2
elif ch == "i":
mask ^= 4
elif ch == "o":
mask ^= 8
elif ch == "u":
mask ^= 16
if mask in first_seen:
best = max(best, i - first_seen[mask])
else:
first_seen[mask] = i
return best
```
## Complexity
| Time | Space |
| ---- | -------------------------------- |
| O(n) | O(1) (at most 32 distinct masks) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Longest Valid Obstacle Course at
Source: https://leetcode-py.wisl.dev/problems/find-the-longest-valid-obstacle-course-at-each-position
Tested Python solution for LeetCode 1964 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1964, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), Longest Increasing Subsequence. [View on LeetCode](https://leetcode.com/problems/find-the-longest-valid-obstacle-course-at-each-position/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1964 # by problem number
lcpy gen -s find_the_longest_valid_obstacle_course_at_each_position # by problem name
```
## Problem
You want to build some obstacle courses. You are given a \0-indexed\ integer array \obstacles\ of length \n\, where \obstacles\[i]\ describes the height of the \i\th\\ obstacle.
For every index \i\ between \0\ and \n - 1\ (\inclusive\), find the length of the \longest obstacle course\ in \obstacles\ such that:
\0\ and \i\ \inclusive\.\i\th\\ obstacle in the course.\obstacles\.\ans\ \of length\ \n\, \where\ \ans\[i]\ \is the length of the \longest obstacle course\ for index\ \i\\ as described above\.
### Examples
```
Input: obstacles = [1,2,3,2]
Output: [1,2,3,3]
Explanation: The longest valid obstacle course at each position is:
- i = 0: [1], [1] has length 1.
- i = 1: [1,2], [1,2] has length 2.
- i = 2: [1,2,3], [1,2,3] has length 3.
- i = 3: [1,2,3,2], [1,2,2] has length 3.
```
```
Input: obstacles = [2,2,1]
Output: [1,2,1]
Explanation: The longest valid obstacle course at each position is:
- i = 0: [2], [2] has length 1.
- i = 1: [2,2], [2,2] has length 2.
- i = 2: [2,2,1], [1] has length 1.
```
```
Input: obstacles = [3,1,5,6,4,2]
Output: [1,1,2,3,2,2]
Explanation: The longest valid obstacle course at each position is:
- i = 0: [3], [3] has length 1.
- i = 1: [3,1], [1] has length 1.
- i = 2: [3,1,5], [3,5] has length 2. [1,5] is also valid.
- i = 3: [3,1,5,6], [3,5,6] has length 3. [1,5,6] is also valid.
- i = 4: [3,1,5,6,4], [3,4] has length 2. [1,4] is also valid.
- i = 5: [3,1,5,6,4,2], [1,2] has length 2.
```
### Constraints
* n == obstacles.length
* 1 \<= n \<= 10^5
* 1 \<= obstacles\[i] \<= 10^7
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_longest_valid_obstacle_course_at_each_position/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_longest_valid_obstacle_course_at_each_position/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import bisect
class Solution:
# Time: O(n log n)
# Space: O(n)
def longest_obstacle_course(self, obstacles: list[int]) -> list[int]:
tails: list[int] = []
result: list[int] = []
for height in obstacles:
pos = bisect.bisect_right(tails, height)
if pos == len(tails):
tails.append(height)
else:
tails[pos] = height
result.append(pos + 1)
return result
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Maximum Sum of Node Values
Source: https://leetcode-py.wisl.dev/problems/find-the-maximum-sum-of-node-values
Tested Python solution for LeetCode 3068 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 3068, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Bit Manipulation](/catalog/topics/bit-manipulation), [Tree](/catalog/topics/tree), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/find-the-maximum-sum-of-node-values/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3068 # by problem number
lcpy gen -s find_the_maximum_sum_of_node_values # by problem name
```
## Problem
There exists an **undirected** tree with `n` nodes numbered `0` to `n - 1`. You are given a **0-indexed** 2D integer array `edges` of length `n - 1`, where `edges[i] = [u_i, v_i]` indicates that there is an edge between nodes `u_i` and `v_i` in the tree. You are also given a **positive** integer `k`, and a **0-indexed** array of **non-negative** integers `nums` of length `n`, where `nums[i]` represents the **value** of the node numbered `i`.
Alice wants the sum of values of tree nodes to be **maximum**, for which Alice can perform the following operation **any** number of times (**including zero**) on the tree:
* Choose any edge `[u, v]` connecting the nodes `u` and `v`, and update their values as follows:
* `nums[u] = nums[u] XOR k`
* `nums[v] = nums[v] XOR k`
Return the **maximum** possible **sum** of the **values** Alice can achieve by performing the operation **any** number of times.
### Examples

```
Input: nums = [1,2,1], k = 3, edges = [[0,1],[0,2]]
Output: 6
Explanation: Alice can achieve the maximum sum of 6 using a single operation:
- Choose the edge [0,2]. nums[0] and nums[2] become: 1 XOR 3 = 2, and the array nums becomes: [1,2,1] -> [2,2,2].
The total sum of values is 2 + 2 + 2 = 6.
It can be shown that 6 is the maximum achievable sum of values.
```

```
Input: nums = [2,3], k = 7, edges = [[0,1]]
Output: 9
Explanation: Alice can achieve the maximum sum of 9 using a single operation:
- Choose the edge [0,1]. nums[0] becomes: 2 XOR 7 = 5 and nums[1] become: 3 XOR 7 = 4, and the array nums becomes: [2,3] -> [5,4].
The total sum of values is 5 + 4 = 9.
It can be shown that 9 is the maximum achievable sum of values.
```

```
Input: nums = [7,7,7,7,7,7], k = 3, edges = [[0,1],[0,2],[0,3],[0,4],[0,5]]
Output: 42
Explanation: The maximum achievable sum is 42 which can be achieved by Alice performing no operations.
```
### Constraints
* `2 <= n == nums.length <= 2 * 10^4`
* `1 <= k <= 10^9`
* `0 <= nums[i] <= 10^9`
* `edges.length == n - 1`
* `edges[i].length == 2`
* `0 <= edges[i][0], edges[i][1] <= n - 1`
* The input is generated such that `edges` represent a valid tree.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_maximum_sum_of_node_values/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_maximum_sum_of_node_values/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def maximum_value_sum(self, nums: list[int], k: int, edges: list[list[int]]) -> int:
# A tree lets any even-sized set of nodes be XORed with k (each edge op
# toggles two endpoints; paths transfer a toggle and cancel out).
# So maximize the sum of gains (x ^ k) - x over an even count of nodes.
del edges
total = sum(nums)
gains = sorted(((x ^ k) - x for x in nums), reverse=True)
for i in range(0, len(gains) - 1, 2):
pair = gains[i] + gains[i + 1]
if pair <= 0:
break
total += pair
return total
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Minimum and Maximum Number of Nodes
Source: https://leetcode-py.wisl.dev/problems/find-the-minimum-and-maximum-number-of-nodes-between-critical-points
Tested Python solution for LeetCode 2058 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 2058, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/find-the-minimum-and-maximum-number-of-nodes-between-critical-points/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2058 # by problem number
lcpy gen -s find_the_minimum_and_maximum_number_of_nodes_between_critical_points # by problem name
```
## Problem
A **critical point** in a linked list is defined as **either** a **local maxima** or a **local minima**.
A node is a **local maxima** if the current node has a value **strictly greater** than the previous node and the next node.
A node is a **local minima** if the current node has a value **strictly smaller** than the previous node and the next node.
Note that a node can only be a local maxima/minima if there exists **both** a previous node and a next node.
Given a linked list `head`, return *an array of length 2 containing* `[minDistance, maxDistance]` *where* `minDistance` *is the* ***minimum distance*** *between* ***any two distinct*** *critical points and* `maxDistance` *is the* ***maximum distance*** *between* ***any two distinct*** *critical points. If there are* ***fewer*** *than two critical points, return* `[-1, -1]`.
### Examples

```
Input: head = [3,1]
Output: [-1,-1]
```

```
Input: head = [5,3,1,2,5,1,2]
Output: [1,3]
```

```
Input: head = [1,3,2,2,3,2,2,2,7]
Output: [3,3]
```
### Constraints
* The number of nodes in the list is in the range `[2, 10^5]`.
* `1 <= Node.val <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_minimum_and_maximum_number_of_nodes_between_critical_points/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_minimum_and_maximum_number_of_nodes_between_critical_points/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def nodes_between_critical_points(self, head: ListNode[int] | None) -> list[int]:
first = prev = 0
min_gap = 10**6
count = 0
pos = 1
if head is None or head.next is None or head.next.next is None:
return [-1, -1]
prev_val = head.val
curr = head.next
while curr.next is not None:
next_val = curr.next.val
if (curr.val > prev_val and curr.val > next_val) or (
curr.val < prev_val and curr.val < next_val
):
if count == 0:
first = pos
else:
min_gap = min(min_gap, pos - prev)
prev = pos
count += 1
prev_val = curr.val
curr = curr.next
pos += 1
if count < 2:
return [-1, -1]
return [min_gap, prev - first]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Power of K-Size Subarrays I
Source: https://leetcode-py.wisl.dev/problems/find-the-power-of-k-size-subarrays-i
Tested Python solution for LeetCode 3254 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 3254, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/find-the-power-of-k-size-subarrays-i/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3254 # by problem number
lcpy gen -s find_the_power_of_k_size_subarrays_i # by problem name
```
## Problem
You are given an array of integers `nums` of length `n` and a *positive* integer `k`.
The **power** of an array is defined as:
* Its **maximum** element if **all** of its elements are **consecutive** and **sorted** in **ascending** order.
* `-1` otherwise.
You need to find the **power** of all subarrays of `nums` of size `k`.
Return an integer array `results` of size `n - k + 1`, where `results[i]` is the power of `nums[i..(i + k - 1)]`.
### Examples
```
Input: nums = [1,2,3,4,3,2,5]
Output: [3,4,-1,-1,-1]
Explanation:
There are 5 subarrays of nums of size 3:
- [1, 2, 3] with the maximum element 3.
- [2, 3, 4] with the maximum element 4.
- [3, 4, 3] whose elements are not consecutive.
- [4, 3, 2] whose elements are not sorted.
- [3, 2, 5] whose elements are not consecutive.
```
```
Input: nums = [2,2,2,2,2]
Output: [-1,-1]
```
```
Input: nums = [3,2,3,2,3,2]
Output: [-1,3,-1,3,-1]
```
### Constraints
* `1 <= n == nums.length <= 500`
* `1 <= nums[i] <= 10^5`
* `1 <= k <= n`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_power_of_k_size_subarrays_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_power_of_k_size_subarrays_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) extra (output excluded)
def results_array(self, nums: list[int], k: int) -> list[int]:
# run[i] = length of the consecutive ascending run ending at index i
results: list[int] = []
run = 1
for i, num in enumerate(nums):
if i > 0 and num == nums[i - 1] + 1:
run += 1
else:
run = 1
if i >= k - 1:
results.append(num if run >= k else -1)
return results
```
## Complexity
| Time | Space |
| ---- | ---------------------------- |
| O(n) | O(1) extra (output excluded) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Punishment Number of an Integer
Source: https://leetcode-py.wisl.dev/problems/find-the-punishment-number-of-an-integer
Tested Python solution for LeetCode 2698 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 2698, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/find-the-punishment-number-of-an-integer/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2698 # by problem number
lcpy gen -s find_the_punishment_number_of_an_integer # by problem name
```
## Problem
Given a positive integer `n`, return *the **punishment number*** of `n`.
The **punishment number** of `n` is defined as the sum of the squares of all integers `i` such that:
* `1 <= i <= n`
* The decimal representation of `i * i` can be partitioned into contiguous substrings such that the sum of the integer values of these substrings equals `i`.
### Examples
```
Input: n = 10
Output: 182
Explanation: There are exactly 3 integers i in the range [1, 10] that satisfy the conditions in the statement:
- 1 since 1 * 1 = 1
- 9 since 9 * 9 = 81 and 81 can be partitioned into 8 and 1 with a sum equal to 8 + 1 == 9.
- 10 since 10 * 10 = 100 and 100 can be partitioned into 10 and 0 with a sum equal to 10 + 0 == 10.
Hence, the punishment number of 10 is 1 + 81 + 100 = 182
```
```
Input: n = 37
Output: 1478
Explanation: There are exactly 4 integers i in the range [1, 37] that satisfy the conditions in the statement:
- 1 since 1 * 1 = 1.
- 9 since 9 * 9 = 81 and 81 can be partitioned into 8 + 1.
- 10 since 10 * 10 = 100 and 100 can be partitioned into 10 + 0.
- 36 since 36 * 36 = 1296 and 1296 can be partitioned into 1 + 29 + 6.
Hence, the punishment number of 37 is 1 + 81 + 100 + 1296 = 1478
```
### Constraints
* 1 \<= n \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_punishment_number_of_an_integer/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_punishment_number_of_an_integer/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * d^2) where d is the digit count of i*i (partition search per i)
# Space: O(d) recursion depth
def punishment_number(self, n: int) -> int:
def can_partition(sq: str, target: int, idx: int = 0, cur: int = 0) -> bool:
if idx == len(sq):
return cur == target
for j in range(idx + 1, len(sq) + 1):
part = int(sq[idx:j])
if cur + part > target:
break
if can_partition(sq, target, j, cur + part):
return True
return False
total = 0
for i in range(1, n + 1):
if can_partition(str(i * i), i):
total += i * i
return total
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------------- | -------------------- |
| O(n \* d^2) where d is the digit count of i\*i (partition search per i) | O(d) recursion depth |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Safest Path in a Grid Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-the-safest-path-in-a-grid
Tested Python solution for LeetCode 2812 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2812, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/find-the-safest-path-in-a-grid/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2812 # by problem number
lcpy gen -s find_the_safest_path_in_a_grid # by problem name
```
## Problem
You are given a **0-indexed** 2D matrix `grid` of size `n x n`, where `(r, c)` represents:
* A cell containing a thief if `grid[r][c] = 1`
* An empty cell if `grid[r][c] = 0`
You are initially positioned at cell `(0, 0)`. In one move, you can move to any adjacent cell in the grid, including cells containing thieves.
The **safeness factor** of a path on the grid is defined as the **minimum** manhattan distance from any cell in the path to any thief in the grid.
Return *the **maximum safeness factor** of all paths leading to cell `(n - 1, n - 1)`*.
An **adjacent** cell of cell `(r, c)`, is one of the cells `(r, c + 1)`, `(r, c - 1)`, `(r + 1, c)` and `(r - 1, c)` if it exists.
The **Manhattan distance** between two cells `(a, b)` and `(x, y)` is equal to `|a - x| + |b - y|`, where `|val|` denotes the absolute value of val.
### Examples

```
Input: grid = [[1,0,0],[0,0,0],[0,0,1]]
Output: 0
Explanation: All paths from (0, 0) to (n - 1, n - 1) go through the thieves in cells (0, 0) and (n - 1, n - 1).
```

```
Input: grid = [[0,0,1],[0,0,0],[0,0,0]]
Output: 2
Explanation: The path depicted in the picture above has a safeness factor of 2 since:
- The closest cell of the path to the thief at cell (0, 2) is cell (0, 0). The distance between them is | 0 - 0 | + | 0 - 2 | = 2.
It can be shown that there are no other paths with a higher safeness factor.
```

```
Input: grid = [[0,0,0,1],[0,0,0,0],[0,0,0,0],[1,0,0,0]]
Output: 2
Explanation: The path depicted in the picture above has a safeness factor of 2 since:
- The closest cell of the path to the thief at cell (0, 3) is cell (1, 2). The distance between them is | 0 - 1 | + | 3 - 2 | = 2.
- The closest cell of the path to the thief at cell (3, 0) is cell (3, 2). The distance between them is | 3 - 3 | + | 0 - 2 | = 2.
It can be shown that there are no other paths with a higher safeness factor.
```
### Constraints
* `1 <= grid.length == n <= 400`
* `grid[i].length == n`
* `grid[i][j]` is either `0` or `1`.
* There is at least one thief in the `grid`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_safest_path_in_a_grid/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_safest_path_in_a_grid/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from heapq import heappop, heappush
class Solution:
# Time: O(n^2 log(n^2)) for the multi-source BFS plus the maximin search
# Space: O(n^2)
def maximum_safeness_factor(self, grid: list[list[int]]) -> int:
n = len(grid)
dist = self._thief_distances(grid, n)
best = [[-1] * n for _ in range(n)]
best[0][0] = dist[0][0]
heap: list[tuple[int, int, int]] = [(-dist[0][0], 0, 0)]
while heap:
neg, r, c = heappop(heap)
safe = -neg
if safe < best[r][c]:
continue
if r == n - 1 and c == n - 1:
return safe
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < n and 0 <= nc < n:
nxt = min(safe, dist[nr][nc])
if nxt > best[nr][nc]:
best[nr][nc] = nxt
heappush(heap, (-nxt, nr, nc))
return best[n - 1][n - 1]
def _thief_distances(self, grid: list[list[int]], n: int) -> list[list[int]]:
dist = [[-1] * n for _ in range(n)]
queue = deque((r, c) for r in range(n) for c in range(n) if grid[r][c] == 1)
for r, c in queue:
dist[r][c] = 0
while queue:
r, c = queue.popleft()
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < n and 0 <= nc < n and dist[nr][nc] < 0:
dist[nr][nc] = dist[r][c] + 1
queue.append((nr, nc))
return dist
```
## Complexity
| Time | Space |
| ---------------------------------------------------------------- | ------ |
| O(n^2 log(n^2)) for the multi-source BFS plus the maximin search | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Find the Shortest Superstring Python Solution
Source: https://leetcode-py.wisl.dev/problems/find-the-shortest-superstring
Tested Python solution for LeetCode 943 with 57 pytest cases. Generate a practice environment with lcpy.
LeetCode 943, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask), Hamiltonian Path. [View on LeetCode](https://leetcode.com/problems/find-the-shortest-superstring/description/).
Generate this problem as a practice environment: tested reference solution, 57 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 943 # by problem number
lcpy gen -s find_the_shortest_superstring # by problem name
```
## Problem
Given an array of strings `words`, return *the smallest string that contains each string in* `words` *as a substring*. If there are multiple valid strings of the smallest length, return **any of them**.
You may assume that no string in `words` is a substring of another string in `words`.
### Examples
```
Input: words = ["alex","loves","leetcode"]
Output: "alexlovesleetcode"
Explanation: All permutations of "alex","loves","leetcode" would also be accepted.
```
```
Input: words = ["catg","ctaagt","gcta","ttca","atgcatc"]
Output: "gctaagttcatgcatc"
```
### Constraints
* `1 <= words.length <= 12`
* `1 <= words[i].length <= 20`
* `words[i]` consists of lowercase English letters.
* All the strings of `words` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_shortest_superstring/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_shortest_superstring/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2 * 2^n) overlap precompute plus O(n^2 * 2^n) DP over masks
# Space: O(n * 2^n) for the parent-tracking DP table
def shortest_superstring(self, words: list[str]) -> str:
n = len(words)
if n == 1:
return words[0]
overlap = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
if i != j:
a, b = words[i], words[j]
for k in range(min(len(a), len(b)), 0, -1):
if a.endswith(b[:k]):
overlap[i][j] = k
break
size = 1 << n
dp = [[0] * n for _ in range(size)]
parent = [[-1] * n for _ in range(size)]
for mask in range(1, size):
for last in range(n):
if not mask >> last & 1:
continue
prev_mask = mask ^ (1 << last)
if prev_mask == 0:
dp[mask][last] = len(words[last])
continue
best_len = 10**9
best_prev = -1
for prev in range(n):
if prev_mask >> prev & 1:
cand = dp[prev_mask][prev] + len(words[last]) - overlap[prev][last]
if cand < best_len:
best_len = cand
best_prev = prev
dp[mask][last] = best_len
parent[mask][last] = best_prev
full = size - 1
last = min(range(n), key=lambda i: dp[full][i])
order: list[int] = []
mask = full
while last != -1:
order.append(last)
prev = parent[mask][last]
mask ^= 1 << last
last = prev
order.reverse()
result = words[order[0]]
for i in range(1, n):
result += words[order[i]][overlap[order[i - 1]][order[i]] :]
return result
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------- | -------------------------------------------- |
| O(n^2 \* 2^n) overlap precompute plus O(n^2 \* 2^n) DP over masks | O(n \* 2^n) for the parent-tracking DP table |
## Tags
# Find the Town Judge Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/find-the-town-judge
Tested Python solution for LeetCode 997 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 997, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/find-the-town-judge/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 997 # by problem number
lcpy gen -s find_the_town_judge # by problem name
```
## Problem
In a town, there are `n` people labeled from `1` to `n`. There is a rumor that one of these people is secretly the town judge.
If the town judge exists, then:
1. The town judge trusts nobody.
2. Everybody (except for the town judge) trusts the town judge.
3. There is exactly one person that satisfies properties 1 and 2.
You are given an array `trust` where `trust[i] = [ai, bi]` representing that the person labeled `ai` trusts the person labeled `bi`. If a trust relationship does not exist in `trust` array, then such a trust relationship does not exist.
Return *the label of the town judge if the town judge exists and can be identified, or return* `-1` *otherwise*.
### Examples
```
Input: n = 2, trust = [[1,2]]
Output: 2
```
```
Input: n = 3, trust = [[1,3],[2,3]]
Output: 3
```
```
Input: n = 3, trust = [[1,3],[2,3],[3,1]]
Output: -1
```
### Constraints
* 1 \<= n \<= 1000
* 0 \<= trust.length \<= 10^4
* `trust[i].length == 2`
* All the pairs of `trust` are **unique**.
* `ai != bi`
* 1 \<= ai, bi \<= n
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_town_judge/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/find_the_town_judge/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + t) where t = len(trust)
# Space: O(n)
def find_judge(self, n: int, trust: list[list[int]]) -> int:
# Net trust score: indegree - outdegree. Judge must reach n - 1.
trust_score = [0] * (n + 1)
for truster, trusted in trust:
trust_score[truster] -= 1
trust_score[trusted] += 1
for person in range(1, n + 1):
if trust_score[person] == n - 1:
return person
return -1
```
## Complexity
| Time | Space |
| ----------------------------- | ----- |
| O(n + t) where t = len(trust) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find the Winner of the Circular Game
Source: https://leetcode-py.wisl.dev/problems/find-the-winner-of-the-circular-game
Tested Python solution for LeetCode 1823 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1823, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Recursion](/catalog/topics/recursion), [Queue](/catalog/topics/queue), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/find-the-winner-of-the-circular-game/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1823 # by problem number
lcpy gen -s find_the_winner_of_the_circular_game # by problem name
```
## Problem
\There are \n\ friends that are playing a game. The friends are sitting in a circle and are numbered from \1\ to \n\ in \clockwise order\. More formally, moving clockwise from the \i\th\\ friend brings you to the \(i+1)\th\\ friend for \1 \<= i \< n\, and moving clockwise from the \n\th\\ friend brings you to the \1\st\\ friend.\
The rules of the game are as follows:\
\1\st\\ friend.\k\ friends in the clockwise direction \including\ the friend you started at. The counting wraps around the circle and may count some friends more than once.\2\ \starting\ from the friend \immediately clockwise\ of the friend who just lost and repeat.\Given the number of friends, \n\, and an integer \k\, return \the winner of the game\.\
m x n\ binary matrix \matrix\.
You can choose any number of columns in the matrix and flip every cell in that column (i.e., Change the value of the cell from \0\ to \1\ or vice versa).
Return \the maximum number of rows that have all values equal after some number of flips\.
### Examples
```
Input: matrix = [[0,1],[1,1]]
Output: 1
Explanation: After flipping no values, 1 row has all values equal.
```
```
Input: matrix = [[0,1],[1,0]]
Output: 2
Explanation: After flipping values in the first column, both rows have equal values.
```
```
Input: matrix = [[0,0,0],[0,0,1],[1,1,0]]
Output: 2
Explanation: After flipping values in the first two columns, the last two rows have equal values.
```
### Constraints
* \m == matrix.length\
* \n == matrix\[i].length\
* \1 \<= m, n \<= 300\
* \matrix\[i]\[j]\ is either \0\ or \1\.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/flip_columns_for_maximum_number_of_equal_rows/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/flip_columns_for_maximum_number_of_equal_rows/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def max_equal_rows_after_flips(self, matrix: list[list[int]]) -> int:
counts: dict[tuple[int, ...], int] = {}
for row in matrix:
key = tuple(row) if row[0] == 0 else tuple(1 - x for x in row)
counts[key] = counts.get(key, 0) + 1
return max(counts.values())
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Flip Equivalent Binary Trees Python Solution
Source: https://leetcode-py.wisl.dev/problems/flip-equivalent-binary-trees
Tested Python solution for LeetCode 951 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 951, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/flip-equivalent-binary-trees/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 951 # by problem number
lcpy gen -s flip_equivalent_binary_trees # by problem name
```
## Problem
\For a binary tree \T\, we can define a \flip operation\ as follows: choose any node, and swap the left and right child subtrees.\
\A binary tree \X\ is \flip equivalent\ to a binary tree \Y\ if and only if we can make \X\ equal to \Y\ after some number of flip operations.\
\Given the roots of two binary trees \root1\ and \root2\, return \true\ if the two trees are flip equivalent or \false\ otherwise.\
\[0, 100]\.\\[0, 99]\.\A binary string is monotone increasing if it consists of some number of \0\'s (possibly none), followed by some number of \1\'s (also possibly none).\
You are given a binary string \s\. You can flip \s\[i]\ changing it from \0\ to \1\ or from \1\ to \0\.\
Return \the minimum number of flips to make \\s\\ monotone increasing\.\
There are \n\ persons on a social media website. You are given an integer array \ages\ where \ages\[i]\ is the age of the \i\th\\ person.\
A Person \x\ will not send a friend request to a person \y\ (\x != y\) if any of the following conditions is true:\
age\[y] \<= 0.5 \* age\[x] + 7\\age\[y] > age\[x]\\age\[y] > 100 && age\[x] \< 100\\Otherwise, \x\ will send a friend request to \y\.\
Note that if \x\ sends a request to \y\, \y\ will not necessarily send a request to \x\. Also, a person will not send a friend request to themself.\
Return \the total number of friend requests made\.\
\\
### Examples ``` Input: ages = [16,16] Output: 2 Explanation: 2 people friend request each other. ``` ``` Input: ages = [16,17,18] Output: 2 Explanation: Friend requests are made 17 -> 16, 18 -> 17. ``` ``` Input: ages = [20,30,100,110,120] Output: 3 Explanation: Friend requests are made 110 -> 100, 120 -> 110, 120 -> 100. ``` ### Constraints * n == ages.length * 1 \<= n \<= 2 \* 10^4 * 1 \<= ages\[i] \<= 120 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/friends_of_appropriate_ages/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/friends_of_appropriate_ages/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n + 120^2) # Space: O(120) def num_friend_requests(self, ages: list[int]) -> int: count = [0] * 121 for age in ages: count[age] += 1 total = 0 for x in range(1, 121): if count[x] == 0: continue for y in range(1, 121): if count[y] == 0: continue if y <= 0.5 * x + 7 or y > x: continue total += count[x] * count[y] if x == y: total -= count[x] return total ``` ## Complexity | Time | Space | | ------------ | ------ | | O(n + 120^2) | O(120) | ## Tags # Frog Jump Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/frog-jump Tested Python solution for LeetCode 403 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 403, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/frog-jump/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 403 # by problem number lcpy gen -s frog_jump # by problem name ``` ## Problem A frog is crossing a river. The river is divided into some number of units, and at each unit, there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water. Given a list of `stones` positions (in units) in sorted **ascending order**, determine if the frog can cross the river by landing on the last stone. Initially, the frog is on the first stone and assumes the first jump must be `1` unit. If the frog's last jump was `k` units, its next jump must be either `k - 1`, `k`, or `k + 1` units. The frog can only jump in the forward direction. ### Examples ``` Input: stones = [0,1,3,5,6,8,12,17] Output: true ``` **Explanation:** The frog can jump to the last stone by jumping 1 unit to the 2nd stone, then 2 units to the 3rd stone, then 2 units to the 4th stone, then 3 units to the 6th stone, 4 units to the 7th stone, and 5 units to the 8th stone. ``` Input: stones = [0,1,2,3,4,8,9,11] Output: false ``` **Explanation:** There is no way to jump to the last stone as the gap between the 5th and 6th stone is too large. ### Constraints * `2 <= stones.length <= 2000` * `0 <= stones[i] <= 2^31 - 1` * `stones[0] == 0` * `stones` is sorted in a strictly increasing order. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/frog_jump/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/frog_jump/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n^2) def can_cross(self, stones: list[int]) -> bool: if stones[1] != 1: return False positions = set(stones) last = stones[-1] if last == 1: return True jumps: dict[int, set[int]] = {pos: set() for pos in stones} jumps[1].add(1) for pos in stones[1:]: for k in jumps[pos]: for step in (k - 1, k, k + 1): nxt = pos + step if step > 0 and nxt in positions: if nxt == last: return True jumps[nxt].add(step) return False ``` ## Complexity | Time | Space | | ------ | ------ | | O(n^2) | O(n^2) | ## Tags # Fruit Into Baskets Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/fruit-into-basket Tested Python solution for LeetCode 904 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 904, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/fruit-into-basket/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 904 # by problem number lcpy gen -s fruit_into_basket # by problem name ``` ## Problem You are visiting a farm that has a single row of fruit trees arranged from left to right. The trees are represented by an integer array \fruits\ where \fruits\[i]\ is the \type\ of fruit the \i\th\\ tree produces. You want to collect as much fruit as possible. However, the owner has some strict rules that you must follow:\
\fruits\, return \the \maximum\ number of fruits you can pick.\\grid\ of size \2 x n\, where \grid\[r]\[c]\ represents the number of points at position \(r, c)\ on the matrix. Two robots are playing a game on this matrix.
Both robots initially start at \(0, 0)\ and want to reach \(1, n-1)\. Each robot may only move to the \right\ (\(r, c)\ to \(r, c + 1)\) or \down\ (\(r, c)\ to \(r + 1, c)\).
At the start of the game, the \first\ robot moves from \(0, 0)\ to \(1, n-1)\, collecting all the points from the cells on its path. For all cells \(r, c)\ traversed on the path, \grid\[r]\[c]\ is set to \0\. Then, the \second\ robot moves from \(0, 0)\ to \(1, n-1)\, collecting the points on its path. Note that their paths may intersect with one another.
The \first\ robot wants to \minimize\ the number of points collected by the \second\ robot. In contrast, the \second\ robot wants to \maximize\ the number of points it collects. If both robots play \optimally\, return the \number of points\ collected by the \second\ robot.
### Examples

```
Input: grid = [[2,5,4],[1,5,1]]
Output: 4
Explanation: The optimal path taken by the first robot is shown in red, and the optimal path taken by the second robot is shown in blue.
The cells visited by the first robot are set to 0.
The second robot will collect 0 + 0 + 4 + 0 = 4 points.
```

```
Input: grid = [[3,3,1],[8,5,2]]
Output: 4
Explanation: The optimal path taken by the first robot is shown in red, and the optimal path taken by the second robot is shown in blue.
The cells visited by the first robot are set to 0.
The second robot will collect 0 + 3 + 1 + 0 = 4 points.
```

```
Input: grid = [[1,3,1,15],[1,3,3,1]]
Output: 7
Explanation: The optimal path taken by the first robot is shown in red, and the optimal path taken by the second robot is shown in blue.
The cells visited by the first robot are set to 0.
The second robot will collect 0 + 1 + 3 + 3 + 0 = 7 points.
```
### Constraints
* grid.length == 2
* n == grid\[r].length
* 1 \<= n \<= 5 \* 10^4
* 1 \<= grid\[r]\[c] \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/grid_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/grid_game/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def grid_game(self, grid: list[list[int]]) -> int:
top = sum(grid[0])
bottom = 0
best = None
for t, b in zip(grid[0], grid[1], strict=True):
top -= t
second = max(top, bottom)
if best is None or second < best:
best = second
bottom += b
return best if best is not None else 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Grid Illumination Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/grid-illumination
Tested Python solution for LeetCode 1001 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1001, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/grid-illumination/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1001 # by problem number
lcpy gen -s grid_illumination # by problem name
```
## Problem
There is a 2D grid of size n x n where each cell of this grid has a lamp that is initially **turned off**.
You are given a 2D array of lamp positions `lamps`, where `lamps[i] = [row_i, col_i]` indicates that the lamp at `grid[row_i][col_i]` is **turned on**. Even if the same lamp is listed more than once, it is turned on.
When a lamp is turned on, it **illuminates its cell** and **all other cells** in the same **row, column, or diagonal**.
You are also given another 2D array `queries`, where `queries[j] = [row_j, col_j]`. For the `jth` query, determine whether `grid[row_j][col_j]` is illuminated or not. After answering the `jth` query, **turn off** the lamp at `grid[row_j][col_j]` and its **8 adjacent lamps** if they exist. A lamp is adjacent if its cell shares either a side or corner with `grid[row_j][col_j]`.
Return *an array of integers* `ans`,\* where `ans[j]` should be `1` if the cell in the `jth` query was illuminated, or `0` if the lamp was not.
### Examples

```
Input: n = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,0]]
Output: [1,0]
Explanation: We have the initial grid with all lamps turned off. In the above picture we see the grid after turning on the lamp at grid[0][0] then turning on the lamp at grid[4][4].
The 0th query asks if the lamp at grid[1][1] is illuminated or not (the blue square). It is illuminated, so set ans[0] = 1. Then, we turn off all lamps in the red square.
```
```
Input: n = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,1]]
Output: [1,1]
```
```
Input: n = 5, lamps = [[0,0],[0,4]], queries = [[0,4],[0,1],[1,4]]
Output: [1,1,0]
```
### Constraints
* 1 \<= n \<= 10^9
* 0 \<= lamps.length \<= 20000
* 0 \<= queries.length \<= 20000
* lamps\[i].length == 2
* 0 \<= row\_i, col\_i \< n
* queries\[j].length == 2
* 0 \<= row\_j, col\_j \< n
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/grid_illumination/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/grid_illumination/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(L + Q) where L = len(lamps), Q = len(queries) (9 turns per query)
# Space: O(L)
def grid_illumination(
self, n: int, lamps: list[list[int]], queries: list[list[int]]
) -> list[int]:
lit: set[tuple[int, int]] = set()
for r, c in lamps:
lit.add((r, c))
rows: dict[int, int] = {}
cols: dict[int, int] = {}
diag: dict[int, int] = {}
anti: dict[int, int] = {}
for r, c in lit:
rows[r] = rows.get(r, 0) + 1
cols[c] = cols.get(c, 0) + 1
diag[r - c] = diag.get(r - c, 0) + 1
anti[r + c] = anti.get(r + c, 0) + 1
result: list[int] = []
for r, c in queries:
is_lit = (
rows.get(r, 0) > 0
or cols.get(c, 0) > 0
or diag.get(r - c, 0) > 0
or anti.get(r + c, 0) > 0
)
result.append(1 if is_lit else 0)
for dr in (-1, 0, 1):
for dc in (-1, 0, 1):
lamp = (r + dr, c + dc)
if lamp in lit:
lit.remove(lamp)
rows[lamp[0]] -= 1
cols[lamp[1]] -= 1
diag[lamp[0] - lamp[1]] -= 1
anti[lamp[0] + lamp[1]] -= 1
return result
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------- | ----- |
| O(L + Q) where L = len(lamps), Q = len(queries) (9 turns per query) | O(L) |
## Tags
# Group Anagrams Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/group-anagrams
Tested Python solution for LeetCode 49 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 49, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/group-anagrams/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 49 # by problem number
lcpy gen -s group_anagrams # by problem name
```
## Problem
Given an array of strings `strs`, group the anagrams together. You can return the answer in **any order**.
An **anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
### Examples
```
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
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.
```
```
Input: strs = [""]
Output: [[""]]
```
```
Input: strs = ["a"]
Output: [["a"]]
```
### Constraints
* `1 <= strs.length <= 10^4`
* `0 <= strs[i].length <= 100`
* `strs[i]` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/group_anagrams/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/group_anagrams/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * k) - when k > 26 use counting O(k), when k ≤ 26 use sorting O(k log k)
# Space: O(n * k)
def group_anagrams(self, strs: list[str]) -> list[list[str]]:
groups: dict[str | tuple[int, ...], list[str]] = {}
for s in strs:
if len(s) >= 26:
# Use counting for short strings (better time)
# Time: O(k) - single pass through string + O(26) for tuple
# Space: O(26) = O(1) per key
count = [0] * 26
for c in s:
count[ord(c) - ord("a")] += 1
key: tuple[int, ...] | str = tuple(count)
else:
# Use sorting for long strings (better space)
# Time: O(k log k) - sorting dominates
# Space: O(k) per key
key: tuple[int, ...] | str = "".join(sorted(s))
groups.setdefault(key, []).append(s)
return list(groups.values())
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------------------- | --------- |
| O(n \* k) - when k > 26 use counting O(k), when k ≤ 26 use sorting O(k log k) | O(n \* k) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Group Shifted Strings Python Solution
Source: https://leetcode-py.wisl.dev/problems/group-shifted-strings
Tested Python solution for LeetCode 249 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 249, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/group-shifted-strings/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 249 # by problem number
lcpy gen -s group_shifted_strings # by problem name
```
## Problem
Perform the following shift operations on a string:
* **Right shift**: Replace every letter with the **successive** letter of the English alphabet, where `'z'` is replaced by `'a'`. For example, `"abc"` can be right-shifted to `"bcd"` or `"xyz"` can be right-shifted to `"yza"`.
* **Left shift**: Replace every letter with the **preceding** letter of the English alphabet, where `'a'` is replaced by `'z'`. For example, `"bcd"` can be left-shifted to `"abc"` or `"yza"` can be left-shifted to `"xyz"`.
We can keep shifting the string in both directions to form an **endless** **shifting sequence**.
* For example, shift `"abc"` to form the sequence: `... <-> "abc" <-> "bcd" <-> ... <-> "xyz" <-> "yza" <-> ...` `<-> "zab" <-> "abc" <-> ...`.
You are given an array of strings `strings`, group together all `strings[i]` that belong to the same shifting sequence. You may return the answer in **any order**.
### Examples
```
Input: strings = ["abc","bcd","acef","xyz","az","ba","a","z"]
Output: [["acef"],["a","z"],["abc","bcd","xyz"],["az","ba"]]
```
```
Input: strings = ["a"]
Output: [["a"]]
```
### Constraints
* `1 <= strings.length <= 200`
* `1 <= strings[i].length <= 50`
* `strings[i]` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/group_shifted_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/group_shifted_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
class Solution:
# Time: O(L) where L is total length of all strings
# Space: O(L)
def group_strings(self, strings: list[str]) -> list[list[str]]:
groups: defaultdict[tuple[int, ...], list[str]] = defaultdict(list)
for s in strings:
shift = ord(s[0]) - ord("a")
key = tuple((ord(c) - ord("a") - shift) % 26 for c in s)
groups[key].append(s)
return list(groups.values())
```
## Complexity
| Time | Space |
| ------------------------------------------- | ----- |
| O(L) where L is total length of all strings | O(L) |
## Tags
[NeetCode All](/catalog/neetcode).
# Groups of Special-Equivalent Strings
Source: https://leetcode-py.wisl.dev/problems/groups-of-special-equivalent-strings
Tested Python solution for LeetCode 893 with 25 pytest cases. Generate a practice environment with lcpy.
LeetCode 893, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/groups-of-special-equivalent-strings/description/).
Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 893 # by problem number
lcpy gen -s groups_of_special_equivalent_strings # by problem name
```
## Problem
You are given an array of strings of the same length `words`.
In one **move**, you can swap any two even indexed characters or any two odd indexed characters of a string `words[i]`.
Two strings `words[i]` and `words[j]` are **special-equivalent** if after any number of moves, `words[i] == words[j]`.
* For example, `words[i] = "zzxy"` and `words[j] = "xyzz"` are **special-equivalent** because we may make the moves `"zzxy" -> "xzzy" -> "xyzz"`.
A **group of special-equivalent strings** from `words` is a non-empty subset of words such that:
* Every pair of strings in the group are special equivalent, and
* The group is the largest size possible (i.e., there is not a string `words[i]` not in the group such that `words[i]` is special-equivalent to every string in the group).
Return *the number of **groups of special-equivalent strings** from* `words`.
### Examples
```
Input: words = ["abcd","cdab","cbad","xyzz","zzxy","zzyx"]
Output: 3
Explanation:
One group is ["abcd", "cdab", "cbad"], since they are all pairwise special equivalent, and none of the other strings is all pairwise special equivalent to these.
The other two groups are ["xyzz", "zzxy"] and ["zzyx"].
Note that in particular, "zzxy" is not special equivalent to "zzyx".
```
```
Input: words = ["abc","acb","bac","bca","cab","cba"]
Output: 3
```
### Constraints
* 1 \<= words.length \<= 1000
* 1 \<= words\[i].length \<= 20
* words\[i] consist of lowercase English letters.
* All the strings are of the same length.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/groups_of_special_equivalent_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/groups_of_special_equivalent_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * l log l)
# Space: O(n * l)
def num_special_equivalent_groups(self, words: list[str]) -> int:
signatures = {("".join(sorted(word[0::2])), "".join(sorted(word[1::2]))) for word in words}
return len(signatures)
```
## Complexity
| Time | Space |
| --------------- | --------- |
| O(n \* l log l) | O(n \* l) |
## Tags
# Grumpy Bookstore Owner Python Solution
Source: https://leetcode-py.wisl.dev/problems/grumpy-bookstore-owner
Tested Python solution for LeetCode 1052 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1052, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/grumpy-bookstore-owner/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1052 # by problem number
lcpy gen -s grumpy_bookstore_owner # by problem name
```
## Problem
There is a bookstore owner that has a store open for \n\ minutes. You are given an integer array \customers\ of length \n\ where \customers\[i]\ is the number of the customers that enter the store at the start of the \i\th\\ minute and all those customers leave after the end of that minute.
During certain minutes, the bookstore owner is grumpy. You are given a binary array \grumpy\ where \grumpy\[i]\ is \1\ if the bookstore owner is grumpy during the \i\th\\ minute, and is \0\ otherwise.
When the bookstore owner is grumpy, the customers entering during that minute are not \satisfied\. Otherwise, they are satisfied.
The bookstore owner knows a secret technique to remain \not grumpy\ for \minutes\ consecutive minutes, but this technique can only be used \once\.
Return the \maximum\ number of customers that can be \satisfied\ throughout the day.
### Examples
```
Input: customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], minutes = 3
Output: 16
Explanation: The bookstore owner keeps themselves not grumpy for the last 3 minutes. The maximum number of customers that can be satisfied = 1 + 1 + 1 + 1 + 7 + 5 = 16.
```
```
Input: customers = [1], grumpy = [0], minutes = 1
Output: 1
```
### Constraints
* \n == customers.length == grumpy.length\
* \1 \<= minutes \<= n \<= 2 \* 10\4\\
* \0 \<= customers\[i] \<= 1000\
* \grumpy\[i]\ is either \0\ or \1\.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/grumpy_bookstore_owner/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/grumpy_bookstore_owner/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) sliding window
# Space: O(1)
def max_satisfied(self, customers: list[int], grumpy: list[int], minutes: int) -> int:
base = sum(c for c, g in zip(customers, grumpy, strict=True) if g == 0)
gain = sum(customers[i] * grumpy[i] for i in range(minutes))
best = gain
for i in range(minutes, len(customers)):
gain += customers[i] * grumpy[i] - customers[i - minutes] * grumpy[i - minutes]
best = max(best, gain)
return base + best
```
## Complexity
| Time | Space |
| ------------------- | ----- |
| O(n) sliding window | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Guess Number Higher or Lower Python Solution
Source: https://leetcode-py.wisl.dev/problems/guess-number-higher-or-lower
Tested Python solution for LeetCode 374 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 374, [Easy](/catalog/easy). Topics: [Binary Search](/catalog/topics/binary-search), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/guess-number-higher-or-lower/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 374 # by problem number
lcpy gen -s guess_number_higher_or_lower # by problem name
```
## Problem
We are playing the Guess Game. The game is as follows:
I pick a number from `1` to `n`. You have to guess which number I picked. Every time you guess wrong, I will tell you whether the number I picked is higher or lower than your guess.
You call a pre-defined API `int guess(int num)`, which returns three possible results:
* `-1`: Your guess is higher than the number I picked (i.e. `num > pick`).
* `1`: Your guess is lower than the number I picked (i.e. `num < pick`).
* `0`: your guess is equal to the number I picked (i.e. `num == pick`).
Return *the number that I picked*.
### Examples
```
Input: n = 10, pick = 6
Output: 6
```
```
Input: n = 1, pick = 1
Output: 1
```
```
Input: n = 2, pick = 1
Output: 1
```
### Constraints
* 1 \<= n \<= 2^31 - 1
* 1 \<= pick \<= n
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_number_higher_or_lower/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_number_higher_or_lower/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def guess(num: int) -> int:
# Predefined by LeetCode; injected by tests.
raise NotImplementedError
class Solution:
# Time: O(log n)
# Space: O(1)
def guess_number(self, n: int) -> int:
low = 1
high = n
while low <= high:
mid = low + (high - low) // 2
result = guess(mid)
if result == 0:
return mid
if result < 0:
high = mid - 1
else:
low = mid + 1
return -1
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Guess Number Higher or Lower II
Source: https://leetcode-py.wisl.dev/problems/guess-number-higher-or-lower-ii
Tested Python solution for LeetCode 375 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 375, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), Minimax, [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/guess-number-higher-or-lower-ii/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 375 # by problem number
lcpy gen -s guess_number_higher_or_lower_ii # by problem name
```
## Problem
We are playing the Guessing Game. The game will work as follows:
\1\ and \n\.\x\, you will pay \x\ dollars. If you run out of money, \you lose the game\.\n\, return \the minimum amount of money you need to \guarantee a win regardless of what number I pick\\.
### Examples

```
Input: n = 10
Output: 16
Explanation: The winning strategy is as follows:
- The range is [1,10]. Guess 7.
- If this is my number, your total is $0. Otherwise, you pay $7.
- If my number is higher, the range is [8,10]. Guess 9.
- If this is my number, your total is $7. Otherwise, you pay $9.
- If my number is higher, it must be 10. Guess 10. Your total is $7 + $9 = $16.
- If my number is lower, it must be 8. Guess 8. Your total is $7 + $9 = $16.
- If my number is lower, the range is [1,6]. Guess 3.
- If this is my number, your total is $7. Otherwise, you pay $3.
- If my number is higher, the range is [4,6]. Guess 5.
- If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $5.
- If my number is higher, it must be 6. Guess 6. Your total is $7 + $3 + $5 = $15.
- If my number is lower, it must be 4. Guess 4. Your total is $7 + $3 + $5 = $15.
- If my number is lower, the range is [1,2]. Guess 1.
- If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $1.
- If my number is higher, it must be 2. Guess 2. Your total is $7 + $3 + $1 = $11.
The worst case in all these scenarios is that you pay $16. Hence, you only need $16 to guarantee a win.
```
```
Input: n = 1
Output: 0
Explanation: There is only one possible number, so you can guess 1 and not have to pay anything.
```
```
Input: n = 2
Output: 1
Explanation: There are two possible numbers, 1 and 2.
- Guess 1.
- If this is my number, your total is $0. Otherwise, you pay $1.
- If my number is higher, it must be 2. Guess 2. Your total is $1.
The worst case is that you pay $1.
```
### Constraints
* 1 \<= n \<= 200
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_number_higher_or_lower_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_number_higher_or_lower_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^3)
# Space: O(n^2)
def get_money_amount(self, n: int) -> int:
# dp[lo][hi] = min worst-case cost to guarantee a win within [lo, hi].
dp = [[0] * (n + 2) for _ in range(n + 2)]
for length in range(2, n + 1):
for lo in range(1, n - length + 2):
hi = lo + length - 1
dp[lo][hi] = min(x + max(dp[lo][x - 1], dp[x + 1][hi]) for x in range(lo, hi))
return dp[1][n]
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^3) | O(n^2) |
## Tags
# Guess the Majority in a Hidden Array
Source: https://leetcode-py.wisl.dev/problems/guess-the-majority-in-a-hidden-array
Tested Python solution for LeetCode 1538 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 1538, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/guess-the-majority-in-a-hidden-array/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1538 # by problem number
lcpy gen -s guess_the_majority_in_a_hidden_array # by problem name
```
## Problem
We have an integer array `nums`, where all the integers in `nums` are **0** or **1**. You will not be given direct access to the array, instead, you will have an **API** `ArrayReader` which has the following functions:
* `int query(int a, int b, int c, int d)`: where `0 <= a < b < c < d < ArrayReader.length()`. The function returns the distribution of the value of the 4 elements:
* **4**: if the values of the 4 elements are the same (0 or 1).
* **2**: if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
* **0**: if two elements have a value equal to 0 and two elements have a value equal to 1.
* `int length()`: Returns the size of the array.
You are allowed to call `query()` **2 \* n times** at most where n is equal to `ArrayReader.length()`.
Return **any** index of the most frequent value in `nums`, in case of tie, return -1.
### Examples
```
Input: nums = [0,0,1,0,1,1,1,1]
Output: 5
Explanation: The following calls to the API
reader.length() // returns 8 because there are 8 elements in the hidden array.
reader.query(0,1,2,3) // returns 2 this is a query that compares the elements nums[0], nums[1], nums[2], nums[3]
// Three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
reader.query(4,5,6,7) // returns 4 because nums[4], nums[5], nums[6], nums[7] have the same value.
We can infer that the most frequent value is found in the last 4 elements.
Index 2, 4, 6, 7 is also a correct answer.
```
```
Input: nums = [0,0,1,1,0]
Output: 0
```
```
Input: nums = [1,0,1,0,1,0,1,0]
Output: -1
```
### Constraints
* `5 <= nums.length <= 10^5`
* `0 <= nums[i] <= 1`
**Follow up:** What is the minimum number of calls needed to find the majority element?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_the_majority_in_a_hidden_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_the_majority_in_a_hidden_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class ArrayReader:
# Test-harness API: backs the query/length interface with the hidden array
def __init__(self, nums: list[int]) -> None:
self.nums = nums
def query(self, a: int, b: int, c: int, d: int) -> int:
total = sum(self.nums[i] for i in (a, b, c, d))
return 4 if total in (0, 4) else 2 if total in (1, 3) else 0
def length(self) -> int:
return len(self.nums)
class Solution:
# Time: O(n) with n queries, well under the 2 * n budget
# Space: O(1)
def guess_majority(self, reader: ArrayReader) -> int:
# query(0, 1, 2, i) returns the same value as query(0, 1, 2, 3) exactly
# when nums[i] == nums[3], so indices 4..n-1 split by equality with
# nums[3]; the count starts at 1 for index 3 itself.
n = reader.length()
base = reader.query(0, 1, 2, 3)
same, diff, k = 1, 0, 0
for i in range(4, n):
if reader.query(0, 1, 2, i) == base:
same += 1
else:
diff += 1
k = i
# Classify indices 0, 1, 2 against nums[3] using index 4 as the pivot:
# swapping index 0 into query(1, 2, 4) preserves the result exactly
# when nums[0] == nums[3], and likewise for indices 1 and 2.
pivot = reader.query(0, 1, 2, 4)
for value, idx in (
(reader.query(1, 2, 3, 4), 0),
(reader.query(0, 2, 3, 4), 1),
(reader.query(0, 1, 3, 4), 2),
):
if value == pivot:
same += 1
else:
diff += 1
k = idx
if same == diff:
return -1
return 3 if same > diff else k
```
## Complexity
| Time | Space |
| ------------------------------------------------- | ----- |
| O(n) with n queries, well under the 2 \* n budget | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Guess the Word Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/guess-the-word
Tested Python solution for LeetCode 843 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 843, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [String](/catalog/topics/string), Minimax, [Interactive](/catalog/topics/interactive), [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/guess-the-word/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 843 # by problem number
lcpy gen -s guess_the_word # by problem name
```
## Problem
You are given an array of unique strings `words` where `words[i]` is six letters long. One word of `words` was chosen as a secret word.
You are also given the helper object `Master`. You may call `Master.guess(word)` where `word` is a six-letter-long string, and it must be from `words`. `Master.guess(word)` returns:
* `-1` if `word` is not from `words`, or
* an integer representing the number of exact matches (value and position) of your guess to the secret word.
There is a parameter `allowedGuesses` for each test case where `allowedGuesses` is the maximum number of times you can call `Master.guess(word)`.
For each test case, you should call `Master.guess` with the secret word without exceeding the maximum number of allowed guesses. You will get:
* `"Either you took too many guesses, or you did not find the secret word."` if you called `Master.guess` more than `allowedGuesses` times or if you did not call `Master.guess` with the secret word, or
* `"You guessed the secret word correctly."` if you called `Master.guess` with the secret word with the number of calls to `Master.guess` less than or equal to `allowedGuesses`.
The test cases are generated such that you can guess the secret word with a reasonable strategy (other than using the bruteforce method).
### Examples
```
Input: secret = "acckzz", words = ["acckzz","ccbazz","eiowzz","abcczz"], allowedGuesses = 10
Output: You guessed the secret word correctly.
Explanation:
master.guess("aaaaaa") returns -1, because "aaaaaa" is not in words.
master.guess("acckzz") returns 6, because "acckzz" is secret and has all 6 matches.
master.guess("ccbazz") returns 3, because "ccbazz" has 3 matches.
master.guess("eiowzz") returns 2, because "eiowzz" has 2 matches.
master.guess("abcczz") returns 4, because "abcczz" has 4 matches.
We made 5 calls to master.guess, and one of them was the secret, so we pass the test case.
```
```
Input: secret = "hamada", words = ["hamada","khaled"], allowedGuesses = 10
Output: You guessed the secret word correctly.
Explanation: Since there are two words, you can guess both.
```
### Constraints
* `1 <= words.length <= 100`
* `words[i].length == 6`
* `words[i]` consist of lowercase English letters.
* All the strings of `words` are **unique**.
* `secret` exists in `words`.
* `10 <= allowedGuesses <= 30`
**Follow up:** What is the minimum number of guesses needed to guarantee finding the secret word?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_the_word/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/guess_the_word/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
def match_count(a: str, b: str) -> int:
return sum(x == y for x, y in zip(a, b, strict=True))
class Master:
# Test-harness API: backs the guess interface with the hidden secret word
def __init__(self, secret: str, words: list[str], allowed_guesses: int) -> None:
self.secret = secret
self.wordset = set(words)
self.allowed_guesses = allowed_guesses
self.calls = 0
self.found = False
def guess(self, word: str) -> int:
self.calls += 1
if word not in self.wordset:
return -1
matches = sum(a == b for a, b in zip(word, self.secret, strict=True))
if matches == len(self.secret):
self.found = True
return matches
def outcome(self) -> bool:
return self.found and self.calls <= self.allowed_guesses
class Solution:
# Time: O(g * n^2) for n candidates over g guesses
# Space: O(n)
def find_secret_word(self, words: list[str], master: Master) -> None:
candidates = list(words)
while len(candidates) > 1:
guess = min(candidates, key=lambda w: self._worst_bucket(w, candidates))
matches = master.guess(guess)
candidates = [w for w in candidates if match_count(w, guess) == matches]
if candidates:
master.guess(candidates[0])
def _worst_bucket(self, word: str, candidates: list[str]) -> int:
counts = Counter(match_count(c, word) for c in candidates)
return max(counts.values())
```
## Complexity
| Time | Space |
| ------------------------------------------- | ----- |
| O(g \* n^2) for n candidates over g guesses | O(n) |
## Tags
# H-Index Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/h-index
Tested Python solution for LeetCode 274 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 274, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting), Counting Sort. [View on LeetCode](https://leetcode.com/problems/h-index/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 274 # by problem number
lcpy gen -s h_index # by problem name
```
## Problem
Given an array of integers `citations` where `citations[i]` is the number of citations a researcher received for their `ith` paper, return *the researcher's h-index*.
According to the [definition of h-index on Wikipedia](https://en.wikipedia.org/wiki/H-index): The h-index is defined as the maximum value of `h` such that the given researcher has published at least `h` papers that have each been cited at least `h` times.
### Examples
```
Input: citations = [3,0,6,1,5]
Output: 3
Explanation: [3,0,6,1,5] means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, their h-index is 3.
```
```
Input: citations = [1,3,1]
Output: 1
```
### Constraints
* n == citations.length
* 1 \<= n \<= 5000
* 0 \<= citations\[i] \<= 1000
**Follow up:** Could you solve it in `O(n)` time and `O(n)` extra space? What about an `O(log n)`-time solution after sorting, or `O(n)` time with `O(1)` space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/h_index/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/h_index/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def h_index(self, citations: list[int]) -> int:
n = len(citations)
buckets = [0] * (n + 1)
for c in citations:
buckets[min(c, n)] += 1
total = 0
for h in range(n, -1, -1):
total += buckets[h]
if total >= h:
return h
return 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# H-Index II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/h-index-ii
Tested Python solution for LeetCode 275 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 275, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/h-index-ii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 275 # by problem number
lcpy gen -s h_index_ii # by problem name
```
## Problem
Given an array of integers `citations` where `citations[i]` is the number of citations a researcher received for their `ith` paper and `citations` is sorted in **non-descending order**, return *the researcher's h-index*.
According to the [definition of h-index on Wikipedia](https://en.wikipedia.org/wiki/H-index): The h-index is defined as the maximum value of `h` such that the given researcher has published at least `h` papers that have each been cited at least `h` times.
You must write an algorithm that runs in logarithmic time.
### Examples
```
Input: citations = [0,1,3,5,6]
Output: 3
```
**Explanation:** \[0,1,3,5,6] means the researcher has 5 papers in total and each of them had received 0, 1, 3, 5, 6 citations respectively.
Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, their h-index is 3.
```
Input: citations = [1,2,100]
Output: 2
```
### Constraints
* n == citations.length
* 1 \<= n \<= 10^5
* 0 \<= citations\[i] \<= 1000
* citations is sorted in ascending order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/h_index_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/h_index_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def h_index(self, citations: list[int]) -> int:
n = len(citations)
lo, hi = 0, n - 1
while lo <= hi:
mid = (lo + hi) // 2
if citations[mid] >= n - mid:
hi = mid - 1
else:
lo = mid + 1
return n - lo
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
# Hamming Distance Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/hamming-distance
Tested Python solution for LeetCode 461 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 461, [Easy](/catalog/easy). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/hamming-distance/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 461 # by problem number
lcpy gen -s hamming_distance # by problem name
```
## Problem
The \Hamming distance\ between two integers is the number of positions at which the corresponding bits are different.
Given two integers \x\ and \y\, return \the \Hamming distance\ between them\.
### Examples
```
Input: x = 1, y = 4
Output: 2
Explanation:
1 (0 0 0 1)
4 (0 1 0 0)
↑ ↑
The above arrows point to positions where the corresponding bits are different.
```
```
Input: x = 3, y = 1
Output: 1
```
### Constraints
* 0 \<= x, y \<= 2^31 - 1
**Note:** This question is the same as [2220: Minimum Bit Flips to Convert Number](https://leetcode.com/problems/minimum-bit-flips-to-convert-number/description/).
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/hamming_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/hamming_distance/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(b), b = number of differing bits (<= 31)
# Space: O(1)
def hamming_distance(self, x: int, y: int) -> int:
return (x ^ y).bit_count()
```
## Complexity
| Time | Space |
| ------------------------------------------- | ----- |
| O(b), b = number of differing bits (\<= 31) | O(1) |
## Tags
# Hand of Straights Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/hand-of-straights
Tested Python solution for LeetCode 846 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 846, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/hand-of-straights/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 846 # by problem number
lcpy gen -s hand_of_straights # by problem name
```
## Problem
Alice has some number of cards and she wants to rearrange the cards into groups so that each group is of size `groupSize`, and consists of `groupSize` consecutive cards.
Given an integer array `hand` where `hand[i]` is the value written on the `ith` card and an integer `groupSize`, return `true` if she can rearrange the cards, or `false` otherwise.
### Examples
```
Input: hand = [1,2,3,6,2,3,4,7,8], groupSize = 3
Output: true
Explanation: Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8]
```
```
Input: hand = [1,2,3,4,5], groupSize = 4
Output: false
Explanation: Alice's hand can not be rearranged into groups of 4.
```
### Constraints
* 1 \<= hand.length \<= 10\4\
* 0 \<= hand\[i] \<= 10\9\
* 1 \<= groupSize \<= hand.length
**Note:** This question is the same as 1296: [https://leetcode.com/problems/divide-array-in-sets-of-k-consecutive-numbers/](https://leetcode.com/problems/divide-array-in-sets-of-k-consecutive-numbers/)
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/hand_of_straights/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/hand_of_straights/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n log n)
# Space: O(n)
def is_n_straight_hand(self, hand: list[int], group_size: int) -> bool:
if len(hand) % group_size != 0:
return False
count: Counter[int] = Counter(hand)
for card in sorted(count):
if count[card] == 0:
continue
frequency = count[card]
# Greedily form `frequency` groups starting at `card`
for offset in range(group_size):
next_card = card + offset
if count[next_card] < frequency:
return False
count[next_card] -= frequency
return True
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Handshakes That Don't Cross Python Solution
Source: https://leetcode-py.wisl.dev/problems/handshakes-that-dont-cross
Tested Python solution for LeetCode 1259 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1259, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/handshakes-that-dont-cross/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1259 # by problem number
lcpy gen -s handshakes_that_dont_cross # by problem name
```
## Problem
You are given an **even** number of people `numPeople` that stand around a circle and each person shakes hands with someone else so that there are `numPeople / 2` handshakes total.
Return *the number of ways these handshakes could occur such that none of the handshakes cross*.
Since the answer could be very large, return it **modulo** `109 + 7`.
### Examples

```
Input: numPeople = 4
Output: 2
```
**Explanation:** There are two ways to do it, the first way is \[(1,2),(3,4)] and the second one is \[(2,3),(4,1)].

```
Input: numPeople = 6
Output: 5
```
### Constraints
* `2 <= numPeople <= 1000`
* `numPeople` is even.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/handshakes_that_dont_cross/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/handshakes_that_dont_cross/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def number_of_ways(self, num_people: int) -> int:
mod = 10**9 + 7
dp = [0] * (num_people + 1)
dp[0] = 1
for people in range(2, num_people + 1, 2):
total = 0
for left in range(0, people, 2):
total += dp[left] * dp[people - left - 2]
dp[people] = total % mod
return dp[num_people]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Happy Number Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/happy-number
Tested Python solution for LeetCode 202 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 202, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/happy-number/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 202 # by problem number
lcpy gen -s happy_number # by problem name
```
## Problem
Write an algorithm to determine if a number `n` is happy.
A **happy number** is a number defined by the following process:
* Starting with any positive integer, replace the number by the sum of the squares of its digits.
* Repeat the process until the number equals 1 (where it will stay), or it **loops endlessly in a cycle** which does not include 1.
* Those numbers for which this process **ends in 1** are happy.
Return `true` *if* `n` *is a happy number, and* `false` *if not*.
### Examples
```
Input: n = 19
Output: true
```
**Explanation:**
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
```
Input: n = 2
Output: false
```
### Constraints
* 1 \<= n \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/happy_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/happy_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(log n)
def is_happy(self, n: int) -> bool:
def digit_square_sum(num: int) -> int:
total = 0
while num:
digit = num % 10
total += digit * digit
num //= 10
return total
slow, fast = n, digit_square_sum(n)
while fast != 1 and slow != fast:
slow = digit_square_sum(slow)
fast = digit_square_sum(digit_square_sum(fast))
return fast == 1
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(log n) | O(log n) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Heaters Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/heaters
Tested Python solution for LeetCode 475 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 475, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/heaters/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 475 # by problem number
lcpy gen -s heaters # by problem name
```
## Problem
Winter is coming! During the contest, your first job is to design a standard heater with a fixed warm radius to warm all the houses.
Every house can be warmed, as long as the house is within the heater's warm radius range.
Given the positions of `houses` and `heaters` on a horizontal line, return *the minimum radius standard of heaters so that those heaters could cover all houses.*
**Notice** that all the `heaters` follow your radius standard, and the warm radius will be the same.
### Examples
```
Input: houses = [1,2,3], heaters = [2]
Output: 1
Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed.
```
```
Input: houses = [1,2,3,4], heaters = [1,4]
Output: 1
Explanation: The two heaters were placed at positions 1 and 4. We need to use a radius 1 standard, then all the houses can be warmed.
```
```
Input: houses = [1,5], heaters = [2]
Output: 3
```
### Constraints
* `1 <= houses.length, heaters.length <= 3 * 10^4`
* `1 <= houses[i], heaters[i] <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/heaters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/heaters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import bisect
class Solution:
# Time: O(n log n + m log m) for the sorts, then O(m log n) lookups
# Space: O(1) extra beyond the in-place sorts
def find_radius(self, houses: list[int], heaters: list[int]) -> int:
houses.sort()
heaters.sort()
radius = 0
for house in houses:
i = bisect.bisect_left(heaters, house)
dists: list[int] = []
if i > 0:
dists.append(house - heaters[i - 1])
if i < len(heaters):
dists.append(heaters[i] - house)
radius = max(radius, min(dists))
return radius
```
## Complexity
| Time | Space |
| ----------------------------------------------------------- | ------------------------------------ |
| O(n log n + m log m) for the sorts, then O(m log n) lookups | O(1) extra beyond the in-place sorts |
## Tags
# Height Checker Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/height-checker
Tested Python solution for LeetCode 1051 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1051, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting), Counting Sort. [View on LeetCode](https://leetcode.com/problems/height-checker/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1051 # by problem number
lcpy gen -s height_checker # by problem name
```
## Problem
A school is trying to take an annual photo of all the students. The students are asked to stand in a single file line in **non-decreasing order** by height. Let this ordering be represented by the integer array `expected` where `expected[i]` is the expected height of the `ith` student in line.
You are given an integer array `heights` representing the current order that the students are standing in. Each `heights[i]` is the height of the `ith` student in line (0-indexed).
Return *the number of indices where* `heights[i] != expected[i]`.
### Examples
```
Input: heights = [1,1,4,2,1,3]
Output: 3
Explanation:
heights: [1,1,4,2,1,3]
expected: [1,1,1,2,3,4]
Indices 2, 4, and 5 do not match.
```
```
Input: heights = [5,1,2,3,4]
Output: 5
Explanation:
heights: [5,1,2,3,4]
expected: [1,2,3,4,5]
All indices do not match.
```
```
Input: heights = [1,2,3,4,5]
Output: 0
Explanation:
heights: [1,2,3,4,5]
expected: [1,2,3,4,5]
All indices match.
```
### Constraints
* `1 <= heights.length <= 100`
* `1 <= heights[i] <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/height_checker/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/height_checker/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def height_checker(self, heights: list[int]) -> int:
expected = sorted(heights)
return sum(a != b for a, b in zip(heights, expected, strict=True))
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# High Five Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/high-five
Tested Python solution for LeetCode 1086 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 1086, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/high-five/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1086 # by problem number
lcpy gen -s high_five # by problem name
```
## Problem
Given a list of the scores of different students, `items`, where `items[i] = [IDi, scorei]` represents one score from a student with `IDi`, calculate each student's top five average.
Return the answer as an array of pairs `result`, where `result[j] = [IDj, topFiveAveragej]` represents the student with `IDj` and their top five average. Sort `result` by `IDj` in increasing order.
A student's `top five average` is calculated by taking the sum of their top five scores and dividing it by `5` using integer division.
### Examples
```
Input: items = [[1,91],[1,92],[2,93],[2,97],[1,60],[2,77],[1,65],[1,87],[1,100],[2,100],[2,76]]
Output: [[1,87],[2,88]]
Explanation:
The student with ID = 1 got scores 91, 92, 60, 65, 87, and 100. Their top five average is (100 + 92 + 91 + 87 + 65) / 5 = 87.
The student with ID = 2 got scores 93, 97, 77, 100, and 76. Their top five average is (100 + 97 + 93 + 77 + 76) / 5 = 88.6, but with integer division their average converts to 88.
```
```
Input: items = [[1,100],[7,100],[1,100],[7,100],[1,100],[7,100],[1,100],[7,100],[1,100],[7,100]]
Output: [[1,100],[7,100]]
```
### Constraints
* 1 \<= items.length \<= 1000
* items\[i].length == 2
* 1 \<= IDi \<= 1000
* 0 \<= scorei \<= 100
* For each IDi, there will be at least five scores.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/high_five/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/high_five/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
from heapq import nlargest
class Solution:
# Time: O(n log n) for sorting scores
# Space: O(n)
def high_five(self, items: list[list[int]]) -> list[list[int]]:
scores: dict[int, list[int]] = defaultdict(list)
for student, score in items:
scores[student].append(score)
return [[student, sum(nlargest(5, vals)) // 5] for student, vals in sorted(scores.items())]
```
## Complexity
| Time | Space |
| ----------------------------- | ----- |
| O(n log n) for sorting scores | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# House Robber Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/house-robber
Tested Python solution for LeetCode 198 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 198, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/house-robber/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 198 # by problem number
lcpy gen -s house_robber # by problem name
```
## Problem
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**.
Given an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police***.
### Examples
```
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
```
```
Input: nums = [2,7,9,3,1]
Output: 12
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.
```
### Constraints
* `1 <= nums.length <= 100`
* `0 <= nums[i] <= 400`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
"""
Houses: [2, 7, 9, 3, 1]
Can't rob adjacent houses!
For each house: max(skip, rob) = max(prev1, prev2 + current)
Step by step:
i=0: prev2=0, prev1=0, num=2 → max(0, 0+2) = 2
i=1: prev2=0, prev1=2, num=7 → max(2, 0+7) = 7
i=2: prev2=2, prev1=7, num=9 → max(7, 2+9) = 11
i=3: prev2=7, prev1=11, num=3 → max(11, 7+3) = 11
i=4: prev2=11, prev1=11, num=1 → max(11, 11+1) = 12
"""
# Time: O(n)
# Space: O(1)
def rob(self, nums: list[int]) -> int:
prev2 = prev1 = 0 # prev2: max 2 ago, prev1: max 1 ago
for num in nums:
prev2, prev1 = prev1, max(prev1, prev2 + num)
return prev1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# House Robber II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/house-robber-ii
Tested Python solution for LeetCode 213 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 213, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/house-robber-ii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 213 # by problem number
lcpy gen -s house_robber_ii # by problem name
```
## Problem
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are **arranged in a circle.** That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.
Given an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police***.
### Examples
```
Input: nums = [2,3,2]
Output: 3
```
**Explanation:** You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses.
```
Input: nums = [1,2,3,1]
Output: 4
```
**Explanation:** Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
```
Input: nums = [1,2,3]
Output: 3
```
### Constraints
* 1 \<= nums.length \<= 100
* 0 \<= nums\[i] \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def rob(self, nums: list[int]) -> int:
"""
Optimized version with better variable naming and edge case handling.
Time: O(n)
Space: O(1)
"""
if not nums:
return 0
if len(nums) == 1:
return nums[0]
def rob_range(start: int, end: int) -> int:
"""Rob houses from start to end (inclusive)."""
prev_rob = prev_not_rob = 0
for i in range(start, end + 1):
current_rob = prev_not_rob + nums[i]
current_not_rob = max(prev_rob, prev_not_rob)
prev_rob, prev_not_rob = current_rob, current_not_rob
return max(prev_rob, prev_not_rob)
n = len(nums)
# Case 1: Rob houses 0 to n-2 (exclude last house)
case1 = rob_range(0, n - 2)
# Case 2: Rob houses 1 to n-1 (exclude first house)
case2 = rob_range(1, n - 1)
return max(case1, case2)
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# House Robber III Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/house-robber-iii
Tested Python solution for LeetCode 337 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 337, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/house-robber-iii/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 337 # by problem number
lcpy gen -s house_robber_iii # by problem name
```
## Problem
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called `root`.
Besides the `root`, each house has one and only one parent house. After a tour, the smart thief realized that all houses in this place form a binary tree. It will automatically contact the police if **two directly-linked houses were broken into on the same night**.
Given the `root` of the binary tree, return *the maximum amount of money the thief can rob **without alerting the police***.
### Examples

```
Input: root = [3,2,3,null,3,null,1]
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
```

```
Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
```
### Constraints
* The number of nodes in the tree is in the range \[1, 10^4].
* 0 \<= Node.val \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def rob(self, root: TreeNode[int] | None) -> int:
def dfs(node: TreeNode[int] | None) -> tuple[int, int]:
# Returns (max if rob node, max if skip node).
if node is None:
return 0, 0
left_rob, left_skip = dfs(node.left)
right_rob, right_skip = dfs(node.right)
rob = node.val + left_skip + right_skip
skip = max(left_rob, left_skip) + max(right_rob, right_skip)
return rob, skip
return max(dfs(root))
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# House Robber IV Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/house-robber-iv
Tested Python solution for LeetCode 2560 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 2560, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/house-robber-iv/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2560 # by problem number
lcpy gen -s house_robber_iv # by problem name
```
## Problem
There are several consecutive houses along a street, each of which has some money inside. There is also a robber, who wants to steal money from the homes, but he **refuses to steal from adjacent homes**.
The **capability** of the robber is the maximum amount of money he steals from one house of all the houses he robbed.
You are given an integer array `nums` representing how much money is stashed in each house. More formally, the `ith` house from the left has `nums[i]` dollars.
You are also given an integer `k`, representing the **minimum** number of houses the robber will steal from. It is always possible to steal at least `k` houses.
Return *the **minimum** capability of the robber out of all the possible ways to steal at least* `k` *houses*.
### Examples
```
Input: nums = [2,3,5,9], k = 2
Output: 5
```
**Explanation:** There are three ways to rob at least 2 houses:
* Rob the houses at indices 0 and 2. Capability is max(nums\[0], nums\[2]) = 5.
* Rob the houses at indices 0 and 3. Capability is max(nums\[0], nums\[3]) = 9.
* Rob the houses at indices 1 and 3. Capability is max(nums\[1], nums\[3]) = 9.
Therefore, we return min(5, 9, 9) = 5.
```
Input: nums = [2,7,9,3,1], k = 2
Output: 2
```
**Explanation:** There are 7 ways to rob the houses. The way which leads to minimum capability is to rob the house at index 0 and 4. Return max(nums\[0], nums\[4]) = 2.
### Constraints
* 1 \<= nums.length \<= 10\5\
* 1 \<= nums\[i] \<= 10\9\
* 1 \<= k \<= (nums.length + 1)/2
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber_iv/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/house_robber_iv/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log m) where m = max(nums)
# Space: O(1)
def min_capability(self, nums: list[int], k: int) -> int:
def can_steal(cap: int) -> bool:
count = 0
i = 0
while i < len(nums):
if nums[i] <= cap:
count += 1
i += 2
else:
i += 1
return count >= k
lo, hi = min(nums), max(nums)
while lo < hi:
mid = (lo + hi) // 2
if can_steal(mid):
hi = mid
else:
lo = mid + 1
return lo
```
## Complexity
| Time | Space |
| ------------------------------ | ----- |
| O(n log m) where m = max(nums) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# How Many Apples Can You Put into the Basket
Source: https://leetcode-py.wisl.dev/problems/how-many-apples-can-you-put-into-the-basket
Tested Python solution for LeetCode 1196 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1196, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/how-many-apples-can-you-put-into-the-basket/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1196 # by problem number
lcpy gen -s how_many_apples_can_you_put_into_the_basket # by problem name
```
## Problem
You have some apples and a basket that can carry up to `5000` units of weight.
Given an integer array `weight` where `weight[i]` is the weight of the `i-th` apple, return the maximum number of apples you can put in the basket.
### Examples
```
Input: weight = [100,200,150,1000]
Output: 4
Explanation: All 4 apples can be carried by the basket since their sum of weights is 1450.
```
```
Input: weight = [900,950,800,1000,700,800]
Output: 5
Explanation: The sum of weights of the 6 apples exceeds 5000 so we choose any 5 of them.
```
### Constraints
* `1 <= weight.length <= 10^3`
* `1 <= weight[i] <= 10^3`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/how_many_apples_can_you_put_into_the_basket/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/how_many_apples_can_you_put_into_the_basket/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n) for the sorted copy
def max_number_of_apples(self, weight: list[int]) -> int:
total = 0
for count, w in enumerate(sorted(weight)):
total += w
if total > 5000:
return count
return len(weight)
```
## Complexity
| Time | Space |
| ---------- | ------------------------ |
| O(n log n) | O(n) for the sorted copy |
## Tags
[NeetCode All](/catalog/neetcode).
# Image Overlap Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/image-overlap
Tested Python solution for LeetCode 835 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 835, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/image-overlap/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 835 # by problem number
lcpy gen -s image_overlap # by problem name
```
## Problem
You are given two images, `img1` and `img2`, represented as binary, square matrices of size `n x n`. A binary matrix has only `0`s and `1`s as values.
We **translate** one image however we choose by sliding all the `1` bits left, right, up, and/or down any number of units. We then place it on top of the other image. We can then calculate the **overlap** by counting the number of positions that have a `1` in **both** images.
Note also that a translation does **not** include any kind of rotation. Any `1` bits that are translated outside of the matrix borders are erased.
Return *the largest possible overlap*.
### Examples

```
Input: img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]
Output: 3
Explanation: We translate img1 to right by 1 unit and down by 1 unit.
```

The number of positions that have a 1 in both images is 3 (shown in red).

```
Input: img1 = [[1]], img2 = [[1]]
Output: 1
```
```
Input: img1 = [[0]], img2 = [[0]]
Output: 0
```
### Constraints
* n == img1.length == img1\[i].length
* n == img2.length == img2\[i].length
* 1 \<= n \<= 30
* img1\[i]\[j] is either 0 or 1.
* img2\[i]\[j] is either 0 or 1.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/image_overlap/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/image_overlap/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n^4) where n is the image size (pairs of 1 bits across both images)
# Space: O(n^2) for the shift counter
def largest_overlap(self, img1: list[list[int]], img2: list[list[int]]) -> int:
ones1 = [(i, j) for i, row in enumerate(img1) for j, val in enumerate(row) if val]
ones2 = [(i, j) for i, row in enumerate(img2) for j, val in enumerate(row) if val]
shifts: Counter[tuple[int, int]] = Counter()
best = 0
for i1, j1 in ones1:
for i2, j2 in ones2:
shift = (i2 - i1, j2 - j1)
shifts[shift] += 1
best = max(best, shifts[shift])
return best
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------- | ---------------------------- |
| O(n^4) where n is the image size (pairs of 1 bits across both images) | O(n^2) for the shift counter |
## Tags
# Image Smoother Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/image-smoother
Tested Python solution for LeetCode 661 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 661, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/image-smoother/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 661 # by problem number
lcpy gen -s image_smoother # by problem name
```
## Problem
An **image smoother** is a filter of the size `3 x 3` that can be applied to each cell of an image by rounding down the average of the cell and the eight surrounding cells (i.e., the average of the nine cells in the blue smoother). If one or more of the surrounding cells of a cell is not present, we do not consider it in the average (i.e., the average of the four cells in the red smoother).
Given an `m x n` integer matrix `img` representing the grayscale of an image, return the image after applying the smoother on each cell of it.
### Examples

```
Input: img = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[0,0,0],[0,0,0],[0,0,0]]
Explanation: For the points (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0.
For the points (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0.
For the point (1,1): floor(8/9) = floor(0.88888889) = 0.
```

```
Input: img = [[100,200,100],[200,50,200],[100,200,100]]
Output: [[137,141,137],[141,138,141],[137,141,137]]
Explanation: For the points (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137.
For the points (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141.
For the point (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138.
```
### Constraints
* m == img.length
* n == img\[i].length
* 1 \<= m, n \<= 200
* 0 \<= img\[i]\[j] \<= 255
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/image_smoother/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/image_smoother/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def image_smoother(self, img: list[list[int]]) -> list[list[int]]:
m, n = len(img), len(img[0])
result: list[list[int]] = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
total = count = 0
for x in range(max(0, i - 1), min(m, i + 2)):
for y in range(max(0, j - 1), min(n, j + 2)):
total += img[x][y]
count += 1
result[i][j] = total // count
return result
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Implement Magic Dictionary Python Solution
Source: https://leetcode-py.wisl.dev/problems/implement-magic-dictionary
Tested Python solution for LeetCode 676 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 676, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Depth-First Search](/catalog/topics/depth-first-search), [Design](/catalog/topics/design), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/implement-magic-dictionary/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 676 # by problem number
lcpy gen -s implement_magic_dictionary # by problem name
```
## Problem
Design a data structure that is initialized with a list of **different** words. Provided a string, you should determine if you can change **exactly one character** in this string to match any word in the data structure.
Implement the `MagicDictionary` class:
* `MagicDictionary()` Initializes the object.
* `void buildDict(String[] dictionary)` Sets the data structure with an array of distinct strings `dictionary`.
* `bool search(String searchWord)` Returns `true` if you can change **exactly one character** in `searchWord` to match any string in the data structure, otherwise returns `false`.
### Examples
```
Input
["MagicDictionary", "buildDict", "search", "search", "search", "search"]
[[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
Output
[null, null, false, true, false, false]
Explanation
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict(["hello", "leetcode"]);
magicDictionary.search("hello"); // return False
magicDictionary.search("hhllo"); // We can change the second 'h' to 'e' to match "hello" so we return True
magicDictionary.search("hell"); // return False
magicDictionary.search("leetcoded"); // return False
```
### Constraints
* `1 <= dictionary.length <= 100`
* `1 <= dictionary[i].length <= 100`
* `dictionary[i]` consists of only lower-case English letters.
* All the strings in `dictionary` are **distinct**.
* `1 <= searchWord.length <= 100`
* `searchWord` consists of only lower-case English letters.
* `buildDict` will be called only once before `search`.
* At most `100` calls will be made to `search`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_magic_dictionary/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_magic_dictionary/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class MagicDictionary:
# Time: build_dict O(total chars), search O(25 * n)
# Space: O(total chars)
def __init__(self) -> None:
self.words: set[str] = set()
def build_dict(self, dictionary: list[str]) -> None:
self.words = set(dictionary)
def search(self, search_word: str) -> bool:
for i, kept in enumerate(search_word):
prefix = search_word[:i]
suffix = search_word[i + 1 :]
for char in "abcdefghijklmnopqrstuvwxyz":
if char != kept and prefix + char + suffix in self.words:
return True
return False
```
## Complexity
| Time | Space |
| --------------------------------------------- | -------------- |
| build\_dict O(total chars), search O(25 \* n) | O(total chars) |
## Tags
# Implement Queue using Stacks Python Solution
Source: https://leetcode-py.wisl.dev/problems/implement-queue-using-stacks
Tested Python solution for LeetCode 232 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 232, [Easy](/catalog/easy). Topics: [Stack](/catalog/topics/stack), [Design](/catalog/topics/design), [Queue](/catalog/topics/queue). [View on LeetCode](https://leetcode.com/problems/implement-queue-using-stacks/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 232 # by problem number
lcpy gen -s implement_queue_using_stacks # by problem name
```
## Problem
Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (`push`, `peek`, `pop`, and `empty`).
Implement the `MyQueue` class:
* `void push(int x)` Pushes element x to the back of the queue.
* `int pop()` Removes the element from the front of the queue and returns it.
* `int peek()` Returns the element at the front of the queue.
* `boolean empty()` Returns `true` if the queue is empty, `false` otherwise.
### Examples
```
Input
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 1, 1, false]
```
**Explanation:**
```
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
```
### Constraints
* 1 \<= x \<= 9
* At most 100 calls will be made to push, pop, peek, and empty.
* All the calls to pop and peek are valid.
**Notes:**
* You must use **only** standard operations of a stack, which means only `push to top`, `peek/pop from top`, `size`, and `is empty` operations are valid.
* Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack's standard operations.
**Follow-up:** Can you implement the queue such that each operation is amortized `O(1)` time complexity? In other words, performing `n` operations will take overall `O(n)` time even if one of those operations may take longer.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_queue_using_stacks/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_queue_using_stacks/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class MyQueue:
# Time: O(1)
# Space: O(n)
def __init__(self) -> None:
self.input_stack: list[int] = []
self.output_stack: list[int] = []
# Time: O(1)
# Space: O(1)
def push(self, x: int) -> None:
self.input_stack.append(x)
# Time: O(1) amortized
# Space: O(1)
def pop(self) -> int:
self._move_to_output()
return self.output_stack.pop()
# Time: O(1) amortized
# Space: O(1)
def peek(self) -> int:
self._move_to_output()
return self.output_stack[-1]
# Time: O(1)
# Space: O(1)
def empty(self) -> bool:
return not self.input_stack and not self.output_stack
def _move_to_output(self) -> None:
if not self.output_stack:
while self.input_stack:
self.output_stack.append(self.input_stack.pop())
# Amortized O(1) Explanation:
# Example with 4 push + 4 pop operations:
#
# push(1) # input: [1], output: [] - O(1)
# push(2) # input: [1,2], output: [] - O(1)
# push(3) # input: [1,2,3], output: [] - O(1)
# push(4) # input: [1,2,3,4], output: [] - O(1)
#
# pop() # Move all 4 to output: input: [], output: [4,3,2,1] then pop 1 - O(4)
# pop() # output: [4,3,2], just pop 2 - O(1)
# pop() # output: [4,3], just pop 3 - O(1)
# pop() # output: [4], just pop 4 - O(1)
#
# Total cost: 4 + 4 + 1 + 1 + 1 = 11 operations for 8 calls = 1.4 per operation
# Key: Each element moves exactly once from input to output, so expensive O(n)
# transfer is "spread out" over multiple cheap O(1) operations = amortized O(1)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Implement Rand10() Using Rand7()
Source: https://leetcode-py.wisl.dev/problems/implement-rand10-using-rand7
Tested Python solution for LeetCode 470 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 470, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), Rejection Sampling, Randomized, Probability and Statistics. [View on LeetCode](https://leetcode.com/problems/implement-rand10-using-rand7/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 470 # by problem number
lcpy gen -s implement_rand10_using_rand7 # by problem name
```
## Problem
Given the **API** `rand7()` that generates a uniform random integer in the range `[1, 7]`, write a function `rand10()` that generates a uniform random integer in the range `[1, 10]`. You can only call the API `rand7()`, and you shouldn't call any other API. Please **do not** use a language's built-in random API.
Each test case will have one **internal** argument `n`, the number of times that your implemented function `rand10()` will be called while testing. Note that this is **not an argument** passed to `rand10()`.
### Examples
```
Input: n = 1
Output: [2]
```
```
Input: n = 2
Output: [2,8]
```
```
Input: n = 3
Output: [3,8,10]
```
### Constraints
* 1 \<= n \<= 10^5
**Follow up:**
* What is the expected value for the number of calls to `rand7()` function?
* Could you minimize the number of calls to `rand7()`?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_rand10_using_rand7/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_rand10_using_rand7/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
# LeetCode exposes rand7() as a black-box API. It is modelled here as a
# concrete seeded class so the generated tests are deterministic and can also
# count how many rand7() calls each rand10() draw consumed.
class Rand7:
def __init__(self, seed: int) -> None:
self._rng = random.Random(seed)
self.calls = 0
def rand7(self) -> int:
self.calls += 1
return self._rng.randint(1, 7)
class Solution:
# Rejection sampling on a 7x7 grid: 49 equally likely outcomes, 40 of them
# map onto [1, 10] and the remaining 9 are discarded and redrawn. Expected
# rand7() calls per rand10() is 2 * 49 / 40 ~= 2.45.
# Time: O(1) expected per rand10() call
# Space: O(1)
def __init__(self, rand7_api: Rand7) -> None:
self._rand7_api = rand7_api
def rand10(self) -> int:
while True:
row = self._rand7_api.rand7()
col = self._rand7_api.rand7()
idx = (row - 1) * 7 + col
if idx <= 40:
return (idx - 1) % 10 + 1
```
## Complexity
| Time | Space |
| ------------------------------- | ----- |
| O(1) expected per rand10() call | O(1) |
## Tags
# Implement Stack using Queues Python Solution
Source: https://leetcode-py.wisl.dev/problems/implement-stack-using-queues
Tested Python solution for LeetCode 225 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 225, [Easy](/catalog/easy). Topics: [Stack](/catalog/topics/stack), [Design](/catalog/topics/design), [Queue](/catalog/topics/queue). [View on LeetCode](https://leetcode.com/problems/implement-stack-using-queues/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 225 # by problem number
lcpy gen -s implement_stack_using_queues # by problem name
```
## Problem
Implement a last-in-first-out (LIFO) stack using only two queues. The implemented stack should support all the functions of a normal stack (`push`, `top`, `pop`, and `empty`).
Implement the `MyStack` class:
* `void push(int x)` Pushes element x to the top of the stack.
* `int pop()` Removes the element on the top of the stack and returns it.
* `int top()` Returns the element on the top of the stack.
* `boolean empty()` Returns `true` if the stack is empty, `false` otherwise.
### Examples
```
Input
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 2, 2, false]
```
**Explanation:**
```
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // return 2
myStack.pop(); // return 2
myStack.empty(); // return False
```
### Constraints
* 1 \<= x \<= 9
* At most 100 calls will be made to push, pop, top, and empty.
* All the calls to pop and top are valid.
**Notes:**
* You must use **only** standard operations of a queue, which means that only `push to back`, `peek/pop from front`, `size`, and `is empty` operations are valid.
* Depending on your language, the queue may not be supported natively. You may simulate a queue using a list or deque (double-ended queue) as long as you use only a queue's standard operations.
**Follow-up:** Can you implement the stack using only one queue?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_stack_using_queues/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_stack_using_queues/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class MyStack:
def __init__(self) -> None:
self.queue: deque[int] = deque()
# Time: O(n)
# Space: O(n)
def push(self, x: int) -> None:
self.queue.append(x)
for _ in range(len(self.queue) - 1):
self.queue.append(self.queue.popleft())
# Time: O(1)
# Space: O(1)
def pop(self) -> int:
return self.queue.popleft()
# Time: O(1)
# Space: O(1)
def top(self) -> int:
return self.queue[0]
# Time: O(1)
# Space: O(1)
def empty(self) -> bool:
return len(self.queue) == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Implement Trie (Prefix Tree) Python Solution
Source: https://leetcode-py.wisl.dev/problems/implement-trie-prefix-tree
Tested Python solution for LeetCode 208 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 208, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Design](/catalog/topics/design), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/implement-trie-prefix-tree/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 208 # by problem number
lcpy gen -s implement_trie_prefix_tree # by problem name
```
## Problem
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.
Implement the Trie class:
* `Trie()` Initializes the trie object.
* `void insert(String word)` Inserts the string `word` into the trie.
* `boolean search(String word)` Returns `true` if the string `word` is in the trie (i.e., was inserted before), and `false` otherwise.
* `boolean startsWith(String prefix)` Returns `true` if there is a previously inserted string `word` that has the prefix `prefix`, and `false` otherwise.
### Examples
```
Input
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
Output
[null, null, true, false, true, null, true]
```
**Explanation:**
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
trie = Trie()
trie.insert("apple")
trie.search("apple") # return True
trie.search("app") # return False
trie.starts_with("app") # return True
trie.insert("app")
trie.search("app") # return True
```
### Constraints
* `1 <= word.length, prefix.length <= 2000`
* `word` and `prefix` consist only of lowercase English letters.
* At most `3 * 10^4` calls **in total** will be made to `insert`, `search`, and `starts_with`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_trie_prefix_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/implement_trie_prefix_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py.data_structures import DictTree, RecursiveDict
class Trie(DictTree[str]):
END_OF_WORD = "#"
# Time: O(1)
# Space: O(1)
def __init__(self) -> None:
self.root: RecursiveDict[str] = {}
# Time: O(m) where m is word length
# Space: O(m)
def insert(self, word: str) -> None:
node = self.root
for char in word:
if char not in node:
node[char] = {}
node = node[char]
node[self.END_OF_WORD] = True
# Time: O(m) where m is word length
# Space: O(1)
def search(self, word: str) -> bool:
node = self.root
for char in word:
if char not in node:
return False
node = node[char]
return self.END_OF_WORD in node
# Time: O(m) where m is prefix length
# Space: O(1)
def starts_with(self, prefix: str) -> bool:
node = self.root
for char in prefix:
if char not in node:
return False
node = node[char]
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Increasing Order Search Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/increasing-order-search-tree
Tested Python solution for LeetCode 897 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 897, [Easy](/catalog/easy). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/increasing-order-search-tree/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 897 # by problem number
lcpy gen -s increasing_order_search_tree # by problem name
```
## Problem
Given the `root` of a binary search tree, rearrange the tree in in-order so that the leftmost node in the tree is now the root of the tree, and every node has no left child and only one right child.
### Examples

```
Input: root = [5,3,6,2,4,null,8,1,null,null,null,7,9]
Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]
```

```
Input: root = [5,1,7]
Output: [1,null,5,null,7]
```
### Constraints
* The number of nodes in the given tree will be in the range \[1, 100].
* 0 \<= Node.val \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/increasing_order_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/increasing_order_search_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) each node is pushed and popped exactly once
# Space: O(n) for the node list plus the stack of left-spine ancestors
def increasing_bst(self, root: TreeNode[int] | None) -> TreeNode[int] | None:
nodes: list[TreeNode[int]] = []
stack: list[TreeNode[int]] = []
current = root
while current or stack:
while current:
stack.append(current)
current = current.left
current = stack.pop()
nodes.append(current)
current = current.right
for i, node in enumerate(nodes):
node.left = None
node.right = nodes[i + 1] if i + 1 < len(nodes) else None
return nodes[0] if nodes else None
```
## Complexity
| Time | Space |
| ------------------------------------------------ | ------------------------------------------------------------- |
| O(n) each node is pushed and popped exactly once | O(n) for the node list plus the stack of left-spine ancestors |
## Tags
# Increasing Triplet Subsequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/increasing-triplet-subsequence
Tested Python solution for LeetCode 334 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 334, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), Longest Increasing Subsequence. [View on LeetCode](https://leetcode.com/problems/increasing-triplet-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 334 # by problem number
lcpy gen -s increasing_triplet_subsequence # by problem name
```
## Problem
Given an integer array `nums`, return `true` if there exists a triple of indices `(i, j, k)` such that `i < j < k` and `nums[i] < nums[j] < nums[k]`. If no such indices exists, return `false`.
### Examples
```
Input: nums = [1,2,3,4,5]
Output: true
Explanation: Any triplet where i < j < k is valid.
```
```
Input: nums = [5,4,3,2,1]
Output: false
Explanation: No triplet exists.
```
```
Input: nums = [2,1,5,0,4,6]
Output: true
Explanation: One of the valid triplet is (1, 4, 5), because nums[1] == 1 < nums[4] == 4 < nums[5] == 6.
```
### Constraints
* `1 <= nums.length <= 5 * 10^5`
* `-2^31 <= nums[i] <= 2^31 - 1`
**Follow up:** Could you implement a solution that runs in `O(n)` time complexity and `O(1)` space complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/increasing_triplet_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/increasing_triplet_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def increasing_triplet(self, nums: list[int]) -> bool:
first: int | None = None
second: int | None = None
for x in nums:
if first is None or x <= first:
first = x
elif second is None or x <= second:
second = x
else:
return True
return False
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Inorder Successor in BST Python Solution
Source: https://leetcode-py.wisl.dev/problems/inorder-successor-in-bst
Tested Python solution for LeetCode 285 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 285, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/inorder-successor-in-bst/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 285 # by problem number
lcpy gen -s inorder_successor_in_bst # by problem name
```
## Problem
Given the `root` of a binary search tree and a node `p` in it, return *the in-order successor of that node in the BST*. If the given node has no in-order successor in the tree, return `null`.
The successor of a node `p` is the node with the smallest key greater than `p.val`.
### Examples
```
Input: root = [2,1,3], p = 1
Output: 2
Explanation: 1's in-order successor node is 2. Note that both p and the return value are of TreeNode type.
```
```
Input: root = [5,3,6,2,4,null,null,1], p = 6
Output: null
Explanation: There is no in-order successor of the current node, so the answer is null.
```
### Constraints
* The number of nodes in the tree is in the range `[1, 10^4]`.
* `-10^5 <= Node.val <= 10^5`
* All Nodes will have unique values.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/inorder_successor_in_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/inorder_successor_in_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(h)
# Space: O(1)
def inorder_successor(
self, root: TreeNode[int] | None, p: TreeNode[int]
) -> TreeNode[int] | None:
# If p has a right subtree, successor is leftmost node of that subtree.
# Otherwise, successor is the lowest ancestor for which p lies in its
# left subtree. Track candidate successor while walking down.
successor = None
while root:
if p.val < root.val:
successor = root
root = root.left
else:
root = root.right
return successor
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(h) | O(1) |
## Tags
[Grind](/catalog/grind).
# Inorder Successor in BST II Python Solution
Source: https://leetcode-py.wisl.dev/problems/inorder-successor-in-bst-ii
Tested Python solution for LeetCode 510 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 510, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/inorder-successor-in-bst-ii/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 510 # by problem number
lcpy gen -s inorder_successor_in_bst_ii # by problem name
```
## Problem
Given a `node` in a binary search tree, return the in-order successor of that node in the BST. If that node has no in-order successor, return `null`.
The successor of a `node` is the node with the smallest key greater than `node.val`.
You will have direct access to the node but not to the root of the tree. Each node will have a reference to its parent node. Below is the definition for `Node`:
```
class Node {
public int val;
public Node left;
public Node right;
public Node parent;
}
```
**Follow up:** Could you solve it without looking up any of the node's values?
### Examples

```
Input: tree = [2,1,3], node = 1
Output: 2
Explanation: 1's in-order successor node is 2. Note that both the node and the return value is of Node type.
```

```
Input: tree = [5,3,6,2,4,null,null,1], node = 6
Output: null
Explanation: There is no in-order successor of the current node, so the answer is null.
```
### Constraints
* The number of nodes in the tree is in the range `[1, 10^4]`.
* `-10^5 <= Node.val <= 10^5`
* All Nodes will have unique values.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/inorder_successor_in_bst_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/inorder_successor_in_bst_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(self, val: int = 0) -> None:
self.val = val
self.left: Node | None = None
self.right: Node | None = None
self.parent: Node | None = None
class Solution:
# Time: O(h)
# Space: O(1)
def inorder_successor(self, node: Node) -> Node | None:
if node.right is not None:
succ = node.right
while succ.left is not None:
succ = succ.left
return succ
child = node
parent = node.parent
while parent is not None and parent.right is child:
child = parent
parent = parent.parent
return parent
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(h) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Insert Delete GetRandom O(1) Python Solution
Source: https://leetcode-py.wisl.dev/problems/insert-delete-getrandom-o1
Tested Python solution for LeetCode 380 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 380, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Design](/catalog/topics/design). [View on LeetCode](https://leetcode.com/problems/insert-delete-getrandom-o1/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 380 # by problem number
lcpy gen -s insert_delete_getrandom_o1 # by problem name
```
## Problem
Implement the `RandomizedSet` class:
* `RandomizedSet()` Initializes the `RandomizedSet` object.
* `bool insert(int val)` Inserts an item `val` into the set if not present. Returns `true` if the item was not present, `false` otherwise.
* `bool remove(int val)` Removes an item `val` from the set if present. Returns `true` if the item was present, `false` otherwise.
* `int getRandom()` Returns a random element from the current set of elements (it's guaranteed that at least one element exists when this method is called). Each element must have the **same probability** of being returned.
You must implement the functions of the class such that each function works in **average** `O(1)` time complexity.
### Examples
```
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.
```
### Constraints
* `-2^31 <= val <= 2^31 - 1`
* At most `2 * 10^5` calls will be made to `insert`, `remove`, and `getRandom`.
* There will be **at least one** element in the data structure when `getRandom` is called.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_delete_getrandom_o1/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_delete_getrandom_o1/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
class RandomizedSet:
# List stores values; dict maps value -> index in list.
# O(1) remove via swap-with-last trick: move last element into removed slot.
# Time: O(1) average per operation
# Space: O(n)
def __init__(self) -> None:
self.values: list[int] = []
self.index: dict[int, int] = {}
def insert(self, val: int) -> bool:
if val in self.index:
return False
self.index[val] = len(self.values)
self.values.append(val)
return True
def remove(self, val: int) -> bool:
if val not in self.index:
return False
last_val = self.values[-1]
remove_idx = self.index[val]
# Move last element into the removed slot, then drop the tail
self.values[remove_idx] = last_val
self.index[last_val] = remove_idx
self.values.pop()
del self.index[val]
return True
def get_random(self) -> int:
return random.choice(self.values)
```
## Complexity
| Time | Space |
| -------------------------- | ----- |
| O(1) average per operation | O(n) |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Insert Delete GetRandom O(1) - Duplicates
Source: https://leetcode-py.wisl.dev/problems/insert-delete-getrandom-o1-duplicates-allowed
Tested Python solution for LeetCode 381 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 381, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Design](/catalog/topics/design), Randomized. [View on LeetCode](https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 381 # by problem number
lcpy gen -s insert_delete_getrandom_o1_duplicates_allowed # by problem name
```
## Problem
RandomizedCollection is a data structure that contains a collection of numbers, possibly duplicates (i.e., a multiset). It should support inserting and removing specific elements and also reporting a random element.
Implement the `RandomizedCollection` class:
* `RandomizedCollection()` Initializes the empty `RandomizedCollection` object.
* `bool insert(int val)` Inserts an item `val` into the multiset, even if the item is already present. Returns `true` if the item is not present, `false` otherwise.
* `bool remove(int val)` Removes an item `val` from the multiset if present. Returns `true` if the item is present, `false` otherwise. Note that if `val` has multiple occurrences in the multiset, we only remove one of them.
* `int getRandom()` Returns a random element from the current multiset of elements. The probability of each element being returned is **linearly related** to the number of the same values the multiset contains.
You must implement the functions of the class such that each function works on **average** `O(1)` time complexity.
**Note:** The test cases are generated such that `getRandom` will only be called if there is at least one item in the `RandomizedCollection`.
### Examples
```
Input
["RandomizedCollection", "insert", "insert", "insert", "getRandom", "remove", "getRandom"]
[[], [1], [1], [2], [], [1], []]
Output
[null, true, false, true, 2, true, 1]
Explanation
RandomizedCollection randomizedCollection = new RandomizedCollection();
randomizedCollection.insert(1); // return true since the collection does not contain 1.
// Inserts 1 into the collection.
randomizedCollection.insert(1); // return false since the collection contains 1.
// Inserts another 1 into the collection. Collection now contains [1,1].
randomizedCollection.insert(2); // return true since the collection does not contain 2.
// Inserts 2 into the collection. Collection now contains [1,1,2].
randomizedCollection.getRandom(); // getRandom should:
// - return 1 with probability 2/3, or
// - return 2 with probability 1/3.
randomizedCollection.remove(1); // return true since the collection contains 1.
// Removes 1 from the collection. Collection now contains [1,2].
randomizedCollection.getRandom(); // getRandom should return 1 or 2, both equally likely.
```
### Constraints
* `-2^31 <= val <= 2^31 - 1`
* At most `2 * 10^5` calls in total will be made to `insert`, `remove`, and `getRandom`.
* There will be **at least one** element in the data structure when `getRandom` is called.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_delete_getrandom_o1_duplicates_allowed/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_delete_getrandom_o1_duplicates_allowed/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
class RandomizedCollection:
# Time: insert O(1), remove O(1), get_random O(1) average
# Space: O(n)
def __init__(self) -> None:
self.vals: list[int] = []
self.positions: dict[int, set[int]] = {}
def insert(self, val: int) -> bool:
self.vals.append(val)
self.positions.setdefault(val, set()).add(len(self.vals) - 1)
return len(self.positions[val]) == 1
def remove(self, val: int) -> bool:
indices = self.positions.get(val)
if not indices:
return False
idx = indices.pop()
last = len(self.vals) - 1
last_val = self.vals[last]
self.vals[idx] = last_val
self.positions[last_val].add(idx)
self.positions[last_val].discard(last)
self.vals.pop()
if not self.positions[val]:
del self.positions[val]
return True
def get_random(self) -> int:
return random.choice(self.vals)
```
## Complexity
| Time | Space |
| -------------------------------------------------- | ----- |
| insert O(1), remove O(1), get\_random O(1) average | O(n) |
## Tags
# Insert Greatest Common Divisors in Linked List
Source: https://leetcode-py.wisl.dev/problems/insert-greatest-common-divisors-in-linked-list
Tested Python solution for LeetCode 2807 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 2807, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Math](/catalog/topics/math), [Number Theory](/catalog/topics/number-theory). [View on LeetCode](https://leetcode.com/problems/insert-greatest-common-divisors-in-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2807 # by problem number
lcpy gen -s insert_greatest_common_divisors_in_linked_list # by problem name
```
## Problem
Given the `head` of a linked list, return the list after inserting the **greatest common divisor** of each pair of adjacent nodes.
Between every pair of adjacent nodes, insert a new node with a value equal to the greatest common divisor of them.
The **greatest common divisor** of two numbers is the largest positive integer that evenly divides both numbers.
### Examples

```
Input: head = [18,6,10,3]
Output: [18,6,6,2,10,1,3]
Explanation:
- We insert the greatest common divisor of 18 and 6 = 6 between the 1st and the 2nd nodes.
- We insert the greatest common divisor of 6 and 10 = 2 between the 2nd and the 3rd nodes.
- We insert the greatest common divisor of 10 and 3 = 1 between the 3rd and the 4th nodes.
There are no more adjacent nodes, so we return the linked list.
```

```
Input: head = [7]
Output: [7]
Explanation: The 1st diagram denotes the initial linked list and the 2nd diagram denotes the linked list after inserting the new nodes.
There are no pairs of adjacent nodes, so we return the initial linked list.
```
### Constraints
* The number of nodes in the list is in the range `[1, 5000]`.
* `1 <= Node.val <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_greatest_common_divisors_in_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_greatest_common_divisors_in_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from math import gcd
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def insert_greatest_common_divisors(self, head: ListNode[int] | None) -> ListNode[int] | None:
current = head
while current and current.next:
inserted = ListNode[int](gcd(current.val, current.next.val))
inserted.next = current.next
current.next = inserted
current = inserted.next
return head
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Insert Interval Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/insert-interval
Tested Python solution for LeetCode 57 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 57, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/insert-interval/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 57 # by problem number
lcpy gen -s insert_interval # by problem name
```
## Problem
You are given an array of non-overlapping intervals `intervals` where `intervals[i] = [starti, endi]` represent the start and the end of the ith 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.
Insert `newInterval` into `intervals` such that `intervals` is still sorted in ascending order by `starti` and `intervals` still does not have any overlapping intervals (merge overlapping intervals if necessary).
Return `intervals` after the insertion.
### Examples
```
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
```
```
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
```
### Constraints
* 0 \<= intervals.length \<= 10^4
* intervals\[i].length == 2
* 0 \<= starti \<= endi \<= 10^5
* intervals is sorted by starti in ascending order
* newInterval.length == 2
* 0 \<= start \<= end \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_interval/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_interval/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def insert(self, intervals: list[list[int]], new_interval: list[int]) -> list[list[int]]:
result = []
i = 0
# Add intervals before new_interval
while i < len(intervals) and intervals[i][1] < new_interval[0]:
result.append(intervals[i])
i += 1
# Merge overlapping intervals
while i < len(intervals) and intervals[i][0] <= new_interval[1]:
new_interval[0] = min(new_interval[0], intervals[i][0])
new_interval[1] = max(new_interval[1], intervals[i][1])
i += 1
result.append(new_interval)
# Add remaining intervals
result.extend(intervals[i:])
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Insert into a Binary Search Tree
Source: https://leetcode-py.wisl.dev/problems/insert-into-a-binary-search-tree
Tested Python solution for LeetCode 701 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 701, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/insert-into-a-binary-search-tree/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 701 # by problem number
lcpy gen -s insert_into_a_binary_search_tree # by problem name
```
## Problem
You are given the `root` node of a binary search tree (BST) and a `value` to insert into the tree. Return *the root node of the BST after the insertion*. It is **guaranteed** that the new value does not exist in the original BST.
**Notice** that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return **any of them**.
### Examples

```
Input: root = [4,2,7,1,3], val = 5
Output: [4,2,7,1,3,5]
Explanation: Another accepted tree is:

```
```
Input: root = [40,20,60,10,30,50,70], val = 25
Output: [40,20,60,10,30,50,70,null,null,25]
```
```
Input: root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
Output: [4,2,7,1,3,5]
```
### Constraints
* The number of nodes in the tree will be in the range \[0, 10^4].
* -10^8 \<= Node.val \<= 10^8
* All the values `Node.val` are **unique**.
* -10^8 \<= val \<= 10^8
* It's **guaranteed** that `val` does not exist in the original BST.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_into_a_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_into_a_binary_search_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(h)
# Space: O(1)
def insert_into_bst(self, root: TreeNode[int] | None, val: int) -> TreeNode[int] | None:
node = TreeNode(val)
if root is None:
return node
current = root
while True:
if val < current.val:
if current.left is None:
current.left = node
return root
current = current.left
else:
if current.right is None:
current.right = node
return root
current = current.right
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(h) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Insert into a Sorted Circular Linked List
Source: https://leetcode-py.wisl.dev/problems/insert-into-a-sorted-circular-linked-list
Tested Python solution for LeetCode 708 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 708, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/insert-into-a-sorted-circular-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 708 # by problem number
lcpy gen -s insert_into_a_sorted_circular_linked_list # by problem name
```
## Problem
Given a Circular Linked List node, which is sorted in non-descending order, write a function to insert a value `insertVal` into the list such that it remains a sorted circular list. The given node can be a reference to any single node in the list and may not necessarily be the smallest value in the circular list.
If there are multiple suitable places for insertion, you may choose any place to insert the new value. After the insertion, the circular list should remain sorted.
If the list is empty (i.e., the given node is `null`), you should create a new single circular list and return the reference to that single node. Otherwise, you should return the originally given node.
### Examples
```
Input: head = [3,4,1], insertVal = 2
Output: [3,4,1,2]
Explanation: The new node should be inserted between node 1 and node 3, and we should still return node 3.
```
```
Input: head = [], insertVal = 1
Output: [1]
Explanation: The list is empty (given head is null). We create a new single circular list and return the reference to that single node.
```
```
Input: head = [1], insertVal = 0
Output: [1,0]
```
### Constraints
* The number of nodes in the list is in the range \[0, 5 \* 10^4].
* -10^6 \<= Node.val, insertVal \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_into_a_sorted_circular_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insert_into_a_sorted_circular_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(self, val: int = 0, next: Node | None = None) -> None:
self.val = val
self.next: Node = next if next is not None else self
class Solution:
# Time: O(n)
# Space: O(1)
def insert(self, head: Node | None, insert_val: int) -> Node:
node = Node(insert_val)
if head is None:
return node
prev, curr = head, head.next
while curr is not head:
if prev.val <= insert_val <= curr.val or (
prev.val > curr.val and (insert_val >= prev.val or insert_val <= curr.val)
):
break
prev, curr = curr, curr.next
prev.next = node
node.next = curr
return head
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Insertion Sort List Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/insertion-sort-list
Tested Python solution for LeetCode 147 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 147, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/insertion-sort-list/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 147 # by problem number
lcpy gen -s insertion_sort_list # by problem name
```
## Problem
Given the `head` of a singly linked list, sort the list using **insertion sort**, and return *the sorted list's head*.
The steps of the **insertion sort** algorithm:
1. Insertion sort iterates, consuming one input element each repetition and growing a sorted output list.
2. At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list and inserts it there.
3. It repeats until no input elements remain.
The following is a graphical example of the insertion sort algorithm. The partially sorted list (black) initially contains only the first element in the list. One element (red) is removed from the input data and inserted in-place into the sorted list with each iteration.

### Examples

```
Input: head = [4,2,1,3]
Output: [1,2,3,4]
```

```
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]
```
### Constraints
* The number of nodes in the list is in the range \[1, 5000]
* -5000 \<= Node.val \<= 5000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insertion_sort_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/insertion_sort_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n^2)
# Space: O(1)
def insertion_sort_list(self, head: ListNode[int] | None) -> ListNode[int] | None:
dummy = ListNode[int](0)
dummy.next = head
current = head
while current is not None and current.next is not None:
next_node = current.next
if current.val <= next_node.val:
current = current.next
continue
current.next = next_node.next
prev = dummy
while prev.next is not None and prev.next.val < next_node.val:
prev = prev.next
next_node.next = prev.next
prev.next = next_node
return dummy.next
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Integer Break Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/integer-break
Tested Python solution for LeetCode 343 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 343, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/integer-break/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 343 # by problem number
lcpy gen -s integer_break # by problem name
```
## Problem
Given an integer `n`, break it into the sum of `k` **positive integers**, where `k >= 2`, and maximize the product of those integers.
Return *the maximum product you can get*.
### Examples
```
Input: n = 2
Output: 1
Explanation: 2 = 1 + 1, 1 * 1 = 1.
```
```
Input: n = 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 * 3 * 4 = 36.
```
### Constraints
* 2 \<= n \<= 58
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_break/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_break/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def integer_break(self, n: int) -> int:
dp = [0] * (n + 1)
dp[1] = 1
for target in range(2, n + 1):
for part in range(1, target):
dp[target] = max(dp[target], part * (target - part), part * dp[target - part])
return dp[n]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Integer Replacement Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/integer-replacement
Tested Python solution for LeetCode 397 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 397, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Bit Manipulation](/catalog/topics/bit-manipulation), [Memoization](/catalog/topics/memoization). [View on LeetCode](https://leetcode.com/problems/integer-replacement/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 397 # by problem number
lcpy gen -s integer_replacement # by problem name
```
## Problem
Given a positive integer `n`, you can apply one of the following operations:
* If `n` is even, replace `n` with `n / 2`.
* If `n` is odd, replace `n` with either `n + 1` or `n - 1`.
Return the minimum number of operations needed for `n` to become `1`.
### Examples
```
Input: n = 8
Output: 3
Explanation: 8 -> 4 -> 2 -> 1
```
```
Input: n = 7
Output: 4
Explanation: 7 -> 8 -> 4 -> 2 -> 1
or 7 -> 6 -> 3 -> 2 -> 1
```
```
Input: n = 4
Output: 2
```
### Constraints
* 1 \<= n \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_replacement/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_replacement/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(log n)
def integer_replacement(self, n: int) -> int:
ops = 0
while n != 1:
if n % 2 == 0:
n //= 2
elif n == 3 or n % 4 == 1:
n -= 1
else:
n += 1
ops += 1
return ops
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(log n) | O(log n) |
## Tags
# Integer to English Words Python Solution
Source: https://leetcode-py.wisl.dev/problems/integer-to-english-words
Tested Python solution for LeetCode 273 with 32 pytest cases. Generate a practice environment with lcpy.
LeetCode 273, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/integer-to-english-words/description/).
Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 273 # by problem number
lcpy gen -s integer_to_english_words # by problem name
```
## Problem
Convert a non-negative integer `num` to its English words representation.
### Examples
```
Input: num = 123
Output: 'One Hundred Twenty Three'
```
```
Input: num = 12345
Output: 'Twelve Thousand Three Hundred Forty Five'
```
```
Input: num = 1234567
Output: 'One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven'
```
### Constraints
* 0 \<= num \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_to_english_words/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_to_english_words/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1) # num < 2^31 bounds the word count
# Space: O(1)
BELOW_20: tuple[str, ...] = (
"",
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Eleven",
"Twelve",
"Thirteen",
"Fourteen",
"Fifteen",
"Sixteen",
"Seventeen",
"Eighteen",
"Nineteen",
)
TENS: tuple[str, ...] = (
"",
"",
"Twenty",
"Thirty",
"Forty",
"Fifty",
"Sixty",
"Seventy",
"Eighty",
"Ninety",
)
THOUSANDS: tuple[str, ...] = ("", "Thousand", "Million", "Billion")
def _three_digit(self, num: int) -> list[str]:
"""Convert 0 <= num < 1000 to words, e.g. 123 -> ['One', 'Hundred', ...]."""
if num == 0:
return []
if num < 20:
return [self.BELOW_20[num]]
if num < 100:
words = [self.TENS[num // 10]]
if num % 10:
words.append(self.BELOW_20[num % 10])
return words
words = [self.BELOW_20[num // 100], "Hundred"]
words.extend(self._three_digit(num % 100))
return words
def number_to_words(self, num: int) -> str:
if num == 0:
return "Zero"
words: list[str] = []
for unit in range(3, -1, -1):
chunk = num // 1000**unit
if chunk:
words.extend(self._three_digit(chunk))
if unit:
words.append(self.THOUSANDS[unit])
num %= 1000**unit
return " ".join(words)
```
## Complexity
| Time | Space |
| ----------------------------------------- | ----- |
| O(1) # num \< 2^31 bounds the word count | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Integer to Roman Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/integer-to-roman
Tested Python solution for LeetCode 12 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 12, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/integer-to-roman/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 12 # by problem number
lcpy gen -s integer_to_roman # by problem name
```
## Problem
Seven different symbols represent Roman numerals with the following values:
| Symbol | Value |
| ------ | ----- |
| I | 1 |
| V | 5 |
| X | 10 |
| L | 50 |
| C | 100 |
| D | 500 |
| M | 1000 |
Roman numerals are formed by appending the conversions of decimal place values from highest to lowest. Converting a decimal place value into a Roman numeral has the following rules:
* If the value does not start with 4 or 9, select the symbol of the maximal value that can be subtracted from the input, append that symbol to the result, subtract its value, and convert the remainder to a Roman numeral.
* If the value starts with 4 or 9 use the **subtractive form** representing one symbol subtracted from the following symbol, for example, 4 is 1 (`I`) less than 5 (`V`): `IV` and 9 is 1 (`I`) less than 10 (`X`): `IX`. Only the following subtractive forms are used: 4 (`IV`), 9 (`IX`), 40 (`XL`), 90 (`XC`), 400 (`CD`) and 900 (`CM`).
* Only powers of 10 (`I`, `X`, `C`, `M`) can be appended consecutively at most 3 times to represent multiples of 10. You cannot append 5 (`V`), 50 (`L`), or 500 (`D`) multiple times. If you need to append a symbol 4 times use the **subtractive form**.
Given an integer, convert it to a Roman numeral.
### Examples
```
Input: num = 3749
Output: "MMMDCCXLIX"
Explanation:
3000 = MMM as 1000 (M) + 1000 (M) + 1000 (M)
700 = DCC as 500 (D) + 100 (C) + 100 (C)
40 = XL as 10 (X) less of 50 (L)
9 = IX as 1 (I) less of 10 (X)
Note: 49 is not 1 (I) less of 50 (L) because the conversion is based on decimal places
```
```
Input: num = 58
Output: "LVIII"
Explanation:
50 = L
8 = VIII
```
```
Input: num = 1994
Output: "MCMXCIV"
Explanation:
1000 = M
900 = CM
90 = XC
4 = IV
```
### Constraints
* `1 <= num <= 3999`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_to_roman/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/integer_to_roman/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def int_to_roman(self, num: int) -> str:
value_symbols: list[tuple[int, str]] = [
(1000, "M"),
(900, "CM"),
(500, "D"),
(400, "CD"),
(100, "C"),
(90, "XC"),
(50, "L"),
(40, "XL"),
(10, "X"),
(9, "IX"),
(5, "V"),
(4, "IV"),
(1, "I"),
]
result: list[str] = []
for value, symbol in value_symbols:
while num >= value:
result.append(symbol)
num -= value
return "".join(result)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Interleaving String Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/interleaving-string
Tested Python solution for LeetCode 97 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 97, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/interleaving-string/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 97 # by problem number
lcpy gen -s interleaving_string # by problem name
```
## Problem
Given strings `s1`, `s2`, and `s3`, find whether `s3` is formed by an **interleaving** of `s1` and `s2`.
An interleaving of two strings `s` and `t` is a configuration where `s` and `t` are divided into `n` and `m` substrings respectively, such that:
* s = s1 + s2 + ... + sn
* t = t1 + t2 + ... + tm
* |n - m| \<= 1
* The interleaving is s1 + t1 + s2 + t2 + s3 + t3 + ... or t1 + s1 + t2 + s2 + t3 + s3 + ...
**Note:** `a + b` is the concatenation of strings `a` and `b`.
### Examples

```
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true
Explanation: One way to obtain s3 is:
Split s1 into s1 = "aa" + "bc" + "c", and s2 into s2 = "dbbc" + "a".
Interleaving the two splits, we get "aadbbcbcac".
```
```
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false
Explanation: Notice how it is hard to find a viable interleaving because s3 must preserve the character order of s1 and s2.
```
```
Input: s1 = "", s2 = "", s3 = ""
Output: true
```
### Constraints
* 0 \<= s1.length, s2.length \<= 100
* 0 \<= s3.length \<= 200
* s1, s2, and s3 consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/interleaving_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/interleaving_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(n) using a single rolling row
def is_interleave(self, s1: str, s2: str, s3: str) -> bool:
m, n = len(s1), len(s2)
if m + n != len(s3):
return False
if n > m:
# Ensure s1 is the longer string so the rolling row stays minimal
return self.is_interleave(s2, s1, s3)
# dp[j] = True if s3[:i+j] is an interleaving of s1[:i] and s2[:j]
dp = [False] * (n + 1)
for i in range(m + 1):
for j in range(n + 1):
if i == 0 and j == 0:
dp[j] = True
elif i == 0:
dp[j] = dp[j - 1] and s2[j - 1] == s3[j - 1]
elif j == 0:
dp[j] = dp[j] and s1[i - 1] == s3[i - 1]
else:
dp[j] = (dp[j] and s1[i - 1] == s3[i + j - 1]) or (
dp[j - 1] and s2[j - 1] == s3[i + j - 1]
)
return dp[n]
```
## Complexity
| Time | Space |
| --------- | ------------------------------- |
| O(m \* n) | O(n) using a single rolling row |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Intersection of Two Arrays Python Solution
Source: https://leetcode-py.wisl.dev/problems/intersection-of-two-arrays
Tested Python solution for LeetCode 349 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 349, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/intersection-of-two-arrays/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 349 # by problem number
lcpy gen -s intersection_of_two_arrays # by problem name
```
## Problem
Given two integer arrays `nums1` and `nums2`, return an array of their intersection. Each element in the result must be **unique** and you may return the result in **any order**.
### Examples
```
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]
```
```
Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [9,4]
Explanation: [4,9] is also accepted.
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 1000
* 0 \<= nums1\[i], nums2\[i] \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/intersection_of_two_arrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/intersection_of_two_arrays/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(n + m)
def intersection(self, nums1: list[int], nums2: list[int]) -> list[int]:
return sorted(set(nums1) & set(nums2))
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + m) | O(n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Intersection of Two Arrays II Python Solution
Source: https://leetcode-py.wisl.dev/problems/intersection-of-two-arrays-ii
Tested Python solution for LeetCode 350 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 350, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/intersection-of-two-arrays-ii/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 350 # by problem number
lcpy gen -s intersection_of_two_arrays_ii # by problem name
```
## Problem
Given two integer arrays `nums1` and `nums2`, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in **any order**.
### Examples
```
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]
```
```
Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [4,9]
Explanation: [9,4] is also accepted.
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 1000
* 0 \<= nums1\[i], nums2\[i] \<= 1000
**Follow up:**
* What if the given array is already sorted? How would you optimize your algorithm?
* What if `nums1`'s size is small compared to `nums2`'s size? Which algorithm is better?
* What if elements of `nums2` are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/intersection_of_two_arrays_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/intersection_of_two_arrays_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(m + n)
# Space: O(min(m, n))
def intersection(self, nums1: list[int], nums2: list[int]) -> list[int]:
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
counts = Counter(nums1)
result: list[int] = []
for num in nums2:
if counts[num] > 0:
counts[num] -= 1
result.append(num)
return result
```
## Complexity
| Time | Space |
| -------- | ------------ |
| O(m + n) | O(min(m, n)) |
## Tags
# Intersection of Two Linked Lists
Source: https://leetcode-py.wisl.dev/problems/intersection-of-two-linked-lists
Tested Python solution for LeetCode 160 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 160, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/intersection-of-two-linked-lists/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 160 # by problem number
lcpy gen -s intersection_of_two_linked_lists # by problem name
```
## Problem
Given the heads of two singly linked-lists `headA` and `headB`, return *the node at which the two lists intersect*. If the two linked lists have no intersection at all, return `null`.
For example, the following two linked lists begin to intersect at node `c1`:

The test cases are generated such that there are no cycles anywhere in the entire linked structure.
**Note** that the linked lists must **retain their original structure** after the function returns.
### Examples

```
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
Output: Intersected at '8'
Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect).
From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.
- Note that the intersected node's value is not 1 because the nodes with value 1 in A and B (2nd node in A and 3rd node in B) are different node references. In other words, they point to two different locations in memory, while the nodes with value 8 in A and B (3rd node in A and 4th node in B) point to the same location in memory.
```

```
Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Intersected at '2'
Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect).
From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B.
```

```
Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: No intersection
Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values.
```
### Constraints
* The number of nodes of `listA` is in the `m`
* The number of nodes of `listB` is in the `n`
* 1 \<= m, n \<= 3 \* 10^4
* 1 \<= Node.val \<= 10^5
* 0 \<= skipA \<= m
* 0 \<= skipB \<= n
* `intersectVal` is `0` if `listA` and `listB` do not intersect.
* `intersectVal == listA[skipA] == listB[skipB]` if `listA` and `listB` intersect.
**Follow up:** Could you write a solution that runs in `O(m + n)` time and use only `O(1)` memory?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/intersection_of_two_linked_lists/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/intersection_of_two_linked_lists/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(m + n)
# Space: O(1)
def get_intersection_node(
self, head_a: ListNode[int] | None, head_b: ListNode[int] | None
) -> ListNode[int] | None:
pointer_a: ListNode[int] | None = head_a
pointer_b: ListNode[int] | None = head_b
while pointer_a is not pointer_b:
pointer_a = pointer_a.next if pointer_a is not None else head_b
pointer_b = pointer_b.next if pointer_b is not None else head_a
return pointer_a
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(m + n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Interval List Intersections Python Solution
Source: https://leetcode-py.wisl.dev/problems/interval-list-intersections
Tested Python solution for LeetCode 986 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 986, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), Sweep Line. [View on LeetCode](https://leetcode.com/problems/interval-list-intersections/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 986 # by problem number
lcpy gen -s interval_list_intersections # by problem name
```
## Problem
You are given two lists of closed intervals, `firstList` and `secondList`, where `firstList[i] = [starti, endi]` and `secondList[j] = [startj, endj]`. Each list of intervals is pairwise disjoint and in sorted order.
Return *the intersection of these two interval lists*.
A closed interval `[a, b]` (with `a <= b`) denotes the set of real numbers `x` with `a <= x <= b`.
The **intersection** of two closed intervals is a set of real numbers that are either empty or represented as a closed interval. For example, the intersection of `[1, 3]` and `[2, 4]` is `[2, 3]`.
### Examples

```
Input: firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]
Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]
```
```
Input: firstList = [[1,3],[5,9]], secondList = []
Output: []
```
### Constraints
* `0 <= firstList.length, secondList.length <= 1000`
* `firstList.length + secondList.length >= 1`
* `0 <= starti < endi <= 10^9`
* `endi < starti+1`
* `0 <= startj < endj <= 10^9`
* `endj < startj+1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/interval_list_intersections/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/interval_list_intersections/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m + n)
# Space: O(1) excluding output
def interval_intersection(
self, first_list: list[list[int]], second_list: list[list[int]]
) -> list[list[int]]:
result: list[list[int]] = []
i = j = 0
while i < len(first_list) and j < len(second_list):
lo = max(first_list[i][0], second_list[j][0])
hi = min(first_list[i][1], second_list[j][1])
if lo <= hi:
result.append([lo, hi])
if first_list[i][1] < second_list[j][1]:
i += 1
else:
j += 1
return result
```
## Complexity
| Time | Space |
| -------- | --------------------- |
| O(m + n) | O(1) excluding output |
## Tags
[NeetCode All](/catalog/neetcode).
# Invert Binary Tree Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/invert-binary-tree
Tested Python solution for LeetCode 226 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 226, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/invert-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 226 # by problem number
lcpy gen -s invert_binary_tree # by problem name
```
## Problem
Given the `root` of a binary tree, invert the tree, and return its root.
### Examples
```
Input: root = [4,2,7,1,3,6,9]
Output: [4,7,2,9,6,3,1]
```
```
Input: root = [2,1,3]
Output: [2,3,1]
```
```
Input: root = []
Output: []
```
### Constraints
* The number of nodes in the tree is in the range \[0, 100]
* -100 \<= Node.val \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/invert_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/invert_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
# Note: "Fringe" is the general CS term for the data structure holding nodes to be explored.
# Stack (LIFO) → DFS, Queue (FIFO) → BFS, Priority Queue → A*/Best-first search
class Solution:
# DFS recursive
# Time: O(n)
# Space: O(h) where h is height of tree
def invert_tree(self, root: TreeNode[int] | None) -> TreeNode[int] | None:
if not root:
return None
root.left, root.right = self.invert_tree(root.right), self.invert_tree(root.left)
return root
class SolutionDFS:
# DFS iterative
# Time: O(n)
# Space: O(h) where h is height of tree
def invert_tree(self, root: TreeNode[int] | None) -> TreeNode[int] | None:
if not root:
return None
stack: list[TreeNode[int] | None] = [root]
while stack:
node = stack.pop()
if node is None:
continue
node.left, node.right = node.right, node.left
stack.append(node.left)
stack.append(node.right)
return root
class SolutionBFS:
# Time: O(n)
# Space: O(w) where w is maximum width of tree
def invert_tree(self, root: TreeNode[int] | None) -> TreeNode[int] | None:
if not root:
return None
queue: deque[TreeNode[int] | None] = deque([root])
while queue:
node = queue.popleft()
if node is None:
continue
node.left, node.right = node.right, node.left
queue.append(node.left)
queue.append(node.right)
return root
```
## Complexity
| Time | Space |
| ---- | ------------------------------ |
| O(n) | O(h) where h is height of tree |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# IP to CIDR Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/ip-to-cidr
Tested Python solution for LeetCode 751 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 751, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/ip-to-cidr/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 751 # by problem number
lcpy gen -s ip_to_cidr # by problem name
```
## Problem
An IP address is a formatted 32-bit unsigned integer where each group of 8 bits is printed as a decimal number and the dot character `'.'` splits the groups.
* For example, the binary number `00001111 10001000 11111111 01101011` (spaces added for clarity) formatted as an IP address would be `"15.136.255.107"`.
A CIDR block is a format used to denote a specific set of IP addresses. It is a string consisting of a base IP address, followed by a slash, followed by a prefix length `k`. The addresses it covers are all the IPs whose first `k` bits are the same as the base IP address.
* For example, `"123.45.67.89/20"` is a CIDR block with a prefix length of 20. Any IP address whose binary representation matches `01111011 00101101 0100xxxx xxxxxxxx`, where x can be either 0 or 1, is in the set covered by the CIDR block.
You are given a start IP address `ip` and the number of IP addresses we need to cover `n`. Your goal is to use as few CIDR blocks as possible to cover all the IP addresses in the inclusive range `[ip, ip + n - 1]` exactly. No other IP addresses outside of the range should be covered.
Return the shortest list of CIDR blocks that covers the range of IP addresses. If there are multiple answers, return any of them.
### Examples
```
Input: ip = "255.0.0.7", n = 10
Output: ["255.0.0.7/32","255.0.0.8/29","255.0.0.16/32"]
Explanation: The CIDR block "255.0.0.7/32" covers the first address, "255.0.0.8/29" covers the middle 8 addresses, and "255.0.0.16/32" covers the last address.
```
```
Input: ip = "117.145.102.62", n = 8
Output: ["117.145.102.62/31","117.145.102.64/30","117.145.102.68/31"]
```
### Constraints
* 7 \<= ip.length \<= 15
* ip is a valid IPv4 on the form "a.b.c.d" where a, b, c, and d are integers in the range \[0, 255].
* 1 \<= n \<= 1000
* Every implied address ip + x (for x \< n) will be a valid IPv4 address.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/ip_to_cidr/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/ip_to_cidr/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) for the range length
# Space: O(1) excluding the output
def ip_to_cidr(self, ip: str, n: int) -> list[str]:
def int_to_ip(x: int) -> str:
return f"{(x >> 24) & 255}.{(x >> 16) & 255}.{(x >> 8) & 255}.{x & 255}"
a, b, c, d = (int(part) for part in ip.split("."))
start = (a << 24) | (b << 16) | (c << 8) | d
ans: list[str] = []
while n > 0:
low = start & -start
max_block = low if start else 1 << 32
block = 1
while block * 2 <= max_block and block * 2 <= n:
block *= 2
ans.append(f"{int_to_ip(start)}/{32 - block.bit_length() + 1}")
start += block
n -= block
return ans
```
## Complexity
| Time | Space |
| ------------------------- | ------------------------- |
| O(n) for the range length | O(1) excluding the output |
## Tags
[NeetCode All](/catalog/neetcode).
# IPO Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/ipo
Tested Python solution for LeetCode 502 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 502, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/ipo/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 502 # by problem number
lcpy gen -s ipo # by problem name
```
## Problem
Suppose LeetCode will start its IPO soon. To sell a good price of its shares, it can only finish at most `k` distinct projects before the IPO. Help LeetCode maximize its total capital.
You are given `n` projects where the `ith` project has a pure profit `profits[i]` and a minimum capital `capital[i]` is needed to start it.
Initially, you have `w` capital. When you finish a project, you obtain its pure profit, which is added to your total capital.
Pick a list of **at most** `k` distinct projects to **maximize your final capital**, and return the final maximized capital.
### Examples
```
Input: k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]
Output: 4
Explanation: Start with capital 0, only project 0 is affordable. Finish it -> capital 1. Now projects 1 and 2 are affordable; finish project 2 -> capital 4.
```
```
Input: k = 3, w = 0, profits = [1,2,3], capital = [0,1,2]
Output: 6
```
### Constraints
* 1 \<= k \<= 10^5
* 0 \<= w \<= 10^9
* n == profits.length
* n == capital.length
* 1 \<= n \<= 10^5
* 0 \<= profits\[i] \<= 10^4
* 0 \<= capital\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/ipo/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/ipo/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O((n + k) * log n) sorting + heap operations
# Space: O(n) for the heap
def find_maximized_capital(self, k: int, w: int, profits: list[int], capital: list[int]) -> int:
# Sort projects by required capital ascending.
projects = sorted(zip(capital, profits, strict=True))
heap: list[int] = [] # max-heap of profits (stored negated)
index = 0
n = len(projects)
current = w
for _ in range(k):
# Push every project now affordable into the profit heap.
while index < n and projects[index][0] <= current:
heapq.heappush(heap, -projects[index][1])
index += 1
if not heap:
break
current += -heapq.heappop(heap)
return current
```
## Complexity
| Time | Space |
| --------------------------------------------- | ----------------- |
| O((n + k) \* log n) sorting + heap operations | O(n) for the heap |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Is Graph Bipartite? Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/is-graph-bipartite
Tested Python solution for LeetCode 785 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 785, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/is-graph-bipartite/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 785 # by problem number
lcpy gen -s is_graph_bipartite # by problem name
```
## Problem
There is an undirected graph with `n` nodes, where each node is numbered between `0` and `n - 1`. You are given a 2D array `graph`, where `graph[u]` is an array of nodes that node `u` is adjacent to. More formally, for each `v` in `graph[u]`, there is an undirected edge between node `u` and node `v`. The graph has the following properties:
* There are no self-edges (`graph[u]` does not contain `u`).
* There are no parallel edges (`graph[u]` does not contain duplicate values).
* If `v` is in `graph[u]`, then `u` is in `graph[v]` (the graph is undirected).
* The graph may not be connected, meaning there may be two nodes `u` and `v` such that there is no path between them.
A graph is **bipartite** if the nodes can be partitioned into two independent sets `A` and `B` such that **every** edge in the graph connects a node in set `A` and a node in set `B`.
Return `true` *if and only if it is **bipartite***.
### Examples

```
Input: graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
Output: false
Explanation: There is no way to partition the nodes into two independent sets such that every edge connects a node in one and a node in the other.
```

```
Input: graph = [[1,3],[0,2],[1,3],[0,2]]
Output: true
Explanation: We can partition the nodes into two sets: {0, 2} and {1, 3}.
```
### Constraints
* graph.length == n
* 1 \<= n \<= 100
* 0 \<= graph\[u].length \< n
* 0 \<= graph\[u]\[i] \<= n - 1
* graph\[u] does not contain u.
* All the values of graph\[u] are unique.
* If graph\[u] contains v, then graph\[v] contains u.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/is_graph_bipartite/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/is_graph_bipartite/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(V + E) where V is nodes, E is edges
# Space: O(V)
def is_bipartite(self, graph: list[list[int]]) -> bool:
n = len(graph)
color = [-1] * n
for start in range(n):
if color[start] == -1:
queue = deque([start])
color[start] = 0
while queue:
node = queue.popleft()
for neighbor in graph[node]:
if color[neighbor] == -1:
color[neighbor] = 1 - color[node]
queue.append(neighbor)
elif color[neighbor] == color[node]:
return False
return True
```
## Complexity
| Time | Space |
| ------------------------------------- | ----- |
| O(V + E) where V is nodes, E is edges | O(V) |
## Tags
[NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Is Subsequence Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/is-subsequence
Tested Python solution for LeetCode 392 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 392, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/is-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 392 # by problem number
lcpy gen -s is_subsequence # by problem name
```
## Problem
Given two strings `s` and `t`, return `true` *if* `s` *is a **subsequence** of* `t`*, or* `false` *otherwise*.
A **subsequence** of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., `"ace"` is a subsequence of `"abcde"` while `"aec"` is not).
### Examples
```
Input: s = "abc", t = "ahbgdc"
Output: true
```
```
Input: s = "axc", t = "ahbgdc"
Output: false
```
### Constraints
* 0 \<= s.length \<= 100
* 0 \<= t.length \<= 10^4
* s and t consist only of lowercase English letters.
**Follow up:** Suppose 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?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/is_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/is_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(t))
# Space: O(1)
def is_subsequence(self, s: str, t: str) -> bool:
i = 0
for char in t:
if i < len(s) and char == s[i]:
i += 1
return i == len(s)
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(len(t)) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Island Perimeter Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/island-perimeter
Tested Python solution for LeetCode 463 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 463, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/island-perimeter/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 463 # by problem number
lcpy gen -s island_perimeter # by problem name
```
## Problem
You are given `row x col` `grid` representing a map where `grid[i][j] = 1` represents land and `grid[i][j] = 0` represents water.
Grid cells are connected **horizontally/vertically** (not diagonally). The `grid` is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).
The island doesn't have "lakes", meaning the water inside isn't connected to the water around the island. One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100.
Determine the perimeter of the island.
### Examples

```
Input: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
Output: 16
Explanation: The perimeter is the 16 yellow stripes in the image above.
```
```
Input: grid = [[1]]
Output: 4
```
```
Input: grid = [[1,0]]
Output: 4
```
### Constraints
* row == grid.length
* col == grid\[i].length
* 1 \<= row, col \<= 100
* grid\[i]\[j] is 0 or 1.
* There is exactly one island in grid.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/island_perimeter/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/island_perimeter/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(row * col) every cell inspected once
# Space: O(1)
def island_perimeter(self, grid: list[list[int]]) -> int:
rows = len(grid)
cols = len(grid[0])
perimeter = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == 0:
continue
# Each land cell starts with 4 exposed sides; subtract shared edges.
exposed = 4
for dr, dc in ((-1, 0), (1, 0), (0, -1), (0, 1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1:
exposed -= 1
perimeter += exposed
return perimeter
```
## Complexity
| Time | Space |
| --------------------------------------- | ----- |
| O(row \* col) every cell inspected once | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Isomorphic Strings Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/isomorphic-strings
Tested Python solution for LeetCode 205 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 205, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/isomorphic-strings/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 205 # by problem number
lcpy gen -s isomorphic_strings # by problem name
```
## Problem
Given two strings `s` and `t`, determine if they are isomorphic.
Two strings `s` and `t` are isomorphic if the characters in `s` can be replaced to get `t`.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character, but a character may map to itself.
### Examples
```
Input: s = "egg", t = "add"
Output: true
Explanation: The strings s and t can be made identical by:
- Mapping 'e' to 'a'.
- Mapping 'g' to 'd'.
```
```
Input: s = "f11", t = "b23"
Output: false
Explanation: The strings s and t can not be made identical as '1' needs to be mapped to both '2' and '3'.
```
```
Input: s = "paper", t = "title"
Output: true
```
### Constraints
* 1 \<= s.length \<= 5 \* 10^4
* t.length == s.length
* s and t consist of any valid ascii character.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/isomorphic_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/isomorphic_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(k) where k is the alphabet size
def is_isomorphic(self, s: str, t: str) -> bool:
s_to_t: dict[str, str] = {}
t_to_s: dict[str, str] = {}
for cs, ct in zip(s, t, strict=True):
if cs in s_to_t and s_to_t[cs] != ct:
return False
if ct in t_to_s and t_to_s[ct] != cs:
return False
s_to_t[cs] = ct
t_to_s[ct] = cs
return True
```
## Complexity
| Time | Space |
| ---- | --------------------------------- |
| O(n) | O(k) where k is the alphabet size |
## Tags
[NeetCode All](/catalog/neetcode).
# Jewels and Stones Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/jewels-and-stones
Tested Python solution for LeetCode 771 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 771, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/jewels-and-stones/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 771 # by problem number
lcpy gen -s jewels_and_stones # by problem name
```
## Problem
You're given strings `jewels` representing the types of stones that are jewels, and `stones` representing the stones you have. Each character in `stones` is a type of stone you have. You want to know how many of the stones you have are also jewels.
Letters are case sensitive, so `"a"` is considered a different type of stone from `"A"`.
### Examples
```
Input: jewels = "aA", stones = "aAAbbbb"
Output: 3
```
```
Input: jewels = "z", stones = "ZZ"
Output: 0
```
### Constraints
* 1 \<= jewels.length, stones.length \<= 50
* jewels and stones consist of only English letters.
* All the characters of jewels are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jewels_and_stones/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jewels_and_stones/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(n)
def num_jewels_in_stones(self, jewels: str, stones: str) -> int:
jewel_set = set(jewels)
return sum(stone in jewel_set for stone in stones)
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + m) | O(n) |
## Tags
# Jump Game Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/jump-game
Tested Python solution for LeetCode 55 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 55, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/jump-game/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 55 # by problem number
lcpy gen -s jump_game # by problem name
```
## Problem
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.
Return `true` *if you can reach the last index, or* `false` *otherwise*.
### Examples
```
Input: nums = [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
```
```
Input: nums = [3,2,1,0,4]
Output: false
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.
```
### Constraints
* `1 <= nums.length <= 10^4`
* `0 <= nums[i] <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jump_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jump_game/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def can_jump(self, nums: list[int]) -> bool:
max_reach = 0
for i, jump in enumerate(nums):
if i > max_reach:
return False
max_reach = max(max_reach, i + jump)
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Jump Game II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/jump-game-ii
Tested Python solution for LeetCode 45 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 45, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/jump-game-ii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 45 # by problem number
lcpy gen -s jump_game_ii # by problem name
```
## Problem
You are given a 0-indexed array of integers `nums` of length `n`. You are initially positioned at index 0.
Each element `nums[i]` represents the maximum length of a forward jump from index `i`. In other words, if you are at index `i`, you can jump to any index `(i + j)` where:
* `0 <= j <= nums[i]` and
* `i + j < n`
Return the minimum number of jumps to reach index `n - 1`. The test cases are generated such that you can reach index `n - 1`.
### Examples
```
Input: nums = [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
```
```
Input: nums = [2,3,0,1,4]
Output: 2
```
### Constraints
* `1 <= nums.length <= 10^4`
* `0 <= nums[i] <= 1000`
* It's guaranteed that you can reach `nums[n - 1]`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jump_game_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jump_game_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def jump(self, nums: list[int]) -> int:
n = len(nums)
if n == 1:
return 0
jumps = 0
current_end = 0
farthest = 0
for i in range(n - 1):
farthest = max(farthest, i + nums[i])
if i == current_end:
jumps += 1
current_end = farthest
if current_end >= n - 1:
break
return jumps
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Jump Game VII Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/jump-game-vii
Tested Python solution for LeetCode 1871 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1871, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sliding Window](/catalog/topics/sliding-window), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/jump-game-vii/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1871 # by problem number
lcpy gen -s jump_game_vii # by problem name
```
## Problem
You are given a **0-indexed** binary string `s` and two integers `minJump` and `maxJump`. In the beginning, you are standing at index `0`, which is equal to `'0'`. You can move from index `i` to index `j` if the following conditions are fulfilled:
* `i + minJump <= j <= min(i + maxJump, s.length - 1)`, and
* `s[j] == '0'`.
Return `true` *if you can reach index* `s.length - 1` *in* `s`, or `false` otherwise.
### Examples
```
Input: s = "011010", minJump = 2, maxJump = 3
Output: true
Explanation:
In the first step, move from index 0 to index 3.
In the second step, move from index 3 to index 5.
```
```
Input: s = "01101110", minJump = 2, maxJump = 3
Output: false
```
### Constraints
* 2 \<= s.length \<= 10^5
* s\[i] is either '0' or '1'.
* s\[0] == '0'
* 1 \<= minJump \<= maxJump \< s.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jump_game_vii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/jump_game_vii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def can_reach(self, s: str, min_jump: int, max_jump: int) -> bool:
n = len(s)
if s[n - 1] != "0":
return False
reachable = [False] * n
reachable[0] = True
window_count = 0
for i in range(1, n):
if i >= min_jump and reachable[i - min_jump]:
window_count += 1
if i > max_jump and reachable[i - max_jump - 1]:
window_count -= 1
if s[i] == "0" and window_count > 0:
reachable[i] = True
return reachable[n - 1]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# K Closest Points to Origin Python Solution
Source: https://leetcode-py.wisl.dev/problems/k-closest-points-to-origin
Tested Python solution for LeetCode 973 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 973, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Geometry](/catalog/topics/geometry), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), Quickselect. [View on LeetCode](https://leetcode.com/problems/k-closest-points-to-origin/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 973 # by problem number
lcpy gen -s k_closest_points_to_origin # by problem name
```
## Problem
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)`.
The distance between two points on the **X-Y** plane is the Euclidean distance (i.e., `√(x1 - x2)² + (y1 - y2)²`).
You may return the answer in **any order**. The answer is **guaranteed** to be **unique** (except for the order that it is in).
### Examples

```
Input: points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]
```
**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]].
```
Input: points = [[3,3],[5,-1],[-2,4]], k = 2
Output: [[3,3],[-2,4]]
```
**Explanation:** The answer \[\[-2,4],\[3,3]] would also be accepted.
### Constraints
* `1 <= k <= points.length <= 10^4`
* `-10^4 <= xi, yi <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_closest_points_to_origin/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_closest_points_to_origin/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log k)
# Space: O(k)
def k_closest(self, points: list[list[int]], k: int) -> list[list[int]]:
heap: list[tuple[int, list[int]]] = []
for x, y in points:
dist = x * x + y * y
heapq.heappush(heap, (-dist, [x, y]))
if len(heap) > k:
heapq.heappop(heap)
return [point for _, point in heap]
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log k) | O(k) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# K-diff Pairs in an Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/k-diff-pairs-in-an-array
Tested Python solution for LeetCode 532 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 532, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/k-diff-pairs-in-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 532 # by problem number
lcpy gen -s k_diff_pairs_in_an_array # by problem name
```
## Problem
Given an array of integers `nums` and an integer `k`, return the number of **unique** k-diff pairs in the array.
A **k-diff** pair is an integer pair `(nums[i], nums[j])`, where the following are true:
* `0 <= i, j < nums.length`
* `i != j`
* `|nums[i] - nums[j]| == k`
**Notice** that `|val|` denotes the absolute value of `val`.
### Examples
```
Input: nums = [3,1,4,1,5], k = 2
Output: 2
Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5).
Although we have two 1s in the input, we should only return the number of **unique** pairs.
```
```
Input: nums = [1,2,3,4,5], k = 1
Output: 4
Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5).
```
```
Input: nums = [1,3,1,5,4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).
```
### Constraints
* 1 \<= nums.length \<= 10^4
* -10^7 \<= nums\[i] \<= 10^7
* 0 \<= k \<= 10^7
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_diff_pairs_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_diff_pairs_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(n)
def find_pairs(self, nums: list[int], k: int) -> int:
counts = Counter(nums)
if k == 0:
return sum(1 for count in counts.values() if count > 1)
return sum(1 for value in counts if value + k in counts)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# K Empty Slots Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/k-empty-slots
Tested Python solution for LeetCode 683 with 41 pytest cases. Generate a practice environment with lcpy.
LeetCode 683, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree), [Queue](/catalog/topics/queue), [Ordered Set](/catalog/topics/ordered-set), [Sliding Window](/catalog/topics/sliding-window), Monotonic Queue, [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/k-empty-slots/description/).
Generate this problem as a practice environment: tested reference solution, 41 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 683 # by problem number
lcpy gen -s k_empty_slots # by problem name
```
## Problem
You have `n` bulbs in a row numbered from `1` to `n`. Initially, all the bulbs are turned off. We turn on **exactly one** bulb every day until all bulbs are on after `n` days.
You are given an array `bulbs` of length `n` where `bulbs[i] = x` means that on the `(i+1)`-th day, we will turn on the bulb at position `x` where `i` is **0-indexed** and `x` is **1-indexed**.
Given an integer `k`, return *the **minimum day number** such that there exists two **turned on** bulbs that have **exactly** `k` bulbs between them that are **all turned off**. If there is no such day, return `-1`.*
### Examples
```
Input: bulbs = [1,3,2], k = 1
Output: 2
```
**Explanation:**
* On the first day: bulbs\[0] = 1, first bulb is turned on: \[1,0,0]
* On the second day: bulbs\[1] = 3, third bulb is turned on: \[1,0,1]
* On the third day: bulbs\[2] = 2, second bulb is turned on: \[1,1,1]
We return 2 because on the second day, there were two on bulbs with one off bulb between them.
```
Input: bulbs = [1,2,3], k = 1
Output: -1
```
### Constraints
* `n == bulbs.length`
* `1 <= n <= 2 * 10^4`
* `1 <= bulbs[i] <= n`
* `bulbs` is a permutation of numbers from `1` to `n`.
* `0 <= k <= 2 * 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_empty_slots/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_empty_slots/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def k_empty_slots(self, bulbs: list[int], k: int) -> int:
n = len(bulbs)
days = [0] * n
for day, pos in enumerate(bulbs, 1):
days[pos - 1] = day
ans = n + 1
left, right = 0, k + 1
while right < n:
valid = True
for i in range(left + 1, right):
if days[i] < days[left] or days[i] < days[right]:
left, right = i, i + k + 1
valid = False
break
if valid:
ans = min(ans, max(days[left], days[right]))
left, right = right, right + k + 1
return -1 if ans == n + 1 else ans
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# K Inverse Pairs Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/k-inverse-pairs-array
Tested Python solution for LeetCode 629 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 629, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/k-inverse-pairs-array/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 629 # by problem number
lcpy gen -s k_inverse_pairs_array # by problem name
```
## Problem
For an integer array `nums`, an **inverse pair** is a pair of integers `[i, j]` where `0 <= i < j < nums.length` and `nums[i] > nums[j]`.
Given two integers `n` and `k`, return the number of different arrays consisting of numbers from `1` to `n` such that there are exactly `k` **inverse pairs**. Since the answer can be huge, return it **modulo** `10^9 + 7`.
### Examples
```
Input: n = 3, k = 0
Output: 1
Explanation: Only the array [1,2,3] which consists of numbers from 1 to 3 has exactly 0 inverse pairs.
```
```
Input: n = 3, k = 1
Output: 2
Explanation: The array [1,3,2] and [2,1,3] have exactly 1 inverse pair.
```
### Constraints
* 1 \<= n \<= 1000
* 0 \<= k \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_inverse_pairs_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_inverse_pairs_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * k)
# Space: O(k)
def k_inverse_pairs(self, n: int, k: int) -> int:
mod = 1_000_000_007
# dp[j]: arrays using values 1..i with exactly j inverse pairs.
dp = [0] * (k + 1)
dp[0] = 1
for i in range(2, n + 1):
prefix = [0] * (k + 2)
for j in range(k + 1):
prefix[j + 1] = (prefix[j] + dp[j]) % mod
# Inserting value i adds between 0 and i-1 new inverse pairs.
new = [0] * (k + 1)
for j in range(k + 1):
low = max(0, j - (i - 1))
new[j] = (prefix[j + 1] - prefix[low]) % mod
dp = new
return dp[k]
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(n \* k) | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# K-Similar Strings Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/k-similarity
Tested Python solution for LeetCode 854 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 854, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/k-similarity/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 854 # by problem number
lcpy gen -s k_similarity # by problem name
```
## Problem
Strings `s1` and `s2` are `k`-**similar** (for some non-negative integer `k`) if we can swap the positions of two letters in `s1` exactly `k` times so that the resulting string equals `s2`.
Given two anagrams `s1` and `s2`, return the smallest `k` for which `s1` and `s2` are `k`-**similar**.
### Examples
```
Input: s1 = "ab", s2 = "ba"
Output: 1
Explanation: The two strings are 1-similar because we can use one swap to change s1 to s2: "ab" --> "ba".
```
```
Input: s1 = "abc", s2 = "bca"
Output: 2
Explanation: The two strings are 2-similar because we can use two swaps to change s1 to s2: "abc" --> "bac" --> "bca".
```
### Constraints
* 1 \<= s1.length \<= 20
* s2.length == s1.length
* s1 and s2 contain only lowercase letters from the set \{'a', 'b', 'c', 'd', 'e', 'f'}.
* s2 is an anagram of s1.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_similarity/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_similarity/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n * n! * n) worst case, pruned heavily by only branching on the
# first mismatched position and only swapping in a letter that belongs there
# Space: O(n! * n) for the visited set of intermediate strings
def k_similarity(self, s1: str, s2: str) -> int:
queue: deque[str] = deque([s1])
visited = {s1}
steps = 0
while queue:
for _ in range(len(queue)):
cur = queue.popleft()
if cur == s2:
return steps
i = 0
while cur[i] == s2[i]:
i += 1
chars = list(cur)
for j in range(i + 1, len(chars)):
if chars[j] == s2[i] and chars[j] != s2[j]:
chars[i], chars[j] = chars[j], chars[i]
nxt = "".join(chars)
if nxt not in visited:
visited.add(nxt)
queue.append(nxt)
chars[i], chars[j] = chars[j], chars[i]
steps += 1
return steps
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------- | ------------------------------------------------------ |
| O(n \* n! \* n) worst case, pruned heavily by only branching on the | O(n! \* n) for the visited set of intermediate strings |
## Tags
# The k-th Lexicographical String of All Happy
Source: https://leetcode-py.wisl.dev/problems/k-th-lexicographical-string-of-all-happy-strings-of-length-n
Tested Python solution for LeetCode 1415 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 1415, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/k-th-lexicographical-string-of-all-happy-strings-of-length-n/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1415 # by problem number
lcpy gen -s k_th_lexicographical_string_of_all_happy_strings_of_length_n # by problem name
```
## Problem
A **happy string** is a string that:
* consists only of letters of the set `['a', 'b', 'c']`.
* `s[i] != s[i + 1]` for all values of `i` from `1` to `s.length - 1` (string is 1-indexed).
For example, strings **"abc", "ac", "b"** and **"abcbabcbcb"** are all happy strings and strings **"aa", "baa"** and **"ababbc"** are not happy strings.
Given two integers `n` and `k`, consider a list of all happy strings of length `n` sorted in lexicographical order.
Return *the kth string* of this list or return an *empty string* if there are less than `k` happy strings of length `n`.
### Examples
```
Input: n = 1, k = 3
Output: "c"
Explanation: The list ["a", "b", "c"] contains all happy strings of length 1. The third string is "c".
```
```
Input: n = 1, k = 4
Output: ""
Explanation: There are only 3 happy strings of length 1.
```
```
Input: n = 3, k = 9
Output: "cab"
Explanation: There are 12 different happy strings of length 3 ["aba", "abc", "aca", "acb", "bab", "bac", "bca", "bcb", "cab", "cac", "cba", "cbc"]. You will find the 9th string = "cab".
```
### Constraints
* `1 <= n <= 10`
* `1 <= k <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_th_lexicographical_string_of_all_happy_strings_of_length_n/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_th_lexicographical_string_of_all_happy_strings_of_length_n/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def get_happy_string(self, n: int, k: int) -> str:
total = 3 << (n - 1)
if k > total:
return ""
k -= 1
result: list[str] = []
for i in range(n):
block = 1 << (n - 1 - i)
prev = result[-1] if result else ""
candidates = [c for c in "abc" if c != prev]
index, k = divmod(k, block)
result.append(candidates[index])
return "".join(result)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# K-th Smallest in Lexicographical Order
Source: https://leetcode-py.wisl.dev/problems/k-th-smallest-in-lexicographical-order
Tested Python solution for LeetCode 440 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 440, [Hard](/catalog/hard). Topics: [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/k-th-smallest-in-lexicographical-order/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 440 # by problem number
lcpy gen -s k_th_smallest_in_lexicographical_order # by problem name
```
## Problem
Given two integers `n` and `k`, return *the* `k^th` *lexicographically smallest integer in the range* `[1, n]`.
### Examples
```
Input: n = 13, k = 2
Output: 10
Explanation: The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], so the second smallest number is 10.
```
```
Input: n = 1, k = 1
Output: 1
```
### Constraints
* `1 <= k <= n <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_th_smallest_in_lexicographical_order/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_th_smallest_in_lexicographical_order/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log(n)^2)
# Space: O(1)
def find_kth_number(self, n: int, k: int) -> int:
curr = 1
k -= 1
while k:
steps = self._count_steps(n, curr)
if steps <= k:
# skip the whole subtree rooted at curr
curr += 1
k -= steps
else:
# descend into the subtree
curr *= 10
k -= 1
return curr
def _count_steps(self, n: int, prefix: int) -> int:
# count numbers in [1, n] starting with `prefix`
steps = 0
first = prefix
last = prefix
while first <= n:
steps += min(last, n) - first + 1
first *= 10
last = last * 10 + 9
return steps
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(log(n)^2) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# K-th Smallest Prime Fraction Python Solution
Source: https://leetcode-py.wisl.dev/problems/k-th-smallest-prime-fraction
Tested Python solution for LeetCode 786 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 786, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/k-th-smallest-prime-fraction/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 786 # by problem number
lcpy gen -s k_th_smallest_prime_fraction # by problem name
```
## Problem
You are given a sorted integer array `arr` containing `1` and **prime** numbers, where all the integers of `arr` are unique. You are also given an integer `k`.
For every `i` and `j` where `0 <= i < j < arr.length`, we consider the fraction `arr[i] / arr[j]`.
Return *the* `kth` *smallest fraction considered*. Return your answer as an array of integers of size `2`, where `answer[0] == arr[i]` and `answer[1] == arr[j]`.
### Examples
```
Input: arr = [1,2,3,5], k = 3
Output: [2,5]
Explanation: The fractions to be considered in sorted order are:
1/5, 1/3, 2/5, 1/2, 3/5, and 2/3.
The third fraction is 2/5.
```
```
Input: arr = [1,7], k = 1
Output: [1,7]
```
### Constraints
* 2 \<= arr.length \<= 1000
* 1 \<= arr\[i] \<= 3 \* 10^4
* arr\[0] == 1
* arr\[i] is a prime number for i > 0.
* All the numbers of arr are unique and sorted in strictly increasing order.
* 1 \<= k \<= arr.length \* (arr.length - 1) / 2
**Follow up:** Can you solve the problem with better than O(n^2) complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_th_smallest_prime_fraction/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/k_th_smallest_prime_fraction/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from fractions import Fraction
class Solution:
# Time: O(n * log(1/gap)) where gap is the smallest difference between two
# distinct fractions (>= 1 / (3 * 10^4)^2), so ~31 counting passes.
# Space: O(1)
def kth_smallest_prime_fraction(self, arr: list[int], k: int) -> list[int]:
n = len(arr)
lo, hi = Fraction(0), Fraction(1)
# Smallest gap between two distinct fractions a/b and c/d (values <= 3 * 10^4)
# is >= 1 / (3 * 10^4)^2, so once the bracket is narrower the answer fraction
# is isolated and the best fraction below `hi` is exactly the k-th smallest.
limit = Fraction(1, 9 * 10**8)
best = [arr[0], arr[-1]]
while hi - lo >= limit:
mid = (lo + hi) / 2
count = 0
i = 0
num, den = 0, 1
for j in range(1, n):
while arr[i] * mid.denominator < arr[j] * mid.numerator:
i += 1
count += i
if i > 0 and num * arr[j] < arr[i - 1] * den:
num, den = arr[i - 1], arr[j]
if count < k:
lo = mid
else:
hi = mid
best = [num, den]
return best
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------- | ----- |
| O(n \* log(1/gap)) where gap is the smallest difference between two | O(1) |
## Tags
# Keyboard Row Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/keyboard-row
Tested Python solution for LeetCode 500 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 500, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/keyboard-row/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 500 # by problem number
lcpy gen -s keyboard_row # by problem name
```
## Problem
Given an array of strings `words`, return the words that can be typed using letters of the alphabet on only one row of American keyboard like the image below.
Note that the strings are **case-insensitive**, both lowercased and uppercased of the same letter are treated as if they are at the same row.
In the American keyboard:
* the first row consists of the characters `qwertyuiop`,
* the second row consists of the characters `asdfghjkl`, and
* the third row consists of the characters `zxcvbnm`.

### Examples
```
Input: words = ["Hello","Alaska","Dad","Peace"]
Output: ["Alaska","Dad"]
Explanation: Both "a" and "A" are in the 2nd row of the American keyboard due to case insensitivity.
```
```
Input: words = ["omk"]
Output: []
```
```
Input: words = ["adsdf","sfd"]
Output: ["adsdf","sfd"]
```
### Constraints
* 1 \<= words.length \<= 20
* 1 \<= words\[i].length \<= 100
* words\[i] consists of English letters (both lowercase and uppercase).
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/keyboard_row/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/keyboard_row/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m) where n = len(words), m = max word length
# Space: O(1) (row sets are constant size)
def find_words(self, words: list[str]) -> list[str]:
rows = [set("qwertyuiop"), set("asdfghjkl"), set("zxcvbnm")]
return [word for word in words if any(set(word.lower()) <= row for row in rows)]
```
## Complexity
| Time | Space |
| --------------------------------------------------- | --------------------------------- |
| O(n \* m) where n = len(words), m = max word length | O(1) (row sets are constant size) |
## Tags
# Keys and Rooms Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/keys-and-rooms
Tested Python solution for LeetCode 841 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 841, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/keys-and-rooms/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 841 # by problem number
lcpy gen -s keys_and_rooms # by problem name
```
## Problem
There are `n` rooms labeled from `0` to `n - 1` and all the rooms are locked except for room `0`. Your goal is to visit all the rooms. However, you cannot enter a locked room without having its key.
When you visit a room, you may find a set of **distinct keys** in it. Each key has a number on it, denoting which room it unlocks, and you can take all of them with you to unlock the other rooms.
Given an array `rooms` where `rooms[i]` is the set of keys that you can obtain if you visited room `i`, return `true` if you can visit **all** the rooms, or `false` otherwise.
### Examples
```
Input: rooms = [[1],[2],[3],[]]
Output: true
Explanation:
We visit room 0 and pick up key 1.
We then visit room 1 and pick up key 2.
We then visit room 2 and pick up key 3.
We then visit room 3.
Since we were able to visit every room, we return true.
```
```
Input: rooms = [[1,3],[3,0,1],[2],[0]]
Output: false
Explanation: We can not enter room number 2 since the only key that unlocks it is in that room.
```
### Constraints
* n == rooms.length
* 2 \<= n \<= 1000
* 0 \<= rooms\[i].length \<= 1000
* 1 \<= sum(rooms\[i].length) \<= 3000
* 0 \<= rooms\[i]\[j] \< n
* All the values of rooms\[i] are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/keys_and_rooms/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/keys_and_rooms/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + k) where k is the total number of keys
# Space: O(n)
def can_visit_all_rooms(self, rooms: list[list[int]]) -> bool:
visited = {0}
stack = [0]
while stack:
room = stack.pop()
for key in rooms[room]:
if key not in visited:
visited.add(key)
stack.append(key)
return len(visited) == len(rooms)
```
## Complexity
| Time | Space |
| -------------------------------------------- | ----- |
| O(n + k) where k is the total number of keys | O(n) |
## Tags
# Kill Process Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/kill-process
Tested Python solution for LeetCode 582 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 582, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/kill-process/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 582 # by problem number
lcpy gen -s kill_process # by problem name
```
## Problem
You have `n` processes forming a rooted tree structure. You are given two integer arrays `pid` and `ppid`, where `pid[i]` is the ID of the `i^th` process and `ppid[i]` is the ID of the `i^th` process's parent process.
Each process has only **one parent process** but may have multiple children processes. Only one process has `ppid[i] = 0`, which means this process has **no parent process** (the root of the tree).
When a process is **killed**, all of its children processes will also be killed.
Given an integer `kill` representing the ID of a process you want to kill, return a list of the IDs of the processes that will be killed. You may return the answer in **any order**.
### Examples

```
Input: pid = [1,3,10,5], ppid = [3,0,5,3], kill = 5
Output: [5,10]
Explanation: The processes colored in red are the processes that should be killed.
```
```
Input: pid = [1], ppid = [0], kill = 1
Output: [1]
```
### Constraints
* `n == pid.length`
* `n == ppid.length`
* `1 <= n <= 5 * 10^4`
* `1 <= pid[i] <= 5 * 10^4`
* `0 <= ppid[i] <= 5 * 10^4`
* Only one process has no parent.
* All the values of `pid` are **unique**.
* `kill` is **guaranteed** to be in `pid`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kill_process/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kill_process/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def kill_process(self, pid: list[int], ppid: list[int], kill: int) -> list[int]:
children: dict[int, list[int]] = {}
for child, parent in zip(pid, ppid, strict=True):
children.setdefault(parent, []).append(child)
killed: list[int] = []
stack = [kill]
while stack:
cur = stack.pop()
killed.append(cur)
stack.extend(children.get(cur, []))
return killed
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Knight Dialer Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/knight-dialer
Tested Python solution for LeetCode 935 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 935, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/knight-dialer/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 935 # by problem number
lcpy gen -s knight_dialer # by problem name
```
## Problem
\The chess knight has a \unique movement\ ,it may move two squares vertically and one square horizontally, or two squares horizontally and one square vertically (with both forming the shape of an \L\). The possible movements of chess knight are shown in this diagram:\
\A chess knight can move as indicated in the chess diagram below:\
\We have a chess knight and a phone pad as shown below, the knight can only stand on a numeric cell (i.e. blue cell).\
\\
\
\
\
Given an integer \n\, return how many distinct phone numbers of length \n\ we can dial.\
You are allowed to place the knight on any numeric cell initially and then you should perform \n - 1\ jumps to dial a number of length \n\. All jumps should be valid knight jumps.\
As the answer may be very large, return the answer modulo \10\9\ + 7\.\
arr\, and an integer \k\, return \the \\k\th\\\ \distinct string\ present in \\arr\. If there are \fewer\ than \k\ distinct strings, return \an \empty string \\\""\.
Note that the strings are considered in the \order in which they appear\ in the array.
### Examples
```
Input: arr = ["d","b","c","b","c","a"], k = 2
Output: "a"
Explanation:
The only distinct strings in arr are "d" and "a".
"d" appears 1st, so it is the 1st distinct string.
"a" appears 2nd, so it is the 2nd distinct string.
Since k == 2, "a" is returned.
```
```
Input: arr = ["aaa","aa","a"], k = 1
Output: "aaa"
Explanation:
All strings in arr are distinct, so the 1st string "aaa" is returned.
```
```
Input: arr = ["a","b","a"], k = 3
Output: ""
Explanation:
The only distinct string is "b". Since there are fewer than 3 distinct strings, we return an empty string "".
```
### Constraints
* `1 <= k <= arr.length <= 1000`
* `1 <= arr[i].length <= 5`
* `arr[i]` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_distinct_string_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_distinct_string_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(n)
def kth_distinct(self, arr: list[str], k: int) -> str:
counts = Counter(arr)
for s in arr:
if counts[s] == 1:
k -= 1
if k == 0:
return s
return ""
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Kth Largest Element in a Stream
Source: https://leetcode-py.wisl.dev/problems/kth-largest-element-in-a-stream
Tested Python solution for LeetCode 703 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 703, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Design](/catalog/topics/design), [Binary Search Tree](/catalog/topics/binary-search-tree), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Binary Tree](/catalog/topics/binary-tree), [Data Stream](/catalog/topics/data-stream). [View on LeetCode](https://leetcode.com/problems/kth-largest-element-in-a-stream/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 703 # by problem number
lcpy gen -s kth_largest_element_in_a_stream # by problem name
```
## Problem
You are part of a university admissions office and need to keep track of the `kth` highest test score from applicants in real-time. This helps to determine cut-off marks for interviews and admissions dynamically as new applicants submit their scores.
You are tasked to implement a class which, for a given integer `k`, maintains a stream of test scores and continuously returns the `k`th highest test score **after** a new score has been submitted. More specifically, we are looking for the `k`th highest score in the sorted list of all scores.
Implement the `KthLargest` class:
* `KthLargest(int k, int[] nums)` Initializes the object with the integer `k` and the stream of test scores `nums`.
* `int add(int val)` Adds a new test score `val` to the stream and returns the element representing the `kth` largest element in the pool of test scores so far.
### Examples
```
Input
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
Output
[null, 4, 5, 5, 8, 8]
Explanation
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4
kthLargest.add(5); // return 5
kthLargest.add(10); // return 5
kthLargest.add(9); // return 8
kthLargest.add(4); // return 8
```
```
Input
["KthLargest", "add", "add", "add", "add"]
[[4, [7, 7, 7, 7, 8, 3]], [2], [10], [9], [9]]
Output
[null, 7, 7, 7, 8]
Explanation
KthLargest kthLargest = new KthLargest(4, [7, 7, 7, 7, 8, 3]);
kthLargest.add(2); // return 7
kthLargest.add(10); // return 7
kthLargest.add(9); // return 7
kthLargest.add(9); // return 8
```
### Constraints
* 0 \<= nums.length \<= 10\4\
* 1 \<= k \<= nums.length + 1
* -10\4\ \<= nums\[i] \<= 10\4\
* -10\4\ \<= val \<= 10\4\
* At most 10\4\ calls will be made to `add`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_element_in_a_stream/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_element_in_a_stream/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class KthLargest:
# Time: O(n log k) init, O(log k) per add
# Space: O(k)
def __init__(self, k: int, nums: list[int]) -> None:
self.k = k
self.min_heap: list[int] = []
for num in nums:
self.add(num)
# Time: O(log k)
# Space: O(k)
def add(self, val: int) -> int:
heapq.heappush(self.min_heap, val)
if len(self.min_heap) > self.k:
heapq.heappop(self.min_heap)
# kth largest is the smallest among the k largest elements
return self.min_heap[0]
```
## Complexity
| Time | Space |
| --------------------------------- | ----- |
| O(n log k) init, O(log k) per add | O(k) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Kth Largest Element in an Array
Source: https://leetcode-py.wisl.dev/problems/kth-largest-element-in-an-array
Tested Python solution for LeetCode 215 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 215, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), Quickselect. [View on LeetCode](https://leetcode.com/problems/kth-largest-element-in-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 215 # by problem number
lcpy gen -s kth_largest_element_in_an_array # by problem name
```
## Problem
Given an integer array `nums` and an integer `k`, return *the* `kth` *largest element in the array*.
Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.
Can you solve it without sorting?
### Examples
```
Input: nums = [3,2,1,5,6,4], k = 2
Output: 5
```
```
Input: nums = [3,2,3,1,2,4,5,5,6], k = 4
Output: 4
```
### Constraints
* 1 \<= k \<= nums.length \<= 10^5
* -10^4 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_element_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_element_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) average, O(n^2) worst
# Space: O(1)
def find_kth_largest(self, nums: list[int], k: int) -> int:
target_index = len(nums) - k
def quickselect(left: int, right: int) -> int:
pivot = nums[right]
store = left
for i in range(left, right):
if nums[i] <= pivot:
nums[store], nums[i] = nums[i], nums[store]
store += 1
nums[store], nums[right] = nums[right], nums[store]
if store == target_index:
return nums[store]
if store < target_index:
return quickselect(store + 1, right)
return quickselect(left, store - 1)
return quickselect(0, len(nums) - 1)
```
## Complexity
| Time | Space |
| -------------------------- | ----- |
| O(n) average, O(n^2) worst | O(1) |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Find the Kth Largest Integer in the Array
Source: https://leetcode-py.wisl.dev/problems/kth-largest-number-in-array
Tested Python solution for LeetCode 1985 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1985, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), Quickselect. [View on LeetCode](https://leetcode.com/problems/kth-largest-number-in-array/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1985 # by problem number
lcpy gen -s kth_largest_number_in_array # by problem name
```
## Problem
You are given an array of strings `nums` and an integer `k`. Each string in `nums` represents an integer without leading zeros.
Return the string that represents the `kth` largest integer in `nums`.
**Note**: Duplicate numbers should be counted distinctly. For example, if `nums` is `["1","2","2"]`, `"2"` is the first largest integer, `"2"` is the second-largest integer, and `"1"` is the third-largest integer.
### Examples
```
Input: nums = ["3","6","7","10"], k = 4
Output: "3"
Explanation: The numbers in nums sorted in non-decreasing order are ["3","6","7","10"]. The 4th largest integer in nums is "3".
```
```
Input: nums = ["2","21","12","1"], k = 3
Output: "2"
Explanation: The numbers in nums sorted in non-decreasing order are ["1","2","12","21"]. The 3rd largest integer in nums is "2".
```
```
Input: nums = ["0","0"], k = 2
Output: "0"
Explanation: The numbers in nums sorted in non-decreasing order are ["0","0"]. The 2nd largest integer in nums is "0".
```
### Constraints
* 1 \<= k \<= nums.length \<= 10^4
* 1 \<= nums\[i].length \<= 100
* nums\[i] consists of only digits.
* nums\[i] will not have any leading zeros.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_number_in_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_number_in_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log k)
# Space: O(k)
def kth_largest_number(self, nums: list[str], k: int) -> str:
heap: list[tuple[int, str]] = []
for num in nums:
key = (len(num), num)
if len(heap) < k:
heapq.heappush(heap, key)
elif key > heap[0]:
heapq.heapreplace(heap, key)
return heap[0][1]
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log k) | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Kth Largest Sum in a Binary Tree
Source: https://leetcode-py.wisl.dev/problems/kth-largest-sum-in-a-binary-tree
Tested Python solution for LeetCode 2583 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2583, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Breadth-First Search](/catalog/topics/breadth-first-search), [Sorting](/catalog/topics/sorting), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/kth-largest-sum-in-a-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2583 # by problem number
lcpy gen -s kth_largest_sum_in_a_binary_tree # by problem name
```
## Problem
You are given the `root` of a binary tree and a positive integer `k`.
The **level sum** in the tree is the sum of the values of the nodes that are on the **same** level.
Return *the* `kth` *largest level sum in the tree (not necessarily distinct)*. If there are fewer than `k` levels in the tree, return `-1`.
Note that two nodes are on the same level if they have the same distance from the root.
### Examples

```
Input: root = [5,8,9,2,1,3,7,4,6], k = 2
Output: 13
Explanation: The level sums are the following:
- Level 1: 5.
- Level 2: 8 + 9 = 17.
- Level 3: 2 + 1 + 3 + 7 = 13.
- Level 4: 4 + 6 = 10.
The 2nd largest level sum is 13.
```

```
Input: root = [1,2,null,3], k = 1
Output: 3
Explanation: The largest level sum is 3.
```
### Constraints
* The number of nodes in the tree is `n`.
* `2 <= n <= 10^5`
* `1 <= Node.val <= 10^6`
* `1 <= k <= n`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_sum_in_a_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_largest_sum_in_a_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(w)
def kth_largest_level_sum(self, root: TreeNode[int] | None, k: int) -> int:
sums: list[int] = []
queue = deque([root] if root is not None else [])
while queue:
level_sum = 0
for _ in range(len(queue)):
node = queue.popleft()
level_sum += node.val
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
sums.append(level_sum)
if k > len(sums):
return -1
sums.sort(reverse=True)
return sums[k - 1]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(w) |
## Tags
[NeetCode All](/catalog/neetcode).
# Kth Smallest Element in a BST Python Solution
Source: https://leetcode-py.wisl.dev/problems/kth-smallest-element-in-a-bst
Tested Python solution for LeetCode 230 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 230, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 230 # by problem number
lcpy gen -s kth_smallest_element_in_a_bst # by problem name
```
## Problem
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.
### Examples

```
Input: root = [3,1,4,null,2], k = 1
Output: 1
```

```
Input: root = [5,3,6,2,4,null,null,1], k = 3
Output: 3
```
### Constraints
* The number of nodes in the tree is `n`.
* `1 <= k <= n <= 10^4`
* `0 <= Node.val <= 10^4`
**Follow up:** If 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?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_element_in_a_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_element_in_a_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Inorder Recursive
# Time: O(k)
# Space: O(h)
def kth_smallest(self, root: TreeNode[int] | None, k: int) -> int:
def inorder(node: TreeNode[int] | None):
if not node:
return
yield from inorder(node.left)
yield node.val
yield from inorder(node.right)
for i, val in enumerate(inorder(root)):
if i == k - 1:
return val
raise ValueError(f"Tree has fewer than {k} nodes")
# Binary Tree Traversal Patterns
#
# def inorder(node):
# if node:
# inorder(node.left)
# print(node.val)
# inorder(node.right)
#
# def preorder(node):
# if node:
# print(node.val)
# preorder(node.left)
# preorder(node.right)
#
# def postorder(node):
# if node:
# postorder(node.left)
# postorder(node.right)
# print(node.val)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(k) | O(h) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Kth Smallest Element in a Sorted Matrix
Source: https://leetcode-py.wisl.dev/problems/kth-smallest-element-in-a-sorted-matrix
Tested Python solution for LeetCode 378 with 33 pytest cases. Generate a practice environment with lcpy.
LeetCode 378, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 33 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 378 # by problem number
lcpy gen -s kth_smallest_element_in_a_sorted_matrix # by problem name
```
## Problem
Given an `n x n` matrix where each of the rows and columns is sorted in ascending order, return the kth smallest element in the matrix.
Note that it is the kth smallest element in the sorted order, not the kth distinct element.
You must find a solution with a memory complexity better than O(n2).
### Examples
```
Input: matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
Output: 13
Explanation: The elements in the matrix are [1,5,9,10,11,12,13,13,15], and the 8th smallest number is 13
```
```
Input: matrix = [[-5]], k = 1
Output: -5
```
### Constraints
* n == matrix.length == matrix\[i].length
* 1 \<= n \<= 300
* -10^9 \<= matrix\[i]\[j] \<= 10^9
* All the rows and columns of matrix are guaranteed to be sorted in non-decreasing order.
* 1 \<= k \<= n2
**Follow up:**
* Could you solve the problem with a constant memory (i.e., O(1) memory complexity)?
* Could you solve the problem in O(n) time complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_element_in_a_sorted_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_element_in_a_sorted_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * log(max - min))
# Space: O(1)
def kth_smallest(self, matrix: list[list[int]], k: int) -> int:
def count_at_most(target: int) -> int:
count = 0
row, col = len(matrix) - 1, 0
while row >= 0 and col < len(matrix):
if matrix[row][col] <= target:
count += row + 1
col += 1
else:
row -= 1
return count
lo, hi = matrix[0][0], matrix[-1][-1]
while lo < hi:
mid = lo + (hi - lo) // 2
if count_at_most(mid) < k:
lo = mid + 1
else:
hi = mid
return lo
```
## Complexity
| Time | Space |
| ---------------------- | ----- |
| O(n \* log(max - min)) | O(1) |
## Tags
# Kth Smallest Number in Multiplication Table
Source: https://leetcode-py.wisl.dev/problems/kth-smallest-number-in-multiplication-table
Tested Python solution for LeetCode 668 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 668, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/kth-smallest-number-in-multiplication-table/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 668 # by problem number
lcpy gen -s kth_smallest_number_in_multiplication_table # by problem name
```
## Problem
Nearly everyone has used the [Multiplication Table](https://en.wikipedia.org/wiki/Multiplication_table). The multiplication table of size `m x n` is an integer matrix `mat` where `mat[i][j] == i * j` (1-indexed).
Given three integers `m`, `n`, and `k`, return the kth smallest element in the `m x n` multiplication table.
### Examples

```
Input: m = 3, n = 3, k = 5
Output: 3
Explanation: The 5th smallest number is 3.
```

```
Input: m = 2, n = 3, k = 6
Output: 6
Explanation: The 6th smallest number is 6.
```
### Constraints
* 1 \<= m, n \<= 3 \* 10^4
* 1 \<= k \<= m \* n
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_number_in_multiplication_table/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_number_in_multiplication_table/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * log(m * n))
# Space: O(1)
def find_kth_number(self, m: int, n: int, k: int) -> int:
# Ensure the per-row count loop iterates over the smaller dimension.
if m > n:
m, n = n, m
def count_le(x: int) -> int:
return sum(min(x // i, n) for i in range(1, m + 1))
lo, hi = 1, m * n
while lo < hi:
mid = (lo + hi) // 2
if count_le(mid) < k:
lo = mid + 1
else:
hi = mid
return lo
```
## Complexity
| Time | Space |
| ------------------- | ----- |
| O(m \* log(m \* n)) | O(1) |
## Tags
# Kth Smallest Product of Two Sorted Arrays
Source: https://leetcode-py.wisl.dev/problems/kth-smallest-product-of-two-sorted-arrays
Tested Python solution for LeetCode 2040 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2040, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/kth-smallest-product-of-two-sorted-arrays/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2040 # by problem number
lcpy gen -s kth_smallest_product_of_two_sorted_arrays # by problem name
```
## Problem
Given two **sorted 0-indexed** integer arrays `nums1` and `nums2` as well as an integer `k`, return the `kth` (**1-based**) smallest product of `nums1[i] * nums2[j]` where `0 <= i < nums1.length` and `0 <= j < nums2.length`.
### Examples
```
Input: nums1 = [2,5], nums2 = [3,4], k = 2
Output: 8
Explanation: The 2 smallest products are:
- nums1[0] * nums2[0] = 2 * 3 = 6
- nums1[0] * nums2[1] = 2 * 4 = 8
The 2nd smallest product is 8.
```
```
Input: nums1 = [-4,-2,0,3], nums2 = [2,4], k = 6
Output: 0
Explanation: The 6 smallest products are:
- nums1[0] * nums2[1] = (-4) * 4 = -16
- nums1[0] * nums2[0] = (-4) * 2 = -8
- nums1[1] * nums2[1] = (-2) * 4 = -8
- nums1[1] * nums2[0] = (-2) * 2 = -4
- nums1[2] * nums2[0] = 0 * 2 = 0
- nums1[2] * nums2[1] = 0 * 4 = 0
The 6th smallest product is 0.
```
```
Input: nums1 = [-2,-1,0,1,2], nums2 = [-3,-1,2,4,5], k = 3
Output: -6
Explanation: The 3 smallest products are:
- nums1[0] * nums2[4] = (-2) * 5 = -10
- nums1[0] * nums2[3] = (-2) * 4 = -8
- nums1[4] * nums2[0] = 2 * (-3) = -6
The 3rd smallest product is -6.
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 5 \* 10^4
* -10^5 \<= nums1\[i], nums2\[j] \<= 10^5
* 1 \<= k \<= nums1.length \* nums2.length
* nums1 and nums2 are sorted.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_product_of_two_sorted_arrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_smallest_product_of_two_sorted_arrays/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_left, bisect_right
class Solution:
# Time: O((len(nums1) + len(nums2)) * log(len(nums2)) * log(max_product))
# Space: O(1)
def kth_smallest_product(self, nums1: list[int], nums2: list[int], k: int) -> int:
def count_at_most(target: int) -> int:
total = 0
for a in nums1:
if a == 0:
if target >= 0:
total += len(nums2)
elif a > 0:
total += bisect_right(nums2, target // a)
else:
total += len(nums2) - bisect_left(nums2, -(target // -a))
return total
low, high = -(10**10), 10**10
while low < high:
mid = (low + high) // 2
if count_at_most(mid) >= k:
high = mid
else:
low = mid + 1
return low
```
## Complexity
| Time | Space |
| -------------------------------------------------------------------- | ----- |
| O((len(nums1) + len(nums2)) \* log(len(nums2)) \* log(max\_product)) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# K-th Symbol in Grammar Python Solution
Source: https://leetcode-py.wisl.dev/problems/kth-symbol-in-grammar
Tested Python solution for LeetCode 779 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 779, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/kth-symbol-in-grammar/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 779 # by problem number
lcpy gen -s kth_symbol_in_grammar # by problem name
```
## Problem
We build a table of `n` rows (1-indexed). We start by writing `0` in the `1st` row. Now in every subsequent row, we look at the previous row and replace each occurrence of `0` with `01`, and each occurrence of `1` with `10`.
* For example, for `n = 3`, the `1st` row is `0`, the `2nd` row is `01`, and the `3rd` row is `0110`.
Given two integer `n` and `k`, return *the* `kth` *(1-indexed) symbol in the* `nth` *row* of a table of `n` rows.
### Examples
```
Input: n = 1, k = 1
Output: 0
Explanation: row 1: 0
```
```
Input: n = 2, k = 1
Output: 0
Explanation:
row 1: 0
row 2: 01
```
```
Input: n = 2, k = 2
Output: 1
Explanation:
row 1: 0
row 2: 01
```
### Constraints
* 1 \<= n \<= 30
* 1 \<= k \<= 2n - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_symbol_in_grammar/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/kth_symbol_in_grammar/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def kth_grammar(self, n: int, k: int) -> int:
# kth symbol = parity of set bits in k - 1
return (k - 1).bit_count() % 2
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest 3-Same-Digit Number in String
Source: https://leetcode-py.wisl.dev/problems/largest-3-same-digit-number-in-string
Tested Python solution for LeetCode 2264 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2264, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/largest-3-same-digit-number-in-string/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2264 # by problem number
lcpy gen -s largest_3_same_digit_number_in_string # by problem name
```
## Problem
You are given a string `num` representing a large integer. An integer is **good** if it meets the following conditions:
* It is a **substring** of `num` with length `3`.
* It consists of only one unique digit.
Return *the **maximum good** integer as a **string** or an empty string* `""` *if no such integer exists*.
**Note:**
* A **substring** is a contiguous sequence of characters within a string.
* There may be **leading zeroes** in `num` or a good integer.
### Examples
```
Input: num = "6777133339"
Output: "777"
Explanation: There are two distinct good integers: "777" and "333". "777" is the largest, so we return "777".
```
```
Input: num = "2300019"
Output: "000"
Explanation: "000" is the only good integer.
```
```
Input: num = "42352338"
Output: ""
Explanation: No substring of length 3 consists of only one unique digit. Therefore, there are no good integers.
```
### Constraints
* 3 \<= num.length \<= 1000
* num only consists of digits.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_3_same_digit_number_in_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_3_same_digit_number_in_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def largest_good_integer(self, num: str) -> str:
best = ""
for i in range(len(num) - 2):
if num[i] == num[i + 1] == num[i + 2] and num[i] * 3 > best:
best = num[i] * 3
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest BST Subtree Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/largest-bst-subtree
Tested Python solution for LeetCode 333 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 333, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Dynamic Programming](/catalog/topics/dynamic-programming), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/largest-bst-subtree/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 333 # by problem number
lcpy gen -s largest_bst_subtree # by problem name
```
## Problem
Given the root of a binary tree, find the largest subtree, which is also a Binary Search Tree (BST), where the largest means subtree has the largest number of nodes.
A **Binary Search Tree (BST)** is a tree in which all the nodes follow the below-mentioned properties:
* The left subtree values are less than the value of their parent (root) node's value.
* The right subtree values are greater than the value of their parent (root) node's value.
**Note:** A subtree must include all of its descendants.
### Examples

```
Input: root = [10,5,15,1,8,null,7]
Output: 3
Explanation: The Largest BST Subtree in this case is the highlighted one. The return value is the subtree's size, which is 3.
```
```
Input: root = [4,2,7,2,3,5,null,2,null,null,null,null,null,1]
Output: 2
```
### Constraints
* The number of nodes in the tree is in the range `[0, 10^4]`.
* `-10^4 <= Node.val <= 10^4`
**Follow up:** Can you figure out ways to solve it with `O(n)` time complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_bst_subtree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_bst_subtree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) — post-order pass carrying (is_bst, size, min, max)
# Space: O(h) — recursion depth equals tree height
def largest_bst_subtree(self, root: TreeNode[int] | None) -> int:
def dfs(node: TreeNode[int] | None) -> tuple[bool, int, int | None, int | None]:
if node is None:
return True, 0, None, None
left_bst, left_size, left_min, left_max = dfs(node.left)
right_bst, right_size, right_min, right_max = dfs(node.right)
if (
left_bst
and right_bst
and (left_max is None or left_max < node.val)
and (right_min is None or right_min > node.val)
):
return (
True,
1 + left_size + right_size,
left_min if left_min is not None else node.val,
right_max if right_max is not None else node.val,
)
return False, max(left_size, right_size), None, None
return dfs(root)[1]
```
## Complexity
| Time | Space |
| --------------------------------------------------------- | ----------------------------------------- |
| O(n) — post-order pass carrying (is\_bst, size, min, max) | O(h) — recursion depth equals tree height |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Color Value in a Directed Graph
Source: https://leetcode-py.wisl.dev/problems/largest-color-value-in-a-directed-graph
Tested Python solution for LeetCode 1857 with 27 pytest cases. Generate a practice environment with lcpy.
LeetCode 1857, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), [Memoization](/catalog/topics/memoization), [Counting](/catalog/topics/counting), Directed Acyclic Graph. [View on LeetCode](https://leetcode.com/problems/largest-color-value-in-a-directed-graph/description/).
Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1857 # by problem number
lcpy gen -s largest_color_value_in_a_directed_graph # by problem name
```
## Problem
There is a \directed graph\ of \n\ colored nodes and \m\ edges. The nodes are numbered from \0\ to \n - 1\.
You are given a string \colors\ where \colors\[i]\ is a lowercase English letter representing the \color\ of the \i\th\\ node in this graph (\0-indexed\). You are also given a 2D array \edges\ where \edges\[j] = \[a\j\, b\j\]\ indicates that there is a \directed edge\ from node \a\j\\ to node \b\j\\.
A valid \path\ in the graph is a sequence of nodes \x\1\ -> x\2\ -> x\3\ -> ... -> x\k\\ such that there is a directed edge from \x\i\\ to \x\i+1\\ for every \1 \<= i \< k\. The \color value\ of the path is the number of nodes that are colored the \most frequently\ occurring color along that path.
Return \the \largest color value\ of any valid path in the given graph, or \\-1\\ if the graph contains a cycle\.
### Examples

```
Input: colors = "abaca", edges = [[0,1],[0,2],[2,3],[3,4]]
Output: 3
```
**Explanation:** The path 0 -> 2 -> 3 -> 4 contains 3 nodes that are colored `"a" (red in the above image)`.

```
Input: colors = "a", edges = [[0,0]]
Output: -1
```
**Explanation:** There is a cycle from 0 to 0.
### Constraints
* `n == colors.length`
* `m == edges.length`
* `1 <= n <= 10^5`
* `0 <= m <= 10^5`
* `colors` consists of lowercase English letters.
* `0 <= aj, bj < n`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_color_value_in_a_directed_graph/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_color_value_in_a_directed_graph/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m) with a constant factor of 26 colors
# Space: O(n)
def largest_path_value(self, colors: str, edges: list[list[int]]) -> int:
n = len(colors)
adj: list[list[int]] = [[] for _ in range(n)]
indegree = [0] * n
for src, dst in edges:
adj[src].append(dst)
indegree[dst] += 1
counts = [[0] * 26 for _ in range(n)]
for node in range(n):
counts[node][ord(colors[node]) - 97] = 1
queue = [node for node in range(n) if indegree[node] == 0]
processed = 0
best = 0
while queue:
node = queue.pop()
processed += 1
node_counts = counts[node]
local_best = max(node_counts)
if local_best > best:
best = local_best
for nxt in adj[node]:
nxt_counts = counts[nxt]
nxt_color = ord(colors[nxt]) - 97
for c in range(26):
cand = node_counts[c] + (1 if c == nxt_color else 0)
if cand > nxt_counts[c]:
nxt_counts[c] = cand
indegree[nxt] -= 1
if indegree[nxt] == 0:
queue.append(nxt)
return best if processed == n else -1
```
## Complexity
| Time | Space |
| -------------------------------------------- | ----- |
| O(n + m) with a constant factor of 26 colors | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Combination With Bitwise AND Greater
Source: https://leetcode-py.wisl.dev/problems/largest-combination-with-bitwise-and-greater-than-zero
Tested Python solution for LeetCode 2275 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 2275, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Bit Manipulation](/catalog/topics/bit-manipulation), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/largest-combination-with-bitwise-and-greater-than-zero/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2275 # by problem number
lcpy gen -s largest_combination_with_bitwise_and_greater_than_zero # by problem name
```
## Problem
The **bitwise AND** of an array `nums` is the bitwise AND of all integers in `nums`.
* For example, for `nums = [1, 5, 3]`, the bitwise AND is equal to `1 & 5 & 3 = 1`.
* Also, for `nums = [7]`, the bitwise AND is `7`.
You are given an array of positive integers `candidates`. Compute the **bitwise AND** for all possible **combinations** of elements in the `candidates` array.
Return *the size of the **largest** combination of* `candidates` *with a bitwise AND* ***greater*** *than* `0`.
### Examples
```
Input: candidates = [16,17,71,62,12,24,14]
Output: 4
```
**Explanation:** The combination `[16,17,62,24]` has a bitwise AND of `16 & 17 & 62 & 24 = 16 > 0`. The size of the combination is 4.
It can be shown that no combination with a size greater than 4 has a bitwise AND greater than 0. Note that more than one combination may have the largest size.
For example, the combination `[62,12,24,14]` has a bitwise AND of `62 & 12 & 24 & 14 = 8 > 0`.
```
Input: candidates = [8,8]
Output: 2
```
**Explanation:** The largest combination `[8,8]` has a bitwise AND of `8 & 8 = 8 > 0`. The size of the combination is 2, so we return 2.
### Constraints
* `1 <= candidates.length <= 10^5`
* `1 <= candidates[i] <= 10^7`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_combination_with_bitwise_and_greater_than_zero/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_combination_with_bitwise_and_greater_than_zero/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * b) where b is the bit width of the largest value (<= 24)
# Space: O(1)
def largest_combination(self, candidates: list[int]) -> int:
best = 0
for bit in range(24):
count = 0
for value in candidates:
count += (value >> bit) & 1
best = max(best, count)
return best
```
## Complexity
| Time | Space |
| ---------------------------------------------------------------- | ----- |
| O(n \* b) where b is the bit width of the largest value (\<= 24) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Component Size by Common Factor
Source: https://leetcode-py.wisl.dev/problems/largest-component-size-by-common-factor
Tested Python solution for LeetCode 952 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 952, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Union-Find](/catalog/topics/union-find), [Number Theory](/catalog/topics/number-theory), Prime Factorization. [View on LeetCode](https://leetcode.com/problems/largest-component-size-by-common-factor/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 952 # by problem number
lcpy gen -s largest_component_size_by_common_factor # by problem name
```
## Problem
Given an integer array of unique positive integers `nums`. Consider the following graph:
* There are `nums.length` nodes, labeled `nums[0]` to `nums[nums.length - 1]`,
* There is an undirected edge between `nums[i]` and `nums[j]` if `nums[i]` and `nums[j]` share a common factor greater than `1`.
Return the size of the largest connected component in the graph.
### Examples

```
Input: nums = [4,6,15,35]
Output: 4
```

```
Input: nums = [20,50,9,63]
Output: 2
```

```
Input: nums = [2,3,6,7,4,12,21,39]
Output: 8
```
### Constraints
* 1 \<= nums.length \<= 2 \* 10^4
* 1 \<= nums\[i] \<= 10^5
* All the values of nums are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_component_size_by_common_factor/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_component_size_by_common_factor/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * sqrt(max(nums)) * alpha(n))
# Space: O(max(nums))
def largest_component_size(self, nums: list[int]) -> int:
parent: dict[int, int] = {}
def find(x: int) -> int:
root = x
while parent[root] != root:
root = parent[root]
while parent[x] != root:
parent[x], x = root, parent[x]
return root
def union(a: int, b: int) -> None:
if b not in parent:
parent[b] = b
root_a, root_b = find(a), find(b)
if root_a != root_b:
parent[root_a] = root_b
for num in nums:
parent[num] = num
for num in nums:
reduced = num
factor = 2
while factor * factor <= reduced:
if reduced % factor == 0:
union(num, factor)
while reduced % factor == 0:
reduced //= factor
factor += 1
if reduced > 1:
union(num, reduced)
sizes: dict[int, int] = {}
largest = 0
for num in nums:
root = find(num)
sizes[root] = sizes.get(root, 0) + 1
largest = max(largest, sizes[root])
return largest
```
## Complexity
| Time | Space |
| ----------------------------------- | ------------ |
| O(n \* sqrt(max(nums)) \* alpha(n)) | O(max(nums)) |
## Tags
# Largest Divisible Subset Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-divisible-subset
Tested Python solution for LeetCode 368 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 368, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/largest-divisible-subset/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 368 # by problem number
lcpy gen -s largest_divisible_subset # by problem name
```
## Problem
Given a set of **distinct** positive integers `nums`, return the largest subset `answer` such that every pair `(answer[i], answer[j])` of elements in this subset satisfies:
* `answer[i] % answer[j] == 0`, or
* `answer[j] % answer[i] == 0`
If there are multiple solutions, return any of them.
### Examples
```
Input: nums = [1,2,3]
Output: [1,2]
Explanation: [1,3] is also accepted.
```
```
Input: nums = [1,2,4,8]
Output: [1,2,4,8]
```
### Constraints
* `1 <= nums.length <= 1000`
* `1 <= nums[i] <= 2 * 10^9`
* All the integers in `nums` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_divisible_subset/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_divisible_subset/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def largest_divisible_subset(self, nums: list[int]) -> list[int]:
nums = sorted(nums)
n = len(nums)
dp = [1] * n
parent = [-1] * n
for i in range(n):
for j in range(i):
if nums[i] % nums[j] == 0 and dp[j] + 1 > dp[i]:
dp[i] = dp[j] + 1
parent[i] = j
best = max(range(n), key=lambda i: dp[i])
chain: list[int] = []
while best != -1:
chain.append(nums[best])
best = parent[best]
return chain[::-1]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Local Values in a Matrix
Source: https://leetcode-py.wisl.dev/problems/largest-local-values-in-a-matrix
Tested Python solution for LeetCode 2373 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 2373, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/largest-local-values-in-a-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2373 # by problem number
lcpy gen -s largest_local_values_in_a_matrix # by problem name
```
## Problem
You are given an n x n integer matrix grid.
Generate an integer matrix maxLocal of size (n - 2) x (n - 2) such that:
* maxLocal\[i]\[j] is equal to the largest value of the 3 x 3 matrix in grid centered around row i + 1 and column j + 1.
In other words, we want to find the largest value in every contiguous 3 x 3 matrix in grid.
Return the generated matrix.
### Examples

```
Input: grid = [[9,9,8,1],[5,6,2,6],[8,2,6,4],[6,2,2,2]]
Output: [[9,9],[8,6]]
Explanation: The diagram above shows the original matrix and the generated matrix.
Notice that each value in the generated matrix corresponds to the largest value of a contiguous 3 x 3 matrix in grid.
```

```
Input: grid = [[1,1,1,1,1],[1,1,1,1,1],[1,1,2,1,1],[1,1,1,1,1],[1,1,1,1,1]]
Output: [[2,2,2],[2,2,2],[2,2,2]]
Explanation: Notice that the 2 is contained within every contiguous 3 x 3 matrix in grid.
```
### Constraints
* n == grid.length == grid\[i].length
* 3 \<= n \<= 100
* 1 \<= grid\[i]\[j] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_local_values_in_a_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_local_values_in_a_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2) - each of the (n - 2)^2 windows scans a fixed 3 x 3 area
# Space: O(1) extra - excluding the (n - 2) x (n - 2) output matrix
def largest_local(self, grid: list[list[int]]) -> list[list[int]]:
n = len(grid)
return [
[max(grid[i + a][j + b] for a in range(3) for b in range(3)) for j in range(n - 2)]
for i in range(n - 2)
]
```
## Complexity
| Time | Space |
| --------------------------------------------------------------- | ---------------------------------------------------------- |
| O(n^2) - each of the (n - 2)^2 windows scans a fixed 3 x 3 area | O(1) extra - excluding the (n - 2) x (n - 2) output matrix |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Number Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/largest-number
Tested Python solution for LeetCode 179 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 179, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/largest-number/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 179 # by problem number
lcpy gen -s largest_number # by problem name
```
## Problem
Given a list of non-negative integers `nums`, arrange them such that they form the largest number and return it.
Since the result may be very large, you need to return a string instead of an integer.
### Examples
```
Input: nums = [10,2]
Output: "210"
```
```
Input: nums = [3,30,34,5,9]
Output: "9534330"
```
### Constraints
* 1 \<= nums.length \<= 100
* 0 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cmp_to_key
class Solution:
# Time: O(k * n log n) — comparator does string concat of length k
# Space: O(n * k) for the string keys
def largest_number(self, nums: list[int]) -> str:
strs = [str(n) for n in nums]
def compare(a: str, b: str) -> int:
if a + b > b + a:
return -1
if a + b < b + a:
return 1
return 0
strs.sort(key=cmp_to_key(compare))
result = "".join(strs)
# Leading zero means every value was zero
return "0" if result[0] == "0" else result
```
## Complexity
| Time | Space |
| ----------------------------------------------------------- | ----------------------------- |
| O(k \* n log n) — comparator does string concat of length k | O(n \* k) for the string keys |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Largest Number At Least Twice of Others
Source: https://leetcode-py.wisl.dev/problems/largest-number-at-least-twice-of-others
Tested Python solution for LeetCode 747 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 747, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/largest-number-at-least-twice-of-others/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 747 # by problem number
lcpy gen -s largest_number_at_least_twice_of_others # by problem name
```
## Problem
You are given an integer array `nums` where the largest integer is **unique**.
Determine whether the largest element in the array is **at least twice** as much as every other number in the array. If it is, return *the **index** of the largest element, or return* `-1` *otherwise*.
### Examples
```
Input: nums = [3,6,1,0]
Output: 1
Explanation: 6 is the largest integer.
For every other number in the array x, 6 is at least twice as big as x.
The index of value 6 is 1, so we return 1.
```
```
Input: nums = [1,2,3,4]
Output: -1
Explanation: 4 is less than twice the value of 3, so we return -1.
```
### Constraints
* 2 \<= nums.length \<= 50
* 0 \<= nums\[i] \<= 100
* The largest element in nums is unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_number_at_least_twice_of_others/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_number_at_least_twice_of_others/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def dominant_index(self, nums: list[int]) -> int:
largest = second = -1
largest_idx = -1
for i, num in enumerate(nums):
if num > largest:
largest_idx = i
second = largest
largest = num
elif num > second:
second = num
if largest >= 2 * second:
return largest_idx
return -1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Largest Odd Number in String Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-odd-number-in-string
Tested Python solution for LeetCode 1903 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1903, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/largest-odd-number-in-string/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1903 # by problem number
lcpy gen -s largest_odd_number_in_string # by problem name
```
## Problem
You are given a string `num`, representing a large integer. Return *the **largest-valued odd** integer (as a string) that is a **non-empty substring** of* `num`*, or an empty string* `""` *if no odd integer exists*.
A **substring** is a contiguous sequence of characters within a string.
### Examples
```
Input: num = "52"
Output: "5"
Explanation: The only non-empty substrings are "5", "2", and "52". "5" is the only odd number.
```
```
Input: num = "4206"
Output: ""
Explanation: There are no odd numbers in "4206".
```
```
Input: num = "35427"
Output: "35427"
Explanation: "35427" is already an odd number.
```
### Constraints
* 1 \<= num.length \<= 10^5
* num only consists of digits and does not contain any leading zeros.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_odd_number_in_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_odd_number_in_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def largest_odd_number(self, num: str) -> str:
for i in range(len(num) - 1, -1, -1):
if int(num[i]) % 2 == 1:
return num[: i + 1]
return ""
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Palindrome Product Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-palindrome-product
Tested Python solution for LeetCode 479 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 479, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/largest-palindrome-product/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 479 # by problem number
lcpy gen -s largest_palindrome_product # by problem name
```
## Problem
Given an integer `n`, return *the **largest palindromic integer** that can be represented as the product of two `n`-digits integers*. Since the answer can be very large, return it **modulo** `1337`.
### Examples
```
Input: n = 2
Output: 987
Explanation: 99 x 91 = 9009, 9009 % 1337 = 987
```
```
Input: n = 1
Output: 9
```
### Constraints
* `1 <= n <= 8`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_palindrome_product/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_palindrome_product/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(10^n) over the first half, each candidate factorized in O(10^(n/2))
# Space: O(1)
def largest_palindrome(self, n: int) -> int:
if n == 1:
return 9
upper = 10**n - 1
lower = 10 ** (n - 1)
for half in range(upper, lower - 1, -1):
s = str(half)
cand = int(s + s[::-1])
factor = upper
while factor * factor >= cand:
if cand % factor == 0:
return cand % 1337
factor -= 1
raise AssertionError("no palindrome found")
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------- | ----- |
| O(10^n) over the first half, each candidate factorized in O(10^(n/2)) | O(1) |
## Tags
# Largest Perimeter Triangle Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-perimeter-triangle
Tested Python solution for LeetCode 976 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 976, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/largest-perimeter-triangle/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 976 # by problem number
lcpy gen -s largest_perimeter_triangle # by problem name
```
## Problem
Given an integer array \nums\, return \the largest perimeter of a triangle with a non-zero area, formed from three of these lengths\. If it is impossible to form any triangle of a non-zero area, return \0\.
### Examples
```
Input: nums = [2,1,2]
Output: 5
Explanation: You can form a triangle with three side lengths: 1, 2, and 2.
```
```
Input: nums = [1,2,1,10]
Output: 0
Explanation: You cannot use the side lengths 1, 1, and 2 to form a triangle.
You cannot use the side lengths 1, 1, and 10 to form a triangle.
You cannot use the side lengths 1, 2, and 10 to form a triangle.
As we cannot use any three side lengths to form a triangle of non-zero area, we return 0.
```
### Constraints
* 3 \<= nums.length \<= 10^4
* 1 \<= nums\[i] \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_perimeter_triangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_perimeter_triangle/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(1) (sort is in-place for this input list)
def largest_perimeter(self, nums: list[int]) -> int:
lengths = sorted(nums, reverse=True)
for i in range(len(lengths) - 2):
if lengths[i] < lengths[i + 1] + lengths[i + 2]:
return lengths[i] + lengths[i + 1] + lengths[i + 2]
return 0
```
## Complexity
| Time | Space |
| ---------- | ------------------------------------------- |
| O(n log n) | O(1) (sort is in-place for this input list) |
## Tags
# Largest Plus Sign Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/largest-plus-sign
Tested Python solution for LeetCode 764 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 764, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/largest-plus-sign/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 764 # by problem number
lcpy gen -s largest_plus_sign # by problem name
```
## Problem
You are given an integer `n`. You have an `n x n` binary grid `grid` with all values initially `1`'s except for some indices given in the array `mines`. The `i^th` element of the array `mines` is defined as `mines[i] = [x_i, y_i]` where `grid[x_i][y_i] == 0`.
Return *the order of the largest **axis-aligned** plus sign of* 1\*'s contained in\* `grid`. If there is none, return `0`.
An **axis-aligned plus sign** of `1`'s of order `k` has some center `grid[r][c] == 1` along with four arms of length `k - 1` going up, down, left, and right, and made of `1`'s. Note that there could be `0`'s or `1`'s beyond the arms of the plus sign, only the relevant area of the plus sign is checked for `1`'s.
### Examples

```
Input: n = 5, mines = [[4,2]]
Output: 2
Explanation: In the above grid, the largest plus sign can only be of order 2. One of them is shown.
```

```
Input: n = 1, mines = [[0,0]]
Output: 0
Explanation: There is no plus sign, so return 0.
```
### Constraints
* 1 \<= n \<= 500
* 1 \<= mines.length \<= 5000
* 0 \<= xi, yi \< n
* All the pairs (xi, yi) are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_plus_sign/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_plus_sign/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def order_of_largest_plus_sign(self, n: int, mines: list[list[int]]) -> int:
blocked = {(x, y) for x, y in mines}
# dp[r][c] = length of the run of 1s ending at (r, c) in the current direction
dp = [[n] * n for _ in range(n)]
for r in range(n):
# left to right
run = 0
for c in range(n):
run = 0 if (r, c) in blocked else run + 1
dp[r][c] = min(dp[r][c], run)
# right to left
run = 0
for c in range(n - 1, -1, -1):
run = 0 if (r, c) in blocked else run + 1
dp[r][c] = min(dp[r][c], run)
for c in range(n):
# top to bottom
run = 0
for r in range(n):
run = 0 if (r, c) in blocked else run + 1
dp[r][c] = min(dp[r][c], run)
# bottom to top
run = 0
for r in range(n - 1, -1, -1):
run = 0 if (r, c) in blocked else run + 1
dp[r][c] = min(dp[r][c], run)
return max(max(row) for row in dp)
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
# Largest Rectangle in Histogram Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-rectangle-in-histogram
Tested Python solution for LeetCode 84 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 84, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/largest-rectangle-in-histogram/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 84 # by problem number
lcpy gen -s largest_rectangle_in_histogram # by problem name
```
## Problem
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.
### Examples

```
Input: heights = [2,1,5,6,2,3]
Output: 10
```
**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.

```
Input: heights = [2,4]
Output: 4
```
### Constraints
* `1 <= heights.length <= 10^5`
* `0 <= heights[i] <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_rectangle_in_histogram/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_rectangle_in_histogram/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
# Monotonic stack approach
# Stack stores indices of bars in increasing height order
# When we find a shorter bar, we calculate area using previous bars
def largest_rectangle_area(self, heights: list[int]) -> int:
stack: list[int] = [] # Stack of indices
max_area = 0
for i, height in enumerate(heights):
# While current height is less than stack top height
# Pop from stack and calculate area with popped height as smallest
while stack and heights[stack[-1]] > height:
max_area = max(max_area, self.calculate_area(heights, stack, i))
stack.append(i)
while stack:
max_area = max(max_area, self.calculate_area(heights, stack, len(heights)))
return max_area
@staticmethod
def calculate_area(heights: list[int], stack: list[int], right_bound: int) -> int:
h = heights[stack.pop()]
w = right_bound if not stack else right_bound - stack[-1] - 1
return h * w
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Largest Submatrix With Rearrangements
Source: https://leetcode-py.wisl.dev/problems/largest-submatrix-with-rearrangements
Tested Python solution for LeetCode 1727 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1727, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/largest-submatrix-with-rearrangements/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1727 # by problem number
lcpy gen -s largest_submatrix_with_rearrangements # by problem name
```
## Problem
You are given a binary matrix `matrix` of size `m x n`, and you are allowed to rearrange the **columns** of the `matrix` in any order.
Return *the area of the largest submatrix within* `matrix` *where **every** element of the submatrix is* `1` *after reordering the columns optimally.*
### Examples

```
Input: matrix = [[0,0,1],[1,1,1],[1,0,1]]
Output: 4
Explanation: You can rearrange the columns as shown above.
The largest submatrix of 1s, in bold, has an area of 4.
```

```
Input: matrix = [[1,0,1,0,1]]
Output: 3
Explanation: You can rearrange the columns as shown above.
The largest submatrix of 1s, in bold, has an area of 3.
```
```
Input: matrix = [[1,1,0],[1,0,1]]
Output: 2
Explanation: Notice that you must rearrange entire columns, and there is no way to make a submatrix of 1s larger than an area of 2.
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m \* n \<= 10^5
* matrix\[i]\[j] is either 0 or 1.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_submatrix_with_rearrangements/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_submatrix_with_rearrangements/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n log n)
# Space: O(n)
def largest_submatrix(self, matrix: list[list[int]]) -> int:
n = len(matrix[0])
heights = [0] * n
best = 0
for row in matrix:
for j, val in enumerate(row):
heights[j] = heights[j] + 1 if val else 0
sorted_heights = sorted(heights, reverse=True)
for i, h in enumerate(sorted_heights):
best = max(best, h * (i + 1))
return best
```
## Complexity
| Time | Space |
| --------------- | ----- |
| O(m \* n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Substring Between Two Equal Characters
Source: https://leetcode-py.wisl.dev/problems/largest-substring-between-two-equal-characters
Tested Python solution for LeetCode 1624 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1624, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/largest-substring-between-two-equal-characters/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1624 # by problem number
lcpy gen -s largest_substring_between_two_equal_characters # by problem name
```
## Problem
Given a string `s`, return *the length of the longest substring between two equal characters, excluding the two characters.* If there is no such substring return `-1`.
A **substring** is a contiguous sequence of characters within a string.
### Examples
```
Input: s = "aa"
Output: 0
Explanation: The optimal substring here is an empty substring between the two 'a's.
```
```
Input: s = "abca"
Output: 2
Explanation: The optimal substring here is "bc".
```
```
Input: s = "cbzxy"
Output: -1
Explanation: There are no characters that appear twice in s.
```
### Constraints
* 1 \<= s.length \<= 300
* s contains only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_substring_between_two_equal_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_substring_between_two_equal_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_length_between_equal_characters(self, s: str) -> int:
best = -1
first: dict[str, int] = {}
for i, ch in enumerate(s):
j = first.setdefault(ch, i)
if j != i:
best = max(best, i - j - 1)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Largest Sum of Averages Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-sum-of-averages
Tested Python solution for LeetCode 813 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 813, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/largest-sum-of-averages/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 813 # by problem number
lcpy gen -s largest_sum_of_averages # by problem name
```
## Problem
You are given an integer array `nums` and an integer `k`. You can partition the array into at most `k` non-empty adjacent subarrays. The **score** of a partition is the sum of the averages of each subarray.
Note that the partition must use every integer in `nums`, and that the score is not necessarily an integer.
Return the maximum **score** you can achieve of all the possible partitions. Answers within `10^-6` of the actual answer will be accepted.
### Examples
```
Input: nums = [9,1,2,3,9], k = 3
Output: 20.00000
Explanation: The best choice is to partition nums into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20.
```
```
Input: nums = [1,2,3,4,5,6,7], k = 4
Output: 20.50000
```
### Constraints
* `1 <= nums.length <= 100`
* `1 <= nums[i] <= 10^4`
* `1 <= k <= nums.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_sum_of_averages/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_sum_of_averages/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2 * k)
# Space: O(n)
def largest_sum_of_averages(self, nums: list[int], k: int) -> float:
n = len(nums)
prefix = [0.0] * (n + 1)
for i, value in enumerate(nums):
prefix[i + 1] = prefix[i] + value
def average(i: int, j: int) -> float:
return (prefix[j] - prefix[i]) / (j - i)
# best[i] = best score achievable for nums[i:] with the parts still available;
# index n is the empty suffix, worth 0
best = [average(i, n) for i in range(n)] + [0.0]
for _ in range(2, k + 1):
# ascending so best[end] still holds the (parts - 1) values
for i in range(n):
best[i] = max(average(i, end) + best[end] for end in range(i + 1, n + 1))
return best[0]
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(n^2 \* k) | O(n) |
## Tags
# Largest Time for Given Digits Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-time-for-given-digits
Tested Python solution for LeetCode 949 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 949, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/largest-time-for-given-digits/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 949 # by problem number
lcpy gen -s largest_time_for_given_digits # by problem name
```
## Problem
Given an array `arr` of 4 digits, find the latest 24-hour time that can be made using each digit exactly once.
24-hour times are formatted as `"HH:MM"`, where `HH` is between `00` and `23`, and `MM` is between `00` and `59`. The earliest 24-hour time is `00:00`, and the latest is `23:59`.
Return the latest 24-hour time in `"HH:MM"` format. If no valid time can be made, return an empty string.
### Examples
```
Input: arr = [1,2,3,4]
Output: "23:41"
Explanation: The valid 24-hour times are "12:34", "12:43", "13:24", "13:42", "14:23", "14:32", "21:34", "21:43", "23:14", and "23:41". Of these times, "23:41" is the latest.
```
```
Input: arr = [5,5,5,5]
Output: ""
Explanation: There are no valid 24-hour times as "55:55" is not valid.
```
### Constraints
* `arr.length == 4`
* `0 <= arr[i] <= 9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_time_for_given_digits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_time_for_given_digits/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from itertools import permutations
class Solution:
# Time: O(4! * 4)
# Space: O(1)
def largest_time_from_digits(self, arr: list[int]) -> str:
best = ""
for h1, h2, m1, m2 in permutations(arr):
hour = h1 * 10 + h2
minute = m1 * 10 + m2
if hour < 24 and minute < 60:
candidate = f"{hour:02d}:{minute:02d}"
if candidate > best:
best = candidate
return best
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(4! \* 4) | O(1) |
## Tags
# Largest Triangle Area Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-triangle-area
Tested Python solution for LeetCode 812 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 812, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry), Polygons. [View on LeetCode](https://leetcode.com/problems/largest-triangle-area/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 812 # by problem number
lcpy gen -s largest_triangle_area # by problem name
```
## Problem
Given an array of points on the X-Y plane `points` where `points[i] = [xi, yi]`, return *the area of the largest triangle that can be formed by any three different points*. Answers within `10^-5` of the actual answer will be accepted.
### Examples

```
Input: points = [[0,0],[0,1],[1,0],[0,2],[2,0]]
Output: 2.00000
Explanation: The five points are shown in the above figure. The red triangle is the largest.
```
```
Input: points = [[1,0],[0,0],[0,1]]
Output: 0.50000
```
### Constraints
* 3 \<= points.length \<= 50
* -50 \<= xi, yi \<= 50
* All the given points are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_triangle_area/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_triangle_area/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from itertools import combinations
class Solution:
# Time: O(n^3)
# Space: O(1)
def largest_triangle_area(self, points: list[list[int]]) -> float:
best = 0.0
for (ax, ay), (bx, by), (cx, cy) in combinations(points, 3):
area = abs((bx - ax) * (cy - ay) - (by - ay) * (cx - ax)) / 2
best = max(best, area)
return best
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^3) | O(1) |
## Tags
# Largest Unique Number Python Solution
Source: https://leetcode-py.wisl.dev/problems/largest-unique-number
Tested Python solution for LeetCode 1133 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1133, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/largest-unique-number/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1133 # by problem number
lcpy gen -s largest_unique_number # by problem name
```
## Problem
Given an integer array `nums`, return *the largest integer that only occurs once*. If no integer occurs once, return `-1`.
### Examples
```
Input: nums = [5,7,3,9,4,9,8,3,1]
Output: 8
```
**Explanation:** The maximum integer in the array is 9 but it is repeated. The number 8 occurs only once, so it is the answer.
```
Input: nums = [9,9,8,8]
Output: -1
```
**Explanation:** There is no number that occurs only once.
### Constraints
* 1 \<= nums.length \<= 2000
* 0 \<= nums\[i] \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_unique_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/largest_unique_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(n)
def largest_unique_number(self, nums: list[int]) -> int:
counts = Counter(nums)
candidates = [value for value, count in counts.items() if count == 1]
return max(candidates) if candidates else -1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Last Stone Weight Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/last-stone-weight
Tested Python solution for LeetCode 1046 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 1046, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/last-stone-weight/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1046 # by problem number
lcpy gen -s last_stone_weight # by problem name
```
## Problem
You are given an array of integers `stones` where `stones[i]` is the weight of the `i^th` stone.
We are playing a game with the stones. On each turn, we choose the **heaviest two stones** and smash them together. Suppose the heaviest two stones have weights `x` and `y` with `x <= y`. The result of this smash is:
* If `x == y`, both stones are destroyed, and
* If `x != y`, the stone of weight `x` is destroyed, and the stone of weight `y` has new weight `y - x`.
At the end of the game, there is **at most one** stone left.
Return *the weight of the last remaining stone*. If there are no stones left, return `0`.
### Examples
```
Input: stones = [2,7,4,1,8,1]
Output: 1
Explanation:
We combine 7 and 8 to get 1 so the array converts to [2,4,1,1,1] then,
we combine 2 and 4 to get 2 so the array converts to [2,1,1,1] then,
we combine 2 and 1 to get 1 so the array converts to [1,1,1] then,
we combine 1 and 1 to get 0 so the array converts to [1] then that's the value of the last stone.
```
```
Input: stones = [1]
Output: 1
```
### Constraints
* 1 \<= stones.length \<= 30
* 1 \<= stones\[i] \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/last_stone_weight/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/last_stone_weight/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log n)
# Space: O(n)
def last_stone_weight(self, stones: list[int]) -> int:
max_heap = [-stone for stone in stones]
heapq.heapify(max_heap)
while len(max_heap) > 1:
heaviest = -heapq.heappop(max_heap)
second = -heapq.heappop(max_heap)
if heaviest != second:
heapq.heappush(max_heap, -(heaviest - second))
return -max_heap[0] if max_heap else 0
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Last Stone Weight II Python Solution
Source: https://leetcode-py.wisl.dev/problems/last-stone-weight-ii
Tested Python solution for LeetCode 1049 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1049, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/last-stone-weight-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1049 # by problem number
lcpy gen -s last_stone_weight_ii # by problem name
```
## Problem
You are given an array of integers `stones` where `stones[i]` is the weight of the `i^th` stone.
We are playing a game with the stones. On each turn, we choose any two stones and smash them together. Suppose the stones have weights `x` and `y` with `x <= y`. The result of this smash is:
* If `x == y`, both stones are destroyed, and
* If `x != y`, the stone of weight `x` is destroyed, and the stone of weight `y` has new weight `y - x`.
At the end of the game, there is **at most** one stone left.
Return *the smallest possible weight of the left stone*. If there are no stones left, return `0`.
### Examples
```
Input: stones = [2,7,4,1,8,1]
Output: 1
Explanation:
We can combine 2 and 4 to get 2, so the array converts to [2,7,1,8,1] then,
we can combine 7 and 8 to get 1, so the array converts to [2,1,1,1] then,
we can combine 2 and 1 to get 1, so the array converts to [1,1,1] then,
we can combine 1 and 1 to get 0, so the array converts to [1], then that's the optimal value.
```
```
Input: stones = [31,26,33,21,40]
Output: 5
```
### Constraints
* 1 \<= stones.length \<= 30
* 1 \<= stones\[i] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/last_stone_weight_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/last_stone_weight_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * total)
# Space: O(total)
def last_stone_weight_ii(self, stones: list[int]) -> int:
total = sum(stones)
target = total // 2
# reachable[s] = True if a subset sums to s.
reachable = [False] * (target + 1)
reachable[0] = True
for stone in stones:
for s in range(target, stone - 1, -1):
if reachable[s - stone]:
reachable[s] = True
for s in range(target, -1, -1):
if reachable[s]:
return total - 2 * s
return total
```
## Complexity
| Time | Space |
| ------------- | -------- |
| O(n \* total) | O(total) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Leaf-Similar Trees Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/leaf-similar-trees
Tested Python solution for LeetCode 872 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 872, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/leaf-similar-trees/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 872 # by problem number
lcpy gen -s leaf_similar_trees # by problem name
```
## Problem
Consider all the leaves of a binary tree, from left to right order, the values of those leaves form a \leaf value sequence\.\
\For example, in the given tree above, the leaf value sequence is \(6, 7, 4, 9, 8)\.\
Two binary trees are considered \leaf-similar\ if their leaf value sequence is the same.\
\Return \true\ if and only if the two given trees with head nodes \root1\ and \root2\ are leaf-similar.
### Examples

```
Input: root1 = [3,5,1,6,2,9,8,null,null,7,4], root2 = [3,5,1,6,7,4,2,null,null,null,null,null,null,9,8]
Output: true
```

```
Input: root1 = [1,2,3], root2 = [1,3,2]
Output: false
```
### Constraints
* The number of nodes in each tree will be in the range \[1, 200].
* Both of the given trees will have values in the range \[0, 200].
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/leaf_similar_trees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/leaf_similar_trees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n + m)
# Space: O(n + m)
def leaf_similar(self, root1: TreeNode[int] | None, root2: TreeNode[int] | None) -> bool:
def leaves(root: TreeNode[int] | None) -> list[int]:
values: list[int] = []
stack: list[TreeNode[int] | None] = [root]
while stack:
node = stack.pop()
if not node:
continue
if not node.left and not node.right:
values.append(node.val)
stack.append(node.left)
stack.append(node.right)
return values
return leaves(root1) == leaves(root2)
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + m) | O(n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Least Number of Unique Integers after K
Source: https://leetcode-py.wisl.dev/problems/least-number-of-unique-integers-after-k-removals
Tested Python solution for LeetCode 1481 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1481, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/least-number-of-unique-integers-after-k-removals/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1481 # by problem number
lcpy gen -s least_number_of_unique_integers_after_k_removals # by problem name
```
## Problem
Given an array of integers `arr` and an integer `k`. Find the *least number of unique integers* after removing **exactly** `k` elements.
### Examples
```
Input: arr = [5,5,4], k = 1
Output: 1
Explanation: Remove the single 4, only 5 is left.
```
```
Input: arr = [4,3,1,1,3,3,2], k = 3
Output: 2
Explanation: Remove 4, 2 and either one of the two 1s or three 3s. 1 and 3 will be left.
```
### Constraints
* 1 \<= arr.length \<= 10^5
* 1 \<= arr\[i] \<= 10^9
* 0 \<= k \<= arr.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/least_number_of_unique_integers_after_k_removals/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/least_number_of_unique_integers_after_k_removals/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n log n)
# Space: O(n)
def find_least_num_of_unique_ints(self, arr: list[int], k: int) -> int:
counts = sorted(Counter(arr).values())
remaining = len(counts)
for count in counts:
if k < count:
break
k -= count
remaining -= 1
return remaining
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Least Operators to Express Number
Source: https://leetcode-py.wisl.dev/problems/least-operators-to-express-number
Tested Python solution for LeetCode 964 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 964, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Memoization](/catalog/topics/memoization). [View on LeetCode](https://leetcode.com/problems/least-operators-to-express-number/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 964 # by problem number
lcpy gen -s least_operators_to_express_number # by problem name
```
## Problem
Given a single positive integer `x`, we will write an expression of the form `x (op1) x (op2) x (op3) x ...` where each operator `op1`, `op2`, etc. is either addition, subtraction, multiplication, or division (`+`, `-`, `*`, or `/`). For example, with `x = 3`, we might write `3 * 3 / 3 + 3 - 3` which is a value of `3`.
When writing such an expression, we adhere to the following conventions:
* The division operator (`/`) returns rational numbers.
* There are no parentheses placed anywhere.
* We use the usual order of operations: multiplication and division happen before addition and subtraction.
* It is not allowed to use the unary negation operator (`-`). For example, `x - x` is a valid expression as it only uses subtraction, but `-x + x` is not because it uses negation.
We would like to write an expression with the least number of operators such that the expression equals the given `target`. Return the least number of operators used.
### Examples
```
Input: x = 3, target = 19
Output: 5
Explanation: 3 * 3 + 3 * 3 + 3 / 3.
The expression contains 5 operations.
```
```
Input: x = 5, target = 501
Output: 8
Explanation: 5 * 5 * 5 * 5 - 5 * 5 * 5 + 5 / 5.
The expression contains 8 operations.
```
```
Input: x = 100, target = 100000000
Output: 3
Explanation: 100 * 100 * 100 * 100.
The expression contains 3 operations.
```
### Constraints
* `2 <= x <= 100`
* `1 <= target <= 2 * 10^8`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/least_operators_to_express_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/least_operators_to_express_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log_x(target)^2 * x)
# Space: O(log_x(target))
def least_ops_express_target(self, x: int, target: int) -> int:
# An expression is a signed sum of blocks, where a block is a power x^k
# written as x * x * ... * x (k-1 inner operators, k >= 1) or x / x for 1
# (1 inner operator). Each block after the first also costs its leading +/-.
# Counting that leading operator in the block cost gives cost(k) = k for
# k >= 1 and cost(0) = 2, and the answer is the minimum total cost minus 1.
# Choosing a_i copies (negative for subtraction) of each x^i means
# sum(a_i * x^i) == target, so a_i is fixed modulo x by the remainder:
# walk the base-x digits keeping the cheapest carry per position.
costs: dict[tuple[int, int], int] = {(0, target): 0}
while costs:
(exp, remaining), total = min(costs.items(), key=lambda item: item[1])
del costs[(exp, remaining)]
if remaining == 0:
return total - 1
digit = remaining % x
block_cost = 2 if exp == 0 else exp
for offset in range(-3, 4):
# Carry up to 2 units into the next digit, in either direction.
amount = digit + offset * x
key = (exp + 1, (remaining - amount) // x)
candidate = total + abs(amount) * block_cost
if key not in costs or candidate < costs[key]:
costs[key] = candidate
raise ValueError("unreachable")
```
## Complexity
| Time | Space |
| ------------------------ | ----------------- |
| O(log\_x(target)^2 \* x) | O(log\_x(target)) |
## Tags
# Leftmost Column with at Least a One
Source: https://leetcode-py.wisl.dev/problems/leftmost-column-with-one
Tested Python solution for LeetCode 1428 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1428, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Interactive](/catalog/topics/interactive), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/leftmost-column-with-one/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1428 # by problem number
lcpy gen -s leftmost_column_with_one # by problem name
```
## Problem
A \row-sorted binary matrix\ means that all elements are \0\ or \1\ and each row of the matrix is sorted in non-decreasing order.
Given a \row-sorted binary matrix\ \binaryMatrix\, return \the index (0-indexed) of the \leftmost column\ with a 1 in it\. If such an index does not exist, return \-1\.
\You can't access the Binary Matrix directly.\ You may only access the matrix using a \BinaryMatrix\ interface:
\
BinaryMatrix.get(row, col)\ returns the element of the matrix at index \(row, col)\ (0-indexed).\BinaryMatrix.dimensions()\ returns the dimensions of the matrix as a list of 2 elements \\[rows, cols]\, which means the matrix is \rows x cols\.\1000\ calls to \BinaryMatrix.get\ will be judged \Wrong Answer\.
### Examples

```
Input: mat = [[0,0],[1,1]]
Output: 0
```

```
Input: mat = [[0,0],[0,1]]
Output: 1
```

```
Input: mat = [[0,0],[0,0]]
Output: -1
```
### Constraints
* \rows == mat.length\
* \cols == mat\[i].length\
* \1 \<= rows, cols \<= 100\
* \mat\[i]\[j]\ is either \0\ or \1\.
* \mat\[i]\ is sorted in non-decreasing order.
\Follow up:\ Could you find a solution with a complexity better than \O(rows x cols)\?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/leftmost_column_with_one/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/leftmost_column_with_one/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class BinaryMatrix:
# Test-harness API: backs the interactive get/dimensions interface with the matrix
def __init__(self, mat: list[list[int]]) -> None:
self.mat = mat
self.calls = 0
def get(self, row: int, col: int) -> int:
self.calls += 1
return self.mat[row][col]
def dimensions(self) -> list[int]:
return [len(self.mat), len(self.mat[0])]
class Solution:
# Time: O(rows + cols)
# Space: O(1)
def leftmost_column_with_one(self, binary_matrix: BinaryMatrix) -> int:
rows, cols = binary_matrix.dimensions()
row, col = 0, cols - 1
result = -1
while row < rows and col >= 0:
if binary_matrix.get(row, col) == 1:
result = col
col -= 1
else:
row += 1
return result
```
## Complexity
| Time | Space |
| -------------- | ----- |
| O(rows + cols) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Lemonade Change Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/lemonade-change
Tested Python solution for LeetCode 860 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 860, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/lemonade-change/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 860 # by problem number
lcpy gen -s lemonade_change # by problem name
```
## Problem
At a lemonade stand, each lemonade costs `$5`. Customers are standing in a queue to buy from you and order one at a time (in the order specified by `bills`). Each customer will only buy one lemonade and pay with either a `$5`, `$10`, or `$20` bill. You must provide the correct change to each customer so that the net transaction is that the customer pays `$5`.
Note that you do not have any change in hand at first.
Given an integer array `bills` where `bills[i]` is the bill the `ith` customer pays, return `true` if you can provide every customer with the correct change, or `false` otherwise.
### Examples
```
Input: bills = [5,5,5,10,20]
Output: true
Explanation:
From the first 3 customers, we collect three $5 bills in order.
From the fourth customer, we collect a $10 bill and give back a $5.
From the fifth customer, we give a $10 bill and a $5 bill.
Since all customers got correct change, we output true.
```
```
Input: bills = [5,5,10,10,20]
Output: false
```
### Constraints
* 1 \<= bills.length \<= 10^5
* `bills[i]` is either `5`, `10`, or `20`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lemonade_change/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lemonade_change/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def lemonade_change(self, bills: list[int]) -> bool:
fives = 0
tens = 0
for bill in bills:
if bill == 5:
fives += 1
elif bill == 10:
if fives == 0:
return False
fives -= 1
tens += 1
else: # bill == 20, prefer giving a $10 + $5 to conserve $5 bills
if tens > 0 and fives > 0:
tens -= 1
fives -= 1
elif fives >= 3:
fives -= 3
else:
return False
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Length of Last Word Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/length-of-last-word
Tested Python solution for LeetCode 58 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 58, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/length-of-last-word/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 58 # by problem number
lcpy gen -s length_of_last_word # by problem name
```
## Problem
Given a string `s` consisting of words and spaces, return *the length of the **last** word in the string.*
A **word** is a maximal substring consisting of non-space characters only.
### Examples
```
Input: s = "Hello World"
Output: 5
Explanation: The last word is "World" with length 5.
```
```
Input: s = " fly me to the moon "
Output: 4
Explanation: The last word is "moon" with length 4.
```
```
Input: s = "luffy is still joyboy"
Output: 6
Explanation: The last word is "joyboy" with length 6.
```
### Constraints
* 1 \<= s.length \<= 10^4
* `s` consists of only English letters and spaces `' '`.
* There will be at least one word in `s`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/length_of_last_word/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/length_of_last_word/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def length_of_last_word(self, s: str) -> int:
i = len(s) - 1
# Skip trailing spaces
while i >= 0 and s[i] == " ":
i -= 1
# Count characters of the last word
length = 0
while i >= 0 and s[i] != " ":
i -= 1
length += 1
return length
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Length of Longest Fibonacci Subsequence
Source: https://leetcode-py.wisl.dev/problems/length-of-longest-fibonacci-subsequence
Tested Python solution for LeetCode 873 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 873, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 873 # by problem number
lcpy gen -s length_of_longest_fibonacci_subsequence # by problem name
```
## Problem
A sequence \x1, x2, ..., xn\ is \Fibonacci-like\ if:\
\n >= 3\\xi + xi+1 == xi+2\ for all \i + 2 \<= n\\Given a \strictly increasing\ array \arr\ of positive integers forming a sequence, return \the length of the longest Fibonacci-like subsequence of\ \arr\. If one does not exist, return \0\.\
A \subsequence\ is derived from another sequence \arr\ by deleting any number of elements (including none) from \arr\, without changing the order of the remaining elements. For example, \\[3, 5, 8]\ is a subsequence of \\[3, 4, 5, 6, 7, 8]\.
### Examples
```
Input: arr = [1,2,3,4,5,6,7,8]
Output: 5
Explanation: The longest subsequence that is Fibonacci-like: [1,2,3,5,8].
```
```
Input: arr = [1,3,7,11,12,14,18]
Output: 3
Explanation: The longest subsequence that is Fibonacci-like: [1,11,12], [3,11,14] or [7,11,18].
```
### Constraints
* 3 \<= arr.length \<= 1000
* 1 \<= arr\[i] \< arr\[i + 1] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/length_of_longest_fibonacci_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/length_of_longest_fibonacci_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def len_longest_fib_subsequence(self, arr: list[int]) -> int:
index = {num: i for i, num in enumerate(arr)}
dp: dict[tuple[int, int], int] = {}
best = 0
for j in range(len(arr)):
for i in range(j):
need = arr[j] - arr[i]
if need < arr[i] and need in index:
dp[(i, j)] = dp.get((index[need], i), 2) + 1
best = max(best, dp[(i, j)])
return best
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Length of Longest Subarray With at Most K
Source: https://leetcode-py.wisl.dev/problems/length-of-longest-subarray-with-at-most-k-frequency
Tested Python solution for LeetCode 2958 with 25 pytest cases. Generate a practice environment with lcpy.
LeetCode 2958, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/length-of-longest-subarray-with-at-most-k-frequency/description/).
Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2958 # by problem number
lcpy gen -s length_of_longest_subarray_with_at_most_k_frequency # by problem name
```
## Problem
You are given an integer array `nums` and an integer `k`.
The **frequency** of an element `x` is the number of times it occurs in an array.
An array is called **good** if the frequency of each element in this array is **less than or equal** to `k`.
Return *the length of the longest* **good** *subarray of* `nums`.
A **subarray** is a contiguous non-empty sequence of elements within an array.
### Examples
```
Input: nums = [1,2,3,1,2,3,1,2], k = 2
Output: 6
Explanation: The longest possible good subarray is [1,2,3,1,2,3] since the values 1, 2, and 3 occur at most twice in this subarray. Note that the subarrays [2,3,1,2,3,1] and [3,1,2,3,1,2] are also good.
It can be shown that there are no good subarrays with length more than 6.
```
```
Input: nums = [1,2,1,2,1,2,1,2], k = 1
Output: 2
Explanation: The longest possible good subarray is [1,2] since the values 1 and 2 occur at most once in this subarray. Note that the subarray [2,1] is also good.
It can be shown that there are no good subarrays with length more than 2.
```
```
Input: nums = [5,5,5,5,5,5,5], k = 4
Output: 4
Explanation: The longest possible good subarray is [5,5,5,5] since the value 5 occurs 4 times in this subarray.
It can be shown that there are no good subarrays with length more than 4.
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= nums[i] <= 10^9`
* `1 <= k <= nums.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/length_of_longest_subarray_with_at_most_k_frequency/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/length_of_longest_subarray_with_at_most_k_frequency/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def max_subarray_length(self, nums: list[int], k: int) -> int:
freq: dict[int, int] = {}
left = 0
best = 0
for right, val in enumerate(nums):
freq[val] = freq.get(val, 0) + 1
while freq[val] > k:
freq[nums[left]] -= 1
left += 1
best = max(best, right - left + 1)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Letter Case Permutation Python Solution
Source: https://leetcode-py.wisl.dev/problems/letter-case-permutation
Tested Python solution for LeetCode 784 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 784, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/letter-case-permutation/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 784 # by problem number
lcpy gen -s letter_case_permutation # by problem name
```
## Problem
Given a string `s`, you can transform every letter individually to be lowercase or uppercase to create another string.
Return a list of all possible strings we could create. Return the output in **any order**.
### Examples
```
Input: s = "a1b2"
Output: ["a1b2","a1B2","A1b2","A1B2"]
```
```
Input: s = "3z4"
Output: ["3z4","3Z4"]
```
### Constraints
* `1 <= s.length <= 12`
* `s` consists of lowercase English letters, uppercase English letters, and digits.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/letter_case_permutation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/letter_case_permutation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * 2^k) where k is the number of letters
# Space: O(n * 2^k) for the output
def letter_case_permutation(self, s: str) -> list[str]:
results: list[str] = [""]
for ch in s:
if ch.isalpha():
results = [prefix + alt for prefix in results for alt in (ch.lower(), ch.upper())]
else:
results = [prefix + ch for prefix in results]
return results
```
## Complexity
| Time | Space |
| -------------------------------------------- | -------------------------- |
| O(n \* 2^k) where k is the number of letters | O(n \* 2^k) for the output |
## Tags
# Letter Combinations of a Phone Number
Source: https://leetcode-py.wisl.dev/problems/letter-combinations-of-a-phone-number
Tested Python solution for LeetCode 17 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 17, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 17 # by problem number
lcpy gen -s letter_combinations_of_a_phone_number # by problem name
```
## Problem
Given a string containing digits from `2-9` inclusive, return all possible letter combinations that the number could represent. Return the answer in **any order**.
A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
### Examples

```
Input: digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
```
```
Input: digits = ""
Output: []
```
```
Input: digits = "2"
Output: ["a","b","c"]
```
### Constraints
* `0 <= digits.length <= 4`
* `digits[i]` is a digit in the range `['2', '9']`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/letter_combinations_of_a_phone_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/letter_combinations_of_a_phone_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(4^n)
# Space: O(4^n)
def letter_combinations(self, digits: str) -> list[str]:
if not digits:
return []
phone = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz",
}
result = []
def backtrack(i: int, path: str) -> None:
if i == len(digits):
result.append(path)
return
for letter in phone[digits[i]]:
backtrack(i + 1, path + letter)
backtrack(0, "")
return result
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(4^n) | O(4^n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Letter Tile Possibilities Python Solution
Source: https://leetcode-py.wisl.dev/problems/letter-tile-possibilities
Tested Python solution for LeetCode 1079 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 1079, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/letter-tile-possibilities/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1079 # by problem number
lcpy gen -s letter_tile_possibilities # by problem name
```
## Problem
You have \n\ \tiles\, where each tile has one letter \tiles\[i]\ printed on it.
Return \the number of possible non-empty sequences of letters\ you can make using the letters printed on those \tiles\.
### Examples
```
Input: tiles = "AAB"
Output: 8
Explanation: The possible sequences are "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA".
```
```
Input: tiles = "AAABBC"
Output: 188
```
```
Input: tiles = "V"
Output: 1
```
### Constraints
* \1 \<= tiles.length \<= 7\
* \tiles\ consists of uppercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/letter_tile_possibilities/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/letter_tile_possibilities/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n!) bounded by distinct-letter tree size
# Space: O(n)
def num_tile_possibilities(self, tiles: str) -> int:
counts: dict[str, int] = {}
for ch in tiles:
counts[ch] = counts.get(ch, 0) + 1
def dfs() -> int:
total = 0
for ch in counts:
if counts[ch] == 0:
continue
counts[ch] -= 1
total += 1 + dfs()
counts[ch] += 1
return total
return dfs()
```
## Complexity
| Time | Space |
| ------------------------------------------ | ----- |
| O(n!) bounded by distinct-letter tree size | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Lexicographical Numbers Python Solution
Source: https://leetcode-py.wisl.dev/problems/lexicographical-numbers
Tested Python solution for LeetCode 386 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 386, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/lexicographical-numbers/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 386 # by problem number
lcpy gen -s lexicographical_numbers # by problem name
```
## Problem
Given an integer `n`, return all the numbers in the range `[1, n]` sorted in lexicographical order.
You must write an algorithm that runs in `O(n)` time and uses `O(1)` extra space.
### Examples
```
Input: n = 13
Output: [1,10,11,12,13,2,3,4,5,6,7,8,9]
```
```
Input: n = 2
Output: [1,2]
```
### Constraints
* `1 <= n <= 5 * 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lexicographical_numbers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lexicographical_numbers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def lexical_order(self, n: int) -> list[int]:
result: list[int] = []
curr = 1
for _ in range(n):
result.append(curr)
if curr * 10 <= n:
curr *= 10
else:
while curr % 10 == 9 or curr + 1 > n:
curr //= 10
curr += 1
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# LFU Cache Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/lfu-cache
Tested Python solution for LeetCode 460 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 460, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list), [Design](/catalog/topics/design), Doubly-Linked List. [View on LeetCode](https://leetcode.com/problems/lfu-cache/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 460 # by problem number
lcpy gen -s lfu_cache # by problem name
```
## Problem
Design and implement a data structure for a Least Frequently Used (LFU) cache.
Implement the `LFUCache` class:
* `LFUCache(int capacity)` Initializes the object with the `capacity` of the data structure.
* `int get(int key)` Gets the value of the `key` if the `key` exists in the cache. Otherwise, returns `-1`.
* `void put(int key, int value)` Update the value of the `key` if present, or inserts the `key` if not already present. When the cache reaches its `capacity`, it should invalidate and remove the **least frequently used** key before inserting a new item. For this problem, when there is a **tie** (i.e., two or more keys with the same frequency), the **least recently used** `key` would be invalidated.
A **use counter** is maintained for each key. The key with the smallest use counter is the least frequently used key. When a key is first inserted, its use counter is set to `1` (due to the `put` operation). The use counter is incremented each time `get` or `put` is called on it.
Both `get` and `put` must run in `O(1)` average time complexity.
### Examples
```
Input
["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
Output
[null, null, null, 1, null, -1, 3, null, -1, 3, 4]
Explanation
lfu = LFUCache(2);
lfu.put(1, 1); // cache=[1,_], cnt(1)=1
lfu.put(2, 2); // cache=[2,1], cnt(2)=1, cnt(1)=1
lfu.get(1); // return 1, cache=[1,2], cnt(2)=1, cnt(1)=2
lfu.put(3, 3); // 2 is LFU (cnt=1 smallest), invalidate 2. cache=[3,1]
lfu.get(2); // return -1
lfu.get(3); // return 3, cnt(3)=2, cnt(1)=2
lfu.put(4, 4); // tie cnt 1 and 3, 1 is LRU, invalidate 1. cache=[4,3]
lfu.get(1); // return -1
lfu.get(3); // return 3, cnt(3)=3, cnt(4)=1
lfu.get(4); // return 4, cnt(4)=2, cnt(3)=3
```
### Constraints
* 1 \<= capacity \<= 10^4
* 0 \<= key \<= 10^5
* 0 \<= value \<= 10^9
* At most 2 \* 10^5 calls will be made to `get` and `put`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lfu_cache/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lfu_cache/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import OrderedDict, defaultdict
class LFUCache:
# Time: O(1) amortized per get/put
# Space: O(capacity)
def __init__(self, capacity: int) -> None:
self.capacity = capacity
self.min_freq = 0
self.key_to_val: dict[int, int] = {}
self.key_to_freq: dict[int, int] = {}
self.freq_to_keys: dict[int, OrderedDict[int, None]] = defaultdict(OrderedDict)
def _touch(self, key: int) -> None:
"""Increment frequency of key and move it to the next frequency bucket."""
freq = self.key_to_freq[key]
bucket = self.freq_to_keys[freq]
bucket.pop(key)
if not bucket:
if self.min_freq == freq:
self.min_freq += 1
del self.freq_to_keys[freq]
new_freq = freq + 1
self.key_to_freq[key] = new_freq
self.freq_to_keys[new_freq][key] = None
# Time: O(1)
# Space: O(1)
def get(self, key: int) -> int:
if key not in self.key_to_val:
return -1
self._touch(key)
return self.key_to_val[key]
# Time: O(1)
# Space: O(1)
def put(self, key: int, value: int) -> None:
if self.capacity <= 0:
return
if key in self.key_to_val:
self.key_to_val[key] = value
self._touch(key)
return
if len(self.key_to_val) >= self.capacity:
# Evict least frequently used; ties broken by least recently used.
min_bucket = self.freq_to_keys[self.min_freq]
evict_key, _ = min_bucket.popitem(last=False)
del self.key_to_val[evict_key]
del self.key_to_freq[evict_key]
if not min_bucket:
del self.freq_to_keys[self.min_freq]
self.key_to_val[key] = value
self.key_to_freq[key] = 1
self.freq_to_keys[1][key] = None
self.min_freq = 1
```
## Complexity
| Time | Space |
| -------------------------- | ----------- |
| O(1) amortized per get/put | O(capacity) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# License Key Formatting Python Solution
Source: https://leetcode-py.wisl.dev/problems/license-key-formatting
Tested Python solution for LeetCode 482 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 482, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/license-key-formatting/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 482 # by problem number
lcpy gen -s license_key_formatting # by problem name
```
## Problem
You are given a license key represented as a string `s` that consists of only alphanumeric characters and dashes. The string is separated into `n + 1` groups by `n` dashes. You are also given an integer `k`.
We want to reformat the string `s` such that each group contains exactly `k` characters, except for the first group, which could be shorter than `k` but still must contain at least one character. Furthermore, there must be a dash inserted between two groups, and you should convert all lowercase letters to uppercase.
Return *the reformatted license key*.
### Examples
```
Input: s = "5F3Z-2e-9-w", k = 4
Output: "5F3Z-2E9W"
Explanation: The string s has been split into two parts, each part has 4 characters. Note that the two extra dashes are not needed and can be removed.
```
```
Input: s = "2-5g-3-J", k = 2
Output: "2-5G-3J"
Explanation: The string s has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.
```
### Constraints
* 1 \<= s.length \<= 10^5
* s consists of English letters, digits, and dashes '-'.
* 1 \<= k \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/license_key_formatting/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/license_key_formatting/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def license_key_formatting(self, s: str, k: int) -> str:
chars = s.replace("-", "").upper()
first = len(chars) % k or k
groups = [chars[:first]] if chars else []
groups.extend(chars[i : i + k] for i in range(first, len(chars), k))
return "-".join(groups)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Line Reflection Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/line-reflection
Tested Python solution for LeetCode 356 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 356, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/line-reflection/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 356 # by problem number
lcpy gen -s line_reflection # by problem name
```
## Problem
Given `n` points on a 2D plane, find if there is such a line parallel to the y-axis that reflects the given points symmetrically.
In other words, answer whether or not if there exists a line that after reflecting all points over the given line, the original points' set is the same as the reflected ones.
**Note** that there can be repeated points.
### Examples

```
Input: points = [[1,1],[-1,1]]
Output: true
Explanation: We can choose the line x = 0.
```

```
Input: points = [[1,1],[-1,-1]]
Output: false
Explanation: We can't choose a line.
```
### Constraints
* `n == points.length`
* `1 <= n <= 10^4`
* `-10^8 <= points[i][j] <= 10^8`
**Follow up:** Could you do better than `O(n^2)`?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/line_reflection/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/line_reflection/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def is_reflected(self, points: list[list[int]]) -> bool:
min_x, max_x = min(x for x, _ in points), max(x for x, _ in points)
point_set = {(x, y) for x, y in points}
s = min_x + max_x
return all((s - x, y) in point_set for x, y in points)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Linked List Components Python Solution
Source: https://leetcode-py.wisl.dev/problems/linked-list-components
Tested Python solution for LeetCode 817 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 817, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/linked-list-components/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 817 # by problem number
lcpy gen -s linked_list_components # by problem name
```
## Problem
You are given the `head` of a linked list containing unique integer values and an integer array `nums` that is a subset of the linked list values.
Return the number of **connected components** in `nums`. A connected component is a non-empty, maximal sequence of **consecutive** nodes in the linked list such that every node's value belongs to `nums`.
### Examples

```
Input: head = [0,1,2,3], nums = [0,1,3]
Output: 2
Explanation: 0 and 1 are connected, so [0, 1] and [3] are the two connected components.
```

```
Input: head = [0,1,2,3,4], nums = [0,3,1,4]
Output: 2
Explanation: 0 and 1 are connected, 3 and 4 are connected, so [0, 1] and [3, 4] are the two connected components.
```
### Constraints
* The number of nodes in the linked list is n.
* 1 \<= n \<= 10\4\
* 0 \<= Node.val \< n
* All the values Node.val are unique.
* 1 \<= nums.length \<= n
* 0 \<= nums\[i] \< n
* All the values of nums are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_components/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_components/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(m) for the nums set
def num_components(self, head: ListNode[int] | None, nums: list[int]) -> int:
values = set(nums)
count = 0
in_component = False
node = head
while node is not None:
if node.val in values:
if not in_component:
count += 1
in_component = True
else:
in_component = False
node = node.next
return count
```
## Complexity
| Time | Space |
| ---- | --------------------- |
| O(n) | O(m) for the nums set |
## Tags
# Linked List Cycle Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/linked-list-cycle
Tested Python solution for LeetCode 141 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 141, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/linked-list-cycle/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 141 # by problem number
lcpy gen -s linked_list_cycle # by problem name
```
## Problem
Given `head`, the head of a linked list, determine if the linked list has a cycle in it.
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the `next` pointer. Internally, `pos` is used to denote the index of the node that tail's `next` pointer is connected to. **Note that `pos` is not passed as a parameter**.
Return `true` *if there is a cycle in the linked list*. Otherwise, return `false`.
### Examples

```
Input: head = [3,2,0,-4], pos = 1
Output: true
```
**Explanation:** There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).

```
Input: head = [1,2], pos = 0
Output: true
```
**Explanation:** There is a cycle in the linked list, where the tail connects to the 0th node.

```
Input: head = [1], pos = -1
Output: false
```
**Explanation:** There is no cycle in the linked list.
### Constraints
* The number of the nodes in the list is in the range `[0, 10^4]`.
* `-10^5 <= Node.val <= 10^5`
* `pos` is `-1` or a **valid index** in the linked-list.
**Follow up:** Can you solve it using `O(1)` (i.e. constant) memory?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_cycle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_cycle/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def has_cycle(self, head: ListNode[int] | None) -> bool:
fast = head
slow = head
while fast and fast.next:
assert slow is not None
fast = fast.next.next
slow = slow.next
if fast is slow:
return True
return False
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Linked List Cycle II Python Solution
Source: https://leetcode-py.wisl.dev/problems/linked-list-cycle-ii
Tested Python solution for LeetCode 142 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 142, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/linked-list-cycle-ii/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 142 # by problem number
lcpy gen -s linked_list_cycle_ii # by problem name
```
## Problem
Given the `head` of a linked list, return the node where the cycle begins. If there is no cycle, return `null`.
### Examples

```
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
```

```
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.
```

```
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.
```
### Constraints
* The number of the nodes in the list is in the range \[0, 10^4].
* -10^5 \<= Node.val \<= 10^5
* pos is -1 or a valid index in the linked-list.
**Follow up:** Can you solve it using O(1) (i.e. constant) memory?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_cycle_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_cycle_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def detect_cycle(self, head: ListNode[int] | None) -> ListNode[int] | None:
if not head:
return None
slow: ListNode[int] | None = head
fast: ListNode[int] | None = head
# Phase 1: Detect if cycle exists using Floyd's algorithm
has_cycle = False
while fast and fast.next:
assert slow is not None
slow = slow.next
fast = fast.next.next
if slow is fast:
has_cycle = True
break
if not has_cycle:
return None
# Phase 2: Find the start of the cycle
slow = head
assert fast is not None # fast is guaranteed to be a valid node here
while slow is not fast:
assert slow is not None
slow = slow.next
assert fast.next is not None
fast = fast.next
return slow
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[AlgoMaster 75](/catalog/algo-master-75).
# Linked List in Binary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/linked-list-in-binary-tree
Tested Python solution for LeetCode 1367 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1367, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/linked-list-in-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1367 # by problem number
lcpy gen -s linked_list_in_binary_tree # by problem name
```
## Problem
Given a binary tree root and a linked list with head as the first node.
Return True if all the elements in the linked list starting from the head correspond to some downward path connected in the binary tree otherwise return False.
In this context downward path means a path that starts at some node and goes downwards.
### Examples

```
Input: head = [4,2,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true
Explanation: Nodes in blue form a subpath in the binary Tree.
```

```
Input: head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true
```
```
Input: head = [1,4,2,6,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: false
Explanation: There is no path in the binary tree that contains all the elements of the linked list from head.
```
### Constraints
* The number of nodes in the tree will be in the range \[1, 2500].
* The number of nodes in the list will be in the range \[1, 100].
* 1 \<= Node.val \<= 100 for each node in the linked list and binary tree.
**Follow up:** What if you cannot modify the input lists, i.e. reversing them is not allowed?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_in_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_in_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode, TreeNode
class Solution:
# Time: O(n * m) worst case (n tree nodes, m list length)
# Space: O(h) recursion depth
def is_sub_path(self, head: ListNode[int] | None, root: TreeNode[int] | None) -> bool:
if root is None:
return False
def match(node: TreeNode[int] | None, cur: ListNode[int] | None) -> bool:
if cur is None:
return True
if node is None or node.val != cur.val:
return False
return match(node.left, cur.next) or match(node.right, cur.next)
def dfs(node: TreeNode[int] | None) -> bool:
if node is None:
return False
return match(node, head) or dfs(node.left) or dfs(node.right)
return dfs(root)
```
## Complexity
| Time | Space |
| -------------------------------------------------- | -------------------- |
| O(n \* m) worst case (n tree nodes, m list length) | O(h) recursion depth |
## Tags
[NeetCode All](/catalog/neetcode).
# Linked List Random Node Python Solution
Source: https://leetcode-py.wisl.dev/problems/linked-list-random-node
Tested Python solution for LeetCode 382 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 382, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Math](/catalog/topics/math), Reservoir Sampling, Randomized. [View on LeetCode](https://leetcode.com/problems/linked-list-random-node/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 382 # by problem number
lcpy gen -s linked_list_random_node # by problem name
```
## Problem
Given a singly linked list, return a random node's value from the linked list. Each node must have the **same probability** of being chosen.
Implement the `Solution` class:
* `Solution(ListNode head)` Initializes the object with the head of the singly-linked list `head`.
* `int getRandom()` Chooses a node randomly from the list and returns its value. All the nodes of the list should be equally likely to be chosen.
### Examples

```
Input
["Solution", "getRandom", "getRandom", "getRandom", "getRandom", "getRandom"]
[[[1, 2, 3]], [], [], [], [], []]
Output
[null, 1, 3, 2, 2, 3]
Explanation
Solution solution = new Solution([1, 2, 3]);
solution.getRandom(); // return 1
solution.getRandom(); // return 3
solution.getRandom(); // return 2
solution.getRandom(); // return 2
solution.getRandom(); // return 3
// getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
```
```
Input
["Solution", "getRandom", "getRandom"]
[[[7]], [], []]
Output
[null, 7, 7]
Explanation
Solution solution = new Solution([7]);
solution.getRandom(); // return 7, the only node in the list.
```
### Constraints
* The number of nodes in the linked list will be in the range `[1, 10^4]`.
* `-10^4 <= Node.val <= 10^4`
* At most `10^4` calls will be made to `getRandom`.
**Follow up:**
* What if the linked list is extremely large and its length is unknown to you?
* Could you solve this efficiently without using extra space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_random_node/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/linked_list_random_node/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
from leetcode_py import ListNode
class Solution:
# Time: init O(1), get_random O(n)
# Space: O(1)
def __init__(self, head: ListNode[int] | None) -> None:
self.head = head
def get_random(self) -> int:
node = self.head
assert node is not None
reservoir = node.val
current = node.next
seen = 2
while current is not None:
if random.randint(1, seen) == 1:
reservoir = current.val
current = current.next
seen += 1
return reservoir
```
## Complexity
| Time | Space |
| --------------------------- | ----- |
| init O(1), get\_random O(n) | O(1) |
## Tags
# Logger Rate Limiter Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/logger-rate-limiter
Tested Python solution for LeetCode 359 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 359, [Easy](/catalog/easy). Topics: [Design](/catalog/topics/design), [Hash Table](/catalog/topics/hash-table), [Data Stream](/catalog/topics/data-stream). [View on LeetCode](https://leetcode.com/problems/logger-rate-limiter/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 359 # by problem number
lcpy gen -s logger_rate_limiter # by problem name
```
## Problem
Design a logger system that receives a stream of messages along with their timestamps. Each **unique** message should only be printed **at most every 10 seconds** (i.e. a message printed at timestamp `t` will prevent other identical messages from being printed until timestamp `t + 10`).
All messages will come in chronological order. Several messages may arrive at the same timestamp.
Implement the `Logger` class:
* `Logger()` Initializes the `logger` object.
* `bool shouldPrintMessage(int timestamp, string message)` Returns `true` if the `message` should be printed in the given `timestamp`, otherwise returns `false`.
### Examples
```
Input
["Logger", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage"]
[[], [1, "foo"], [2, "bar"], [3, "foo"], [8, "bar"], [10, "foo"], [11, "foo"]]
Output
[null, true, true, false, false, false, true]
Explanation
Logger logger = new Logger();
logger.shouldPrintMessage(1, "foo"); // return true, next allowed timestamp for "foo" is 1 + 10 = 11
logger.shouldPrintMessage(2, "bar"); // return true, next allowed timestamp for "bar" is 2 + 10 = 12
logger.shouldPrintMessage(3, "foo"); // 3 < 11, return false
logger.shouldPrintMessage(8, "bar"); // 8 < 12, return false
logger.shouldPrintMessage(10, "foo"); // 10 < 11, return false
logger.shouldPrintMessage(11, "foo"); // 11 >= 11, return true, next allowed timestamp for "foo" is 11 + 10 = 21
```
### Constraints
* `0 <= timestamp <= 10^9`
* Every `timestamp` will be passed in non-decreasing order (chronological order).
* `1 <= message.length <= 30`
* At most `10^4` calls will be made to `shouldPrintMessage`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/logger_rate_limiter/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/logger_rate_limiter/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Logger:
# Time: O(1) per call
# Space: O(m) for m distinct messages
def __init__(self) -> None:
self.ok_until: dict[str, int] = {}
def should_print_message(self, timestamp: int, message: str) -> bool:
if timestamp < self.ok_until.get(message, 0):
return False
self.ok_until[message] = timestamp + 10
return True
```
## Complexity
| Time | Space |
| ------------- | ---------------------------- |
| O(1) per call | O(m) for m distinct messages |
## Tags
[NeetCode All](/catalog/neetcode).
# Logical OR of Two Binary Grids Represented as
Source: https://leetcode-py.wisl.dev/problems/logical-or-of-two-binary-grids-represented-as-quad-trees
Tested Python solution for LeetCode 558 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 558, [Medium](/catalog/medium). Topics: [Divide and Conquer](/catalog/topics/divide-and-conquer), [Tree](/catalog/topics/tree). [View on LeetCode](https://leetcode.com/problems/logical-or-of-two-binary-grids-represented-as-quad-trees/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 558 # by problem number
lcpy gen -s logical_or_of_two_binary_grids_represented_as_quad_trees # by problem name
```
## Problem
A Binary Matrix is a matrix in which all the elements are either `0` or `1`.
Given `quadTree1` and `quadTree2`. `quadTree1` represents a `n * n` binary matrix and `quadTree2` represents another `n * n` binary matrix.
Return *a Quad-Tree* representing the `n * n` binary matrix which is the result of **logical bitwise OR** of the two binary matrixes represented by `quadTree1` and `quadTree2`.
Notice that you can assign the value of a node to **True** or **False** when `isLeaf` is **False**, and both are **accepted** in the answer.
A Quad-Tree is a tree data structure in which each internal node has exactly four children. Besides, each node has two attributes:
* `val`: True if the node represents a grid of 1's or False if the node represents a grid of 0's.
* `isLeaf`: True if the node is leaf node on the tree or False if the node has the four children.
```
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
}
```
We can construct a Quad-Tree from a two-dimensional area using the following steps:
1. If the current grid has the same value (i.e all `1's` or all `0's`) set `isLeaf` True and set `val` to the value of the grid and set the four children to Null and stop.
2. If the current grid has different values, set `isLeaf` to False and set `val` to any value and divide the current grid into four sub-grids as shown in the photo.
3. Recurse for each of the children with the proper sub-grid.

If you want to know more about the Quad-Tree, you can refer to the [wiki](https://en.wikipedia.org/wiki/Quadtree).
**Quad-Tree format:** The input/output represents the serialized format of a Quad-Tree using level order traversal, where `null` signifies a path terminator where no node exists below. It is very similar to the serialization of a binary tree. The only difference is that the node is represented as a list `[isLeaf, val]`.
If the value of `isLeaf` or `val` is True we represent it as **1** in the list `[isLeaf, val]` and if the value of `isLeaf` or `val` is False we represent it as **0**.
### Examples
 
```
Input: quadTree1 = [[0,1],[1,1],[1,1],[1,0],[1,0]]
, quadTree2 = [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]
Output: [[0,0],[1,1],[1,1],[1,1],[1,0]]
Explanation: quadTree1 and quadTree2 are shown above. You can see the binary matrix which is represented by each Quad-Tree.
If we apply logical bitwise OR on the two binary matrices we get the binary matrix below which is represented by the result Quad-Tree.
Notice that the binary matrices shown are only for illustration, you don't have to construct the binary matrix to get the result tree.
```

```
Input: quadTree1 = [[1,0]], quadTree2 = [[1,0]]
Output: [[1,0]]
Explanation: Each tree represents a binary matrix of size 1*1. Each matrix contains only zero.
The resulting matrix is of size 1*1 with also zero.
```
### Constraints
* quadTree1 and quadTree2 are both valid Quad-Trees each representing a `n * n` grid.
* `n == 2^x` where `0 <= x <= 9`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/logical_or_of_two_binary_grids_represented_as_quad_trees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/logical_or_of_two_binary_grids_represented_as_quad_trees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
# ruff: noqa: N803
class Node:
def __init__(
self,
val: bool,
isLeaf: bool,
topLeft: Node | None = None,
topRight: Node | None = None,
bottomLeft: Node | None = None,
bottomRight: Node | None = None,
) -> None:
self.val = val
self.isLeaf = isLeaf
self.topLeft = topLeft
self.topRight = topRight
self.bottomLeft = bottomLeft
self.bottomRight = bottomRight
class Solution:
# Time: O(n)
# Space: O(log n) recursion depth
def intersect(self, quad_tree1: Node, quad_tree2: Node) -> Node:
if quad_tree1.isLeaf:
return Node(True, True) if quad_tree1.val else quad_tree2
if quad_tree2.isLeaf:
return Node(True, True) if quad_tree2.val else quad_tree1
quadrants = (
(quad_tree1.topLeft, quad_tree2.topLeft),
(quad_tree1.topRight, quad_tree2.topRight),
(quad_tree1.bottomLeft, quad_tree2.bottomLeft),
(quad_tree1.bottomRight, quad_tree2.bottomRight),
)
merged: list[Node] = []
for left, right in quadrants:
assert left is not None and right is not None
merged.append(self.intersect(left, right))
if all(child.isLeaf and child.val for child in merged):
return Node(True, True)
top_left, top_right, bottom_left, bottom_right = merged
return Node(False, False, top_left, top_right, bottom_left, bottom_right)
```
## Complexity
| Time | Space |
| ---- | ------------------------ |
| O(n) | O(log n) recursion depth |
## Tags
# Lonely Pixel I Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/lonely-pixel-i
Tested Python solution for LeetCode 531 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 531, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/lonely-pixel-i/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 531 # by problem number
lcpy gen -s lonely_pixel_i # by problem name
```
## Problem
Given an `m x n` `picture` consisting of black `'B'` and white `'W'` pixels, return the number of **black** lonely pixels.
A black lonely pixel is a character `'B'` located at a specific position where the same row and same column don't have **any other** black pixels.
### Examples

```
Input: picture = [["W","W","B"],["W","B","W"],["B","W","W"]]
Output: 3
Explanation: All the three 'B's are black lonely pixels.
```
```
Input: picture = [["B","B","B"],["B","B","W"],["B","B","B"]]
Output: 0
```
### Constraints
* `m == picture.length`
* `n == picture[i].length`
* `1 <= m, n <= 500`
* `picture[i][j]` is `'W'` or `'B'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lonely_pixel_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lonely_pixel_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m + n)
def find_lonely_pixel(self, picture: list[list[str]]) -> int:
if not picture:
return 0
m, n = len(picture), len(picture[0])
row_counts = [row.count("B") for row in picture]
col_counts = [sum(1 for r in range(m) if picture[r][c] == "B") for c in range(n)]
return sum(
1
for r in range(m)
for c in range(n)
if picture[r][c] == "B" and row_counts[r] == 1 and col_counts[c] == 1
)
```
## Complexity
| Time | Space |
| --------- | -------- |
| O(m \* n) | O(m + n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Lonely Pixel II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/lonely-pixel-ii
Tested Python solution for LeetCode 533 with 36 pytest cases. Generate a practice environment with lcpy.
LeetCode 533, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/lonely-pixel-ii/description/).
Generate this problem as a practice environment: tested reference solution, 36 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 533 # by problem number
lcpy gen -s lonely_pixel_ii # by problem name
```
## Problem
Given an `m x n` `picture` consisting of black `'B'` and white `'W'` pixels and an integer `target`, return the number of **black** lonely pixels.
A black lonely pixel is a character `'B'` located at a specific position `(r, c)` where:
* Row `r` and column `c` both contain exactly `target` black pixels.
* For all rows that have a black pixel at column `c`, they should be exactly the same as row `r`.
### Examples

```
Input: picture = [["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","W","B","W","B","W"]], target = 3
Output: 6
Explanation: All the green 'B's are the black pixels we need (all 'B's at column 1 and 3).
Take 'B' at row r = 0 and column c = 1 as an example:
- Rule 1, row r = 0 and column c = 1 both have exactly target = 3 black pixels.
- Rule 2, the rows that have a black pixel at column c = 1 are row 0, row 1 and row 2. They are exactly the same as row r = 0.
```

```
Input: picture = [["W","W","B"],["W","W","B"],["W","W","B"]], target = 1
Output: 0
```
### Constraints
* `m == picture.length`
* `n == picture[i].length`
* `1 <= m, n <= 200`
* `picture[i][j]` is `'W'` or `'B'`.
* `1 <= target <= min(m, n)`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lonely_pixel_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lonely_pixel_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
class Solution:
# Time: O(m * n^2)
# Space: O(m * n)
def find_black_pixel(self, picture: list[list[str]], target: int) -> int:
row_counts = [row.count("B") for row in picture]
cols: dict[int, list[int]] = defaultdict(list)
for i, row in enumerate(picture):
for j, pixel in enumerate(row):
if pixel == "B":
cols[j].append(i)
result = 0
for rows in cols.values():
if row_counts[rows[0]] != target or len(rows) != target:
continue
if all(picture[r] == picture[rows[0]] for r in rows):
result += target
return result
```
## Complexity
| Time | Space |
| ----------- | --------- |
| O(m \* n^2) | O(m \* n) |
## Tags
# Long Pressed Name Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/long-pressed-name
Tested Python solution for LeetCode 925 with 25 pytest cases. Generate a practice environment with lcpy.
LeetCode 925, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/long-pressed-name/description/).
Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 925 # by problem number
lcpy gen -s long_pressed_name # by problem name
```
## Problem
Your friend is typing his `name` into a keyboard. Sometimes, when typing a character `c`, the key might get *long pressed*, and the character will be typed 1 or more times.
You examine the `typed` characters of the keyboard. Return `true` if it is possible that it was your friend's name, with some characters (possibly none) being long pressed.
### Examples
```
Input: name = "alex", typed = "aaleex"
Output: true
Explanation: 'a' and 'e' in 'alex' were long pressed.
```
```
Input: name = "saeed", typed = "ssaaedd"
Output: false
Explanation: 'e' must have been pressed twice, but it was not in the typed output.
```
### Constraints
* 1 \<= name.length, typed.length \<= 1000
* name and typed consist of only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/long_pressed_name/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/long_pressed_name/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(name) + len(typed))
# Space: O(1)
def is_long_pressed_name(self, name: str, typed: str) -> bool:
i = 0
for j, ch in enumerate(typed):
if i < len(name) and name[i] == ch:
i += 1
elif j == 0 or ch != typed[j - 1]:
return False
return i == len(name)
```
## Complexity
| Time | Space |
| ------------------------- | ----- |
| O(len(name) + len(typed)) | O(1) |
## Tags
# Longest Absolute File Path Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-absolute-file-path
Tested Python solution for LeetCode 388 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 388, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Depth-First Search](/catalog/topics/depth-first-search). [View on LeetCode](https://leetcode.com/problems/longest-absolute-file-path/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 388 # by problem number
lcpy gen -s longest_absolute_file_path # by problem name
```
## Problem
Suppose we have a file system that stores both files and directories. An example of one system is represented in the following picture:

Here, we have `dir` as the only directory in the root. `dir` contains two subdirectories, `subdir1` and `subdir2`. `subdir1` contains a file `file1.ext` and subdirectory `subsubdir1`. `subdir2` contains a subdirectory `subsubdir2`, which contains a file `file2.ext`.
In text form, it looks like this (where each indented line is one level deeper):
```
dir
subdir1
file1.ext
subsubdir1
subdir2
subsubdir2
file2.ext
```
If we were to write this representation in code, it will look like this: `"dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"`. Note that the `'\n'` and `'\t'` are the new-line and tab characters.
Every file and directory has a unique **absolute path** in the file system, which is the order of directories that must be opened to reach the file/directory itself, all concatenated by `'/'`s. Using the above example, the **absolute path** to `file2.ext` is `"dir/subdir2/subsubdir2/file2.ext"`. Each directory name consists of letters, digits, and/or spaces. Each file name is of the form `name.extension`, where `name` and `extension` consist of letters, digits, and/or spaces.
Given a string `input` representing the file system in the explained format, return the length of the longest absolute path to a file in the abstracted file system. If there is no file in the system, return `0`.
Note that the testcases are generated such that the file system is valid and no file or directory name has length 0.
### Examples

```
Input: input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"
Output: 20
```
Explanation: We have only one file, and the absolute path is `"dir/subdir2/file.ext"` of length 20.

```
Input: input = "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"
Output: 32
```
Explanation: We have two files: `"dir/subdir1/file1.ext"` of length 21 and `"dir/subdir2/subsubdir2/file2.ext"` of length 32. We return 32 since it is the longest absolute path to a file.
```
Input: input = "a"
Output: 0
```
Explanation: We do not have any files, just a single directory named `"a"`.
### Constraints
* 1 \<= input.length \<= 10^4
* `input` may contain lowercase or uppercase English letters, a new line character `'\n'`, a tab character `'\t'`, a dot `'.'`, a space `' '`, and digits.
* All file and directory names have positive length.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_absolute_file_path/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_absolute_file_path/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) single pass over the input
# Space: O(d) stack of path lengths, d = max nesting depth
def length_longest_path(self, input_str: str) -> int:
best = 0
# path_lens[i] = total length of the path ending at depth i (dirs only)
path_lens: list[int] = []
for line in input_str.split("\n"):
depth = line.count("\t")
name = line[depth:]
del path_lens[depth:]
parent = path_lens[-1] if path_lens else 0
length = parent + (1 if path_lens else 0) + len(name)
if "." in name:
best = max(best, length)
else:
path_lens.append(length)
return best
```
## Complexity
| Time | Space |
| ------------------------------- | ------------------------------------------------- |
| O(n) single pass over the input | O(d) stack of path lengths, d = max nesting depth |
## Tags
# Longest Common Prefix Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-common-prefix
Tested Python solution for LeetCode 14 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 14, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/longest-common-prefix/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 14 # by problem number
lcpy gen -s longest_common_prefix # by problem name
```
## Problem
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string `""`.
### Examples
```
Input: strs = ["flower","flow","flight"]
Output: "fl"
```
```
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
```
### Constraints
* 1 \<= strs.length \<= 200
* 0 \<= strs\[i].length \<= 200
* `strs[i]` consists of only lowercase English letters if it is non-empty.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_common_prefix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_common_prefix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(S) where S is total characters across all strings
# Space: O(1)
def longest_common_prefix(self, strs: list[str]) -> str:
if not strs:
return ""
# Vertical scan: compare each character index against all strings
first = strs[0]
for i, char in enumerate(first):
for other in strs[1:]:
# Stop when index exceeds a string's length or chars mismatch
if i >= len(other) or other[i] != char:
return first[:i]
return first
```
## Complexity
| Time | Space |
| --------------------------------------------------- | ----- |
| O(S) where S is total characters across all strings | O(1) |
## Tags
[Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Longest Common Subsequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-common-subsequence
Tested Python solution for LeetCode 1143 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1143, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/longest-common-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1143 # by problem number
lcpy gen -s longest_common_subsequence # by problem name
```
## Problem
Given two strings `text1` and `text2`, return \*the length of their longest **common subsequence**. \*If there is no **common subsequence**, return `0`.
A **subsequence** of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.
* For example, `"ace"` is a subsequence of `"abcde"`.
A **common subsequence** of two strings is a subsequence that is common to both strings.
### Examples
```
Input: text1 = "abcde", text2 = "ace"
Output: 3
Explanation: The longest common subsequence is "ace" and its length is 3.
```
```
Input: text1 = "abc", text2 = "abc"
Output: 3
Explanation: The longest common subsequence is "abc" and its length is 3.
```
```
Input: text1 = "abc", text2 = "def"
Output: 0
Explanation: There is no such common subsequence, so the result is 0.
```
### Constraints
* 1 \<= text1.length, text2.length \<= 1000
* text1 and text2 consist of only lowercase English characters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_common_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_common_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def longest_common_subsequence(self, text1: str, text2: str) -> int:
m, n = len(text1), len(text2)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if text1[i - 1] == text2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[m][n]
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Longest Consecutive Sequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-consecutive-sequence
Tested Python solution for LeetCode 128 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 128, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Union Find](/catalog/topics/union-find). [View on LeetCode](https://leetcode.com/problems/longest-consecutive-sequence/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 128 # by problem number
lcpy gen -s longest_consecutive_sequence # by problem name
```
## Problem
Given an unsorted array of integers `nums`, return *the length of the longest consecutive elements sequence.*
You must write an algorithm that runs in `O(n)` time.
### Examples
```
Input: nums = [100,4,200,1,3,2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.
```
```
Input: nums = [0,3,7,2,5,8,4,6,0,1]
Output: 9
```
```
Input: nums = [1,0,1,2]
Output: 3
```
### Constraints
* 0 \<= nums.length \<= 10^5
* -10^9 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_consecutive_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_consecutive_sequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) - each number visited at most twice (once as start, once as continuation)
# Space: O(n) - hash set storage
def longest_consecutive(self, nums: list[int]) -> int:
"""
Find longest consecutive sequence using hash set.
Example: nums = [100, 4, 200, 1, 3, 2]
Step 1: Create set {100, 4, 200, 1, 3, 2}
Step 2: For each number, check if it's sequence start (num-1 not in set):
num=100: 99 not in set → START sequence
100 → 101 not in set → length=1
num=4: 3 in set → SKIP (not start)
num=200: 199 not in set → START sequence
200 → 201 not in set → length=1
num=1: 0 not in set → START sequence
1 → 2 in set → 2 → 3 in set → 3 → 4 in set → 4 → 5 not in set
Sequence: [1,2,3,4] → length=4 ✓
Result: max(1, 1, 4) = 4
"""
if not nums:
return 0
num_set = set(nums)
max_length = 0
for num in num_set:
# Only start counting from the beginning of a sequence
if num - 1 not in num_set:
current_num = num
current_length = 1
# Count consecutive numbers
while current_num + 1 in num_set:
current_num += 1
current_length += 1
max_length = max(max_length, current_length)
return max_length
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------------------ | ----------------------- |
| O(n) - each number visited at most twice (once as start, once as continuation) | O(n) - hash set storage |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Longest Continuous Increasing Subsequence
Source: https://leetcode-py.wisl.dev/problems/longest-continuous-increasing-subsequence
Tested Python solution for LeetCode 674 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 674, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/longest-continuous-increasing-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 674 # by problem number
lcpy gen -s longest_continuous_increasing_subsequence # by problem name
```
## Problem
Given an unsorted array of integers `nums`, return the length of the longest continuous increasing subsequence (i.e. subarray). The subsequence must be strictly increasing.
A continuous increasing subsequence is defined by two indices `l` and `r` (`l < r`) such that it is `[nums[l], nums[l + 1], ..., nums[r - 1], nums[r]]` and for each `l <= i < r`, `nums[i] < nums[i + 1]`.
### Examples
```
Input: nums = [1,3,5,4,7]
Output: 3
```
**Explanation:** The longest continuous increasing subsequence is \[1,3,5] with length 3. Even though \[1,3,5,7] is an increasing subsequence, it is not continuous as elements 5 and 7 are separated by element 4.
```
Input: nums = [2,2,2,2,2]
Output: 1
```
**Explanation:** The longest continuous increasing subsequence is \[2] with length 1. Note that it must be strictly increasing.
### Constraints
* `1 <= nums.length <= 10^4`
* `-10^9 <= nums[i] <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_continuous_increasing_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_continuous_increasing_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_length_of_lcis(self, nums: list[int]) -> int:
best = 1
run = 1
for i in range(1, len(nums)):
if nums[i - 1] < nums[i]:
run += 1
best = max(best, run)
else:
run = 1
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Longest Continuous Subarray With Absolute
Source: https://leetcode-py.wisl.dev/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit
Tested Python solution for LeetCode 1438 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1438, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Queue](/catalog/topics/queue), [Sliding Window](/catalog/topics/sliding-window), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Ordered Set](/catalog/topics/ordered-set), Monotonic Queue. [View on LeetCode](https://leetcode.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1438 # by problem number
lcpy gen -s longest_continuous_subarray_with_absolute_diff_less_than_or_equal_to_limit # by problem name
```
## Problem
Given an array of integers `nums` and an integer `limit`, return the size of the longest non-empty subarray such that the absolute difference between any two elements of this subarray is less than or equal to `limit`.
### Examples
```
Input: nums = [8,2,4,7], limit = 4
Output: 2
Explanation: All subarrays are:
[8] with maximum absolute diff |8-8| = 0 <= 4.
[8,2] with maximum absolute diff |8-2| = 6 > 4.
[8,2,4] with maximum absolute diff |8-2| = 6 > 4.
[8,2,4,7] with maximum absolute diff |8-2| = 6 > 4.
[2] with maximum absolute diff |2-2| = 0 <= 4.
[2,4] with maximum absolute diff |2-4| = 2 <= 4.
[2,4,7] with maximum absolute diff |2-7| = 5 > 4.
[4] with maximum absolute diff |4-4| = 0 <= 4.
[4,7] with maximum absolute diff |4-7| = 3 <= 4.
[7] with maximum absolute diff |7-7| = 0 <= 4.
Therefore, the size of the longest subarray is 2.
```
```
Input: nums = [10,1,2,4,7,2], limit = 5
Output: 4
Explanation: The subarray [2,4,7,2] is the longest since the maximum absolute diff is |2-7| = 5 <= 5.
```
```
Input: nums = [4,2,2,2,4,4,2,2], limit = 0
Output: 3
```
### Constraints
* 1 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= 10^9
* 0 \<= limit \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_continuous_subarray_with_absolute_diff_less_than_or_equal_to_limit/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_continuous_subarray_with_absolute_diff_less_than_or_equal_to_limit/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n) each index enters and leaves both deques at most once
# Space: O(n) for the two monotonic deques
def longest_subarray(self, nums: list[int], limit: int) -> int:
min_deque: deque[int] = deque()
max_deque: deque[int] = deque()
left = 0
best = 0
for right, value in enumerate(nums):
while min_deque and min_deque[-1] > value:
min_deque.pop()
min_deque.append(value)
while max_deque and max_deque[-1] < value:
max_deque.pop()
max_deque.append(value)
while max_deque[0] - min_deque[0] > limit:
if max_deque[0] == nums[left]:
max_deque.popleft()
if min_deque[0] == nums[left]:
min_deque.popleft()
left += 1
best = max(best, right - left + 1)
return best
```
## Complexity
| Time | Space |
| ---------------------------------------------------------- | --------------------------------- |
| O(n) each index enters and leaves both deques at most once | O(n) for the two monotonic deques |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Happy String Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-happy-string
Tested Python solution for LeetCode 1405 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1405, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/longest-happy-string/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1405 # by problem number
lcpy gen -s longest_happy_string # by problem name
```
## Problem
A string `s` is called **happy** if it satisfies the following conditions:
* `s` only contains the letters `'a'`, `'b'`, and `'c'`.
* `s` does not contain any of `"aaa"`, `"bbb"`, or `"ccc"` as a substring.
* `s` contains **at most** `a` occurrences of the letter `'a'`.
* `s` contains **at most** `b` occurrences of the letter `'b'`.
* `s` contains **at most** `c` occurrences of the letter `'c'`.
Given three integers `a`, `b`, and `c`, return *the **longest possible happy** string*. If there are multiple longest happy strings, return *any of them*. If there is no such string, return *the empty string* `""`.
### Examples
```
Input: a = 1, b = 1, c = 7
Output: "ccaccbcc"
Explanation: "ccbccacc" would also be a correct answer.
```
```
Input: a = 7, b = 1, c = 0
Output: "aabaa"
Explanation: It is the only correct answer in this case.
```
### Constraints
* `0 <= a, b, c <= 100`
* `a + b + c > 0`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_happy_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_happy_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log 3) = O(n) where n = a + b + c total chars placed
# Space: O(n) for the output
def longest_happy_string(self, a: int, b: int, c: int) -> str:
# Greedy: always place the most abundant legal char; if it would form a
# triple, place the second most abundant instead. Maximises length.
heap: list[tuple[int, str]] = []
for ch, count in (("a", a), ("b", b), ("c", c)):
if count > 0:
heapq.heappush(heap, (-count, ch))
result: list[str] = []
while heap:
neg_count, ch = heapq.heappop(heap)
# Blocked if the last two placed equal this char (would make a triple).
if len(result) >= 2 and result[-1] == result[-2] == ch:
if not heap:
break
neg_count2, ch2 = heapq.heappop(heap)
result.append(ch2)
if neg_count2 + 1 < 0:
heapq.heappush(heap, (neg_count2 + 1, ch2))
heapq.heappush(heap, (neg_count, ch))
else:
result.append(ch)
if neg_count + 1 < 0:
heapq.heappush(heap, (neg_count + 1, ch))
return "".join(result)
```
## Complexity
| Time | Space |
| -------------------------------------------------------- | ------------------- |
| O(n log 3) = O(n) where n = a + b + c total chars placed | O(n) for the output |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Longest Harmonious Subsequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-harmonious-subsequence
Tested Python solution for LeetCode 594 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 594, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sliding Window](/catalog/topics/sliding-window), [Sorting](/catalog/topics/sorting), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/longest-harmonious-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 594 # by problem number
lcpy gen -s longest_harmonious_subsequence # by problem name
```
## Problem
We define a harmonious array as an array where the difference between its maximum value and its minimum value is **exactly** `1`.
Given an integer array `nums`, return the length of its longest harmonious subsequence among all its possible subsequences.
### Examples
```
Input: nums = [1,3,2,2,5,2,3,7]
Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].
```
```
Input: nums = [1,2,3,4]
Output: 2
Explanation: The longest harmonious subsequences are [1,2], [2,3], and [3,4], all of which have a length of 2.
```
```
Input: nums = [1,1,1,1]
Output: 0
Explanation: No harmonious subsequence exists.
```
### Constraints
* 1 \<= nums.length \<= 2 \* 10^4
* -10^9 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_harmonious_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_harmonious_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(n)
def find_lhs(self, nums: list[int]) -> int:
counts = Counter(nums)
longest = 0
for value, count in counts.items():
if value + 1 in counts:
longest = max(longest, count + counts[value + 1])
return longest
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Longest Ideal Subsequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-ideal-subsequence
Tested Python solution for LeetCode 2370 with 27 pytest cases. Generate a practice environment with lcpy.
LeetCode 2370, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/longest-ideal-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2370 # by problem number
lcpy gen -s longest_ideal_subsequence # by problem name
```
## Problem
You are given a string `s` consisting of lowercase letters and an integer `k`. We call a string `t` **ideal** if the following conditions are satisfied:
* `t` is a **subsequence** of the string `s`.
* The absolute difference in the alphabet order of every two **adjacent** letters in `t` is less than or equal to `k`.
Return *the length of the **longest** ideal string*.
A **subsequence** is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.
**Note** that the alphabet order is not cyclic. For example, the absolute difference in the alphabet order of `'a'` and `'z'` is `25`, not `1`.
### Examples
```
Input: s = "acfgbd", k = 2
Output: 4
```
**Explanation:** The longest ideal string is `"acbd"`. The length of this string is `4`, so `4` is returned.
Note that `"acfgbd"` is not ideal because `'c'` and `'f'` have a difference of `3` in alphabet order.
```
Input: s = "abcd", k = 3
Output: 4
```
**Explanation:** The longest ideal string is `"abcd"`. The length of this string is `4`, so `4` is returned.
### Constraints
* `1 <= s.length <= 10^5`
* `0 <= k <= 25`
* `s` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_ideal_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_ideal_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(26 * n)
# Space: O(26)
def longest_ideal_string(self, s: str, k: int) -> int:
best = [0] * 26
for ch in s:
c = ord(ch) - ord("a")
window = best[max(0, c - k) : min(26, c + k + 1)]
best[c] = max(best[c], 1 + max(window))
return max(best)
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(26 \* n) | O(26) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Increasing Path in a Matrix
Source: https://leetcode-py.wisl.dev/problems/longest-increasing-path-in-a-matrix
Tested Python solution for LeetCode 329 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 329, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), [Memoization](/catalog/topics/memoization), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 329 # by problem number
lcpy gen -s longest_increasing_path_in_a_matrix # by problem name
```
## Problem
Given an `m x n` integers `matrix`, return *the length of the longest increasing path in* `matrix`.
From each cell, you can either move in four directions: left, right, up, or down. You **may not** move **diagonally** or move **outside the boundary** (i.e., wrap-around is not allowed).
### Examples

```
Input: matrix = [[9,9,4],[6,6,8],[2,1,1]]
Output: 4
```
**Explanation:** The longest increasing path is `[1, 2, 6, 9]`.

```
Input: matrix = [[3,4,5],[3,2,6],[2,2,1]]
Output: 4
```
**Explanation:** The longest increasing path is `[3, 4, 5, 6]`. Moving diagonally is not allowed.
```
Input: matrix = [[1]]
Output: 1
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m, n \<= 200
* 0 \<= matrix\[i]\[j] \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_increasing_path_in_a_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_increasing_path_in_a_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cache
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def longest_increasing_path(self, matrix: list[list[int]]) -> int:
if not matrix or not matrix[0]:
return 0
rows, cols = len(matrix), len(matrix[0])
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
@cache
def dfs(r: int, c: int) -> int:
max_length = 1
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and matrix[nr][nc] > matrix[r][c]:
max_length = max(max_length, 1 + dfs(nr, nc))
return max_length
result = 0
for i in range(rows):
for j in range(cols):
result = max(result, dfs(i, j))
return result
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Longest Increasing Subsequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-increasing-subsequence
Tested Python solution for LeetCode 300 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 300, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/longest-increasing-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 300 # by problem number
lcpy gen -s longest_increasing_subsequence # by problem name
```
## Problem
Given an integer array `nums`, return the length of the longest **strictly increasing** **subsequence**.
### Examples
```
Input: nums = [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
```
```
Input: nums = [0,1,0,3,2,3]
Output: 4
```
```
Input: nums = [7,7,7,7,7,7,7]
Output: 1
```
### Constraints
* `1 <= nums.length <= 2500`
* `-10^4 <= nums[i] <= 10^4`
**Follow up:** Can you come up with an algorithm that runs in `O(n log(n))` time complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_increasing_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_increasing_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def length_of_lis(self, nums: list[int]) -> int:
"""
Binary Search + DP: tails[i] = smallest tail of all LIS of length i+1
Example with middle replacement: [1,5,3,7,2,6,4,8]
Step | num | tails | Action
-----|-----|--------------|------------------
1 | 1 | [1] | append
2 | 5 | [1,5] | append
3 | 3 | [1,3] | replace 5 (pos=1)
4 | 7 | [1,3,7] | append
5 | 2 | [1,2,7] | replace 3 (pos=1)
6 | 6 | [1,2,6] | replace 7 (pos=2)
7 | 4 | [1,2,4] | replace 6 (pos=2)
8 | 8 | [1,2,4,8] | append
Result: len(tails) = 4
"""
import bisect
tails: list[int] = []
for num in nums:
pos = bisect.bisect_left(tails, num)
if pos == len(tails):
tails.append(num)
else:
tails[pos] = num
return len(tails)
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Longest Line of Consecutive One in Matrix
Source: https://leetcode-py.wisl.dev/problems/longest-line-of-consecutive-one-in-matrix
Tested Python solution for LeetCode 562 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 562, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/longest-line-of-consecutive-one-in-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 562 # by problem number
lcpy gen -s longest_line_of_consecutive_one_in_matrix # by problem name
```
## Problem
Given an \m x n\ binary matrix \mat\, return \the length of the longest line of consecutive one in the matrix\.
The line could be horizontal, vertical, diagonal, or anti-diagonal.
### Examples

```
Input: mat = [[0,1,1,0],[0,1,1,0],[0,0,0,1]]
Output: 3
```

```
Input: mat = [[1,1,1,1],[0,1,1,0],[0,0,0,1]]
Output: 4
```
### Constraints
* `m == mat.length`
* `n == mat[i].length`
* `1 <= m, n <= 10^4`
* `1 <= m * n <= 10^4`
* `mat[i][j]` is either `0` or `1`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_line_of_consecutive_one_in_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_line_of_consecutive_one_in_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(n)
def longest_line(self, mat: list[list[int]]) -> int:
n = len(mat[0])
prev_vertical = [0] * n
prev_diagonal = [0] * n
prev_anti_diagonal = [0] * n
best = 0
for row in mat:
cur_vertical = [0] * n
cur_diagonal = [0] * n
cur_anti_diagonal = [0] * n
horizontal = 0
for j, value in enumerate(row):
if value == 1:
horizontal += 1
cur_vertical[j] = prev_vertical[j] + 1
cur_diagonal[j] = prev_diagonal[j - 1] + 1 if j > 0 else 1
cur_anti_diagonal[j] = prev_anti_diagonal[j + 1] + 1 if j + 1 < n else 1
best = max(
best, horizontal, cur_vertical[j], cur_diagonal[j], cur_anti_diagonal[j]
)
else:
horizontal = 0
prev_vertical = cur_vertical
prev_diagonal = cur_diagonal
prev_anti_diagonal = cur_anti_diagonal
return best
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(m \* n) | O(n) |
## Tags
# Longest Strictly Increasing or Strictly
Source: https://leetcode-py.wisl.dev/problems/longest-monotonic-subarray
Tested Python solution for LeetCode 3105 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 3105, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/longest-monotonic-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3105 # by problem number
lcpy gen -s longest_monotonic_subarray # by problem name
```
## Problem
You are given an array of integers `nums`. Return the length of the longest subarray of `nums` which is either strictly increasing or strictly decreasing.
### Examples
```
Input: nums = [1,4,3,3,2]
Output: 2
Explanation:
The strictly increasing subarrays of nums are [1], [2], [3], [3], [4], and [1,4].
The strictly decreasing subarrays of nums are [1], [2], [3], [3], [4], [3,2], and [4,3].
Hence, we return 2.
```
```
Input: nums = [3,3,3,3]
Output: 1
Explanation:
The strictly increasing subarrays of nums are [3], [3], [3], and [3].
The strictly decreasing subarrays of nums are [3], [3], [3], and [3].
Hence, we return 1.
```
```
Input: nums = [3,2,1]
Output: 3
Explanation:
The strictly increasing subarrays of nums are [3], [2], and [1].
The strictly decreasing subarrays of nums are [3], [2], [1], [3,2], [2,1], and [3,2,1].
Hence, we return 3.
```
### Constraints
* 1 \<= nums.length \<= 50
* 1 \<= nums\[i] \<= 50
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_monotonic_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_monotonic_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def longest_monotonic_subarray(self, nums: list[int]) -> int:
best = 1
inc = dec = 1
for i in range(1, len(nums)):
if nums[i] > nums[i - 1]:
inc += 1
dec = 1
elif nums[i] < nums[i - 1]:
dec += 1
inc = 1
else:
inc = dec = 1
best = max(best, inc, dec)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Mountain in Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-mountain-in-array
Tested Python solution for LeetCode 845 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 845, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Dynamic Programming](/catalog/topics/dynamic-programming), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/longest-mountain-in-array/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 845 # by problem number
lcpy gen -s longest_mountain_in_array # by problem name
```
## Problem
You may recall that an array `arr` is a **mountain array** if and only if:
* `arr.length >= 3`
* There exists some index `i` (**0-indexed**) with `0 < i < arr.length - 1` such that:
* `arr[0] < arr[1] < ... < arr[i - 1] < arr[i]`
* `arr[i] > arr[i + 1] > ... > arr[arr.length - 1]`
Given an integer array `arr`, return *the length of the longest subarray, which is a mountain*. Return `0` if there is no mountain subarray.
### Examples
```
Input: arr = [2,1,4,7,3,2,5]
Output: 5
Explanation: The largest mountain is [1,4,7,3,2] which has length 5.
```
```
Input: arr = [2,2,2]
Output: 0
Explanation: There is no mountain.
```
### Constraints
* 1 \<= arr.length \<= 10^4
* 0 \<= arr\[i] \<= 10^4
**Follow up:**
* Can you solve it using only one pass?
* Can you solve it in `O(1)` space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_mountain_in_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_mountain_in_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def longest_mountain(self, arr: list[int]) -> int:
n = len(arr)
longest = 0
i = 1
while i < n:
if arr[i - 1] < arr[i]:
start = i - 1
while i < n and arr[i - 1] < arr[i]:
i += 1
peak = i - 1
while i < n and arr[i - 1] > arr[i]:
i += 1
if peak < i - 1:
longest = max(longest, i - start)
else:
i += 1
return longest
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Longest Nice Subarray Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-nice-subarray
Tested Python solution for LeetCode 2401 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2401, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-nice-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2401 # by problem number
lcpy gen -s longest_nice_subarray # by problem name
```
## Problem
You are given an array `nums` consisting of positive integers.
We call a subarray of `nums` nice if the bitwise AND of every pair of elements that are in different positions in the subarray is equal to 0.
Return the length of the longest nice subarray.
A subarray is a contiguous part of an array.
Note that subarrays of length 1 are always considered nice.
### Examples
```
Input: nums = [1,3,8,48,10]
Output: 3
Explanation: The longest nice subarray is [3,8,48]. This subarray satisfies the conditions:
- 3 AND 8 = 0.
- 3 AND 48 = 0.
- 8 AND 48 = 0.
It can be proven that no longer nice subarray can be obtained, so we return 3.
```
```
Input: nums = [3,1,5,11,13]
Output: 1
Explanation: The length of the longest nice subarray is 1. Any subarray of length 1 can be chosen.
```
### Constraints
1 \<= nums.length \<= 10^5
1 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_nice_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_nice_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def longest_nice_subarray(self, nums: list[int]) -> int:
best = 0
window_or = 0
left = 0
for right, num in enumerate(nums):
while window_or & num:
window_or ^= nums[left]
left += 1
window_or |= num
best = max(best, right - left + 1)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Palindrome Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/longest-palindrome
Tested Python solution for LeetCode 409 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 409, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/longest-palindrome/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 409 # by problem number
lcpy gen -s longest_palindrome # by problem name
```
## Problem
Given a string `s` which consists of lowercase or uppercase letters, return the length of the longest palindrome that can be built with those letters.
Letters are case sensitive, for example, "Aa" is not considered a palindrome.
### Examples
```
Input: s = "abccccdd"
Output: 7
```
**Explanation:** One longest palindrome that can be built is "dccaccd", whose length is 7.
```
Input: s = "a"
Output: 1
```
**Explanation:** The longest palindrome that can be built is "a", whose length is 1.
### Constraints
* `1 <= s.length <= 2000`
* `s` consists of lowercase and/or uppercase English letters only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_palindrome/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_palindrome/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def longest_palindrome(self, s: str) -> int:
char_count: dict[str, int] = {}
for char in s:
char_count[char] = char_count.get(char, 0) + 1
length = 0
has_odd = False
for count in char_count.values():
length += count // 2 * 2
if count % 2 == 1:
has_odd = True
return length + (1 if has_odd else 0)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Longest Palindromic Subsequence
Source: https://leetcode-py.wisl.dev/problems/longest-palindromic-subsequence
Tested Python solution for LeetCode 516 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 516, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/longest-palindromic-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 516 # by problem number
lcpy gen -s longest_palindromic_subsequence # by problem name
```
## Problem
Given a string `s`, find *the longest palindromic **subsequence**'s length in* `s`.
A **subsequence** is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.
### Examples
```
Input: s = "bbbab"
Output: 4
Explanation: One possible longest palindromic subsequence is "bbbb".
```
```
Input: s = "cbbd"
Output: 2
Explanation: One possible longest palindromic subsequence is "bb".
```
### Constraints
* `1 <= s.length <= 1000`
* `s` consists only of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_palindromic_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_palindromic_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def longest_palindrome_subseq(self, s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
dp[i][i] = 1
for j in range(i + 1, n):
if s[i] == s[j]:
dp[i][j] = dp[i + 1][j - 1] + 2
else:
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
return dp[0][n - 1]
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Palindromic Substring Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-palindromic-substring
Tested Python solution for LeetCode 5 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 5, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/longest-palindromic-substring/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 5 # by problem number
lcpy gen -s longest_palindromic_substring # by problem name
```
## Problem
Given a string `s`, return the longest palindromic substring in `s`.
### Examples
```
Input: s = "babad"
Output: "bab"
```
**Explanation:** "aba" is also a valid answer.
```
Input: s = "cbbd"
Output: "bb"
```
### Constraints
* `1 <= s.length <= 1000`
* `s` consist of only digits and English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_palindromic_substring/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_palindromic_substring/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(1)
def longest_palindrome(self, s: str) -> str:
start = 0
max_len = 0
for i in range(len(s)):
# Odd length palindromes (center at i)
len1 = self.expand(s, i, i)
# Even length palindromes (center between i and i+1)
len2 = self.expand(s, i, i + 1)
curr_len = max(len1, len2)
if curr_len > max_len:
max_len = curr_len
start = i - (curr_len - 1) // 2
return s[start : start + max_len]
@staticmethod
def expand(s: str, left: int, right: int) -> int:
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return right - left - 1
class SolutionManacher:
# Time: O(n)
# Space: O(n)
def longest_palindrome(self, s: str) -> str:
t = "#".join(f"^{s}$")
n = len(t)
p = [0] * n
center = right = 0
for i in range(1, n - 1):
mirror_value = 2 * center - i
p[i] = min(right - i, p[mirror_value]) if right > i else 0
while t[i + 1 + p[i]] == t[i - 1 - p[i]]:
p[i] += 1
if i + p[i] > right:
center, right = i, i + p[i]
max_len = max(p)
center_index = p.index(max_len)
# Map back to original string: (center_index - max_len) // 2
start = (center_index - max_len) // 2
return s[start : start + max_len]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Longest Repeating Character Replacement
Source: https://leetcode-py.wisl.dev/problems/longest-repeating-character-replacement
Tested Python solution for LeetCode 424 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 424, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-repeating-character-replacement/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 424 # by problem number
lcpy gen -s longest_repeating_character_replacement # by problem name
```
## Problem
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.
Return the length of the longest substring containing the same letter you can get after performing the above operations.
### Examples
```
Input: s = "ABAB", k = 2
Output: 4
Explanation: Replace the two 'A's with two 'B's or vice versa.
```
```
Input: s = "AABABBA", k = 1
Output: 4
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.
```
### Constraints
1 \<= s.length \<= 10^5
s consists of only uppercase English letters.
0 \<= k \<= s.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_repeating_character_replacement/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_repeating_character_replacement/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) - single pass through string
# Space: O(1) - at most 26 characters in count dict
def character_replacement(self, s: str, k: int) -> int:
"""
Find the length of the longest substring with same character
after at most k replacements using sliding window approach.
"""
if not s:
return 0
count: dict[str, int] = {}
left = 0
max_freq = 0
max_length = 0
for right in range(len(s)):
# Expand window: add character at right pointer
count[s[right]] = count.get(s[right], 0) + 1
max_freq = max(max_freq, count[s[right]])
# Shrink window if needed: if we need more than k replacements
# Current window size = right - left + 1
# Characters to replace = window_size - max_freq
# If characters_to_replace > k, we need to shrink
if (right - left + 1) - max_freq > k:
count[s[left]] -= 1
left += 1
# Update max length
max_length = max(max_length, right - left + 1)
return max_length
```
## Complexity
| Time | Space |
| --------------------------------- | ------------------------------------------ |
| O(n) - single pass through string | O(1) - at most 26 characters in count dict |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Longest String Chain Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-string-chain
Tested Python solution for LeetCode 1048 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1048, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/longest-string-chain/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1048 # by problem number
lcpy gen -s longest_string_chain # by problem name
```
## Problem
You are given an array of `words` where each word consists of lowercase English letters.
`wordA` is a **predecessor** of `wordB` if and only if we can insert **exactly one** letter anywhere in `wordA` **without changing the order of the other characters** to make it equal to `wordB`.
* For example, `"abc"` is a **predecessor** of `"abac"`, while `"cba"` is not a **predecessor** of `"bcad"`.
A **word chain** is a sequence of words `[word1, word2, ..., wordk]` with `k >= 1`, where `word1` is a **predecessor** of `word2`, `word2` is a **predecessor** of `word3`, and so on. A single word is trivially a **word chain** with `k == 1`.
Return *the length of the **longest possible word chain** with words chosen from the given list of* `words`.
### Examples
```
Input: words = ["a","b","ba","bca","bda","bdca"]
Output: 4
Explanation: One of the longest word chains is ["a","ba","bda","bdca"].
```
```
Input: words = ["xbc","pcxbcf","xb","cxbc","pcxbc"]
Output: 5
Explanation: All the words can be put in a word chain ["xb", "xbc", "cxbc", "pcxbc", "pcxbcf"].
```
```
Input: words = ["abcd","dbqca"]
Output: 1
Explanation: The trivial word chain ["abcd"] is one of the longest word chains.
["abcd","dbqca"] is not a valid word chain because the ordering of the letters is changed.
```
### Constraints
* `1 <= words.length <= 1000`
* `1 <= words[i].length <= 16`
* `words[i]` only consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_string_chain/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_string_chain/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * L^2) where L is the max word length
# Space: O(n * L)
def longest_str_chain(self, words: list[str]) -> int:
words = sorted(words, key=len)
chains: dict[str, int] = {}
best = 0
for word in words:
chains[word] = 1
for i in range(len(word)):
predecessor = word[:i] + word[i + 1 :]
if predecessor in chains:
chains[word] = max(chains[word], chains[predecessor] + 1)
best = max(best, chains[word])
return best
```
## Complexity
| Time | Space |
| ------------------------------------------ | --------- |
| O(n \* L^2) where L is the max word length | O(n \* L) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Subarray With Maximum Bitwise AND
Source: https://leetcode-py.wisl.dev/problems/longest-subarray-with-maximum-bitwise-and
Tested Python solution for LeetCode 2419 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2419, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), Brainteaser. [View on LeetCode](https://leetcode.com/problems/longest-subarray-with-maximum-bitwise-and/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2419 # by problem number
lcpy gen -s longest_subarray_with_maximum_bitwise_and # by problem name
```
## Problem
You are given an integer array `nums` of size `n`.
Consider a **non-empty** subarray from `nums` that has the **maximum** possible **bitwise AND**.
* In other words, let `k` be the maximum value of the bitwise AND of **any** subarray of `nums`. Then, only subarrays with a bitwise AND equal to `k` should be considered.
Return *the length of the **longest** such subarray*.
The bitwise AND of an array is the bitwise AND of all the numbers in it.
A **subarray** is a contiguous sequence of elements within an array.
### Examples
```
Input: nums = [1,2,3,3,2,2]
Output: 2
Explanation:
The maximum possible bitwise AND of a subarray is 3.
The longest subarray with that value is [3,3], so we return 2.
```
```
Input: nums = [1,2,3,4]
Output: 1
Explanation:
The maximum possible bitwise AND of a subarray is 4.
The longest subarray with that value is [4], so we return 1.
```
### Constraints
1 \<= nums.length \<= 10^5
1 \<= nums\[i] \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_subarray_with_maximum_bitwise_and/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_subarray_with_maximum_bitwise_and/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def longest_subarray(self, nums: list[int]) -> int:
target = max(nums)
best = 0
run = 0
for num in nums:
run = run + 1 if num == target else 0
if run > best:
best = run
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Substring with At Least K Repeating
Source: https://leetcode-py.wisl.dev/problems/longest-substring-with-at-least-k-repeating-characters
Tested Python solution for LeetCode 395 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 395, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 395 # by problem number
lcpy gen -s longest_substring_with_at_least_k_repeating_characters # by problem name
```
## Problem
Given a string `s` and an integer `k`, return *the length of the longest substring of* `s` *such that the frequency of each character in this substring is greater than or equal to* `k`.
### Examples
```
Input: s = "aaabb", k = 3
Output: 3
Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.
```
```
Input: s = "ababbc", k = 2
Output: 5
Explanation: The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
```
### Constraints
* `1 <= s.length <= 10^4`
* `s` consists of only lowercase English letters.
* `1 <= k <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_with_at_least_k_repeating_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_with_at_least_k_repeating_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(26 * n) -> O(n)
# Space: O(26) -> O(1)
def longest_substring_with_at_least_k_repeating_characters(self, s: str, k: int) -> int:
best = 0
for target in range(1, 27):
if target * k > len(s):
break
counts: dict[str, int] = {}
left = 0
for right, ch in enumerate(s):
counts[ch] = counts.get(ch, 0) + 1
while len(counts) > target:
counts[s[left]] -= 1
if counts[s[left]] == 0:
del counts[s[left]]
left += 1
if len(counts) == target and all(c >= k for c in counts.values()):
best = max(best, right - left + 1)
return best
```
## Complexity
| Time | Space |
| ------------------ | ------------- |
| O(26 \* n) -> O(n) | O(26) -> O(1) |
## Tags
# Longest Substring with At Most K Distinct
Source: https://leetcode-py.wisl.dev/problems/longest-substring-with-at-most-k-distinct-characters
Tested Python solution for LeetCode 340 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 340, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 340 # by problem number
lcpy gen -s longest_substring_with_at_most_k_distinct_characters # by problem name
```
## Problem
Given a string `s` and an integer `k`, return *the length of the longest* substring *of* `s` *that contains at most* `k` **distinct** characters\*.
### Examples
```
Input: s = "eceba", k = 2
Output: 3
Explanation: The substring is "ece" with length 3.
```
```
Input: s = "aa", k = 1
Output: 2
Explanation: The substring is "aa" with length 2.
```
### Constraints
* `1 <= s.length <= 5 * 10^4`
* `0 <= k <= 50`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_with_at_most_k_distinct_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_with_at_most_k_distinct_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) — each character enters and leaves the window once
# Space: O(k) — counter holds at most k + 1 distinct characters
def length_of_longest_substring_k_distinct(self, s: str, k: int) -> int:
if k == 0:
return 0
counts: dict[str, int] = {}
left = 0
best = 0
for right, ch in enumerate(s):
counts[ch] = counts.get(ch, 0) + 1
while len(counts) > k:
left_ch = s[left]
counts[left_ch] -= 1
if counts[left_ch] == 0:
del counts[left_ch]
left += 1
best = max(best, right - left + 1)
return best
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | ------------------------------------------------------ |
| O(n) — each character enters and leaves the window once | O(k) — counter holds at most k + 1 distinct characters |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Substring with At Most Two Distinct
Source: https://leetcode-py.wisl.dev/problems/longest-substring-with-at-most-two-distinct-characters
Tested Python solution for LeetCode 159 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 159, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 159 # by problem number
lcpy gen -s longest_substring_with_at_most_two_distinct_characters # by problem name
```
## Problem
Given a string `s`, return the length of the longest substring that contains at most two distinct characters.
### Examples
```
Input: s = "eceba"
Output: 3
Explanation: The substring is "ece" which its length is 3.
```
```
Input: s = "ccaabbb"
Output: 5
Explanation: The substring is "aabbb" which its length is 5.
```
### Constraints
* 1 \<= s.length \<= 10^5
* s consists of English letters
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_with_at_most_two_distinct_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_with_at_most_two_distinct_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def length_of_longest_substring_two_distinct(self, s: str) -> int:
count: dict[str, int] = {}
left = 0
longest = 0
for right, ch in enumerate(s):
count[ch] = count.get(ch, 0) + 1
while len(count) > 2:
left_ch = s[left]
count[left_ch] -= 1
if count[left_ch] == 0:
del count[left_ch]
left += 1
longest = max(longest, right - left + 1)
return longest
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Longest Substring Without Repeating Characters
Source: https://leetcode-py.wisl.dev/problems/longest-substring-without-repeating-characters
Tested Python solution for LeetCode 3 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 3, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-substring-without-repeating-characters/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3 # by problem number
lcpy gen -s longest_substring_without_repeating_characters # by problem name
```
## Problem
Given a string `s`, find the length of the **longest** **substring** without duplicate characters.
### Examples
```
Input: s = "abcabcbb"
Output: 3
```
**Explanation:** The answer is "abc", with the length of 3.
```
Input: s = "bbbbb"
Output: 1
```
**Explanation:** The answer is "b", with the length of 1.
```
Input: s = "pwwkew"
Output: 3
```
**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.
### Constraints
* 0 \<= s.length \<= 5 \* 10^4
* s consists of English letters, digits, symbols and spaces.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_without_repeating_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_substring_without_repeating_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(min(m, n)) where m is charset size
def length_of_longest_substring(self, s: str) -> int:
seen: set[str] = set()
left = max_len = 0
for right in range(len(s)):
while s[right] in seen:
seen.remove(s[left])
left += 1
seen.add(s[right])
max_len = max(max_len, right - left + 1)
return max_len
```
## Complexity
| Time | Space |
| ---- | ------------------------------------ |
| O(n) | O(min(m, n)) where m is charset size |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Longest Turbulent Subarray Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-turbulent-subarray
Tested Python solution for LeetCode 978 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 978, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/longest-turbulent-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 978 # by problem number
lcpy gen -s longest_turbulent_subarray # by problem name
```
## Problem
Given an integer array `arr`, return *the length of a maximum size turbulent subarray of* `arr`.
A subarray is **turbulent** if the comparison sign flips between each adjacent pair of elements in the subarray.
More formally, a subarray `[arr[i], arr[i + 1], ..., arr[j]]` of `arr` is said to be turbulent if and only if:
* For `i <= k < j`:
* `arr[k] > arr[k + 1]` when `k` is odd, and
* `arr[k] < arr[k + 1]` when `k` is even.
* Or, for `i <= k < j`:
* `arr[k] > arr[k + 1]` when `k` is even, and
* `arr[k] < arr[k + 1]` when `k` is odd.
### Examples
```
Input: arr = [9,4,2,10,7,8,8,1,9]
Output: 5
Explanation: arr[1] > arr[2] < arr[3] > arr[4] < arr[5]
```
```
Input: arr = [4,8,12,16]
Output: 2
```
```
Input: arr = [100]
Output: 1
```
### Constraints
* 1 \<= arr.length \<= 4 \* 10^4
* 0 \<= arr\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_turbulent_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_turbulent_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_turbulence_size(self, arr: list[int]) -> int:
n = len(arr)
best = 1
left = 0
last_sign = 0 # 1 for prev < next, -1 for prev > next, 0 for equal
for right in range(1, n):
if arr[right - 1] < arr[right]:
sign = 1
elif arr[right - 1] > arr[right]:
sign = -1
else:
sign = 0
if sign == 0:
best = max(best, right - left)
left = right
last_sign = 0
elif sign == last_sign:
best = max(best, right - left)
left = right - 1
last_sign = sign
else:
best = max(best, right - left + 1)
last_sign = sign
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Longest Uncommon Subsequence I Python Solution
Source: https://leetcode-py.wisl.dev/problems/longest-uncommon-subsequence-i
Tested Python solution for LeetCode 521 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 521, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/longest-uncommon-subsequence-i/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 521 # by problem number
lcpy gen -s longest_uncommon_subsequence_i # by problem name
```
## Problem
Given two strings `a` and `b`, return the length of the **longest uncommon subsequence** between `a` and `b`. If no such uncommon subsequence exists, return `-1`.
An **uncommon subsequence** between two strings is a string that is a subsequence of exactly one of them.
### Examples
```
Input: a = "aba", b = "cdc"
Output: 3
Explanation: One longest uncommon subsequence is "aba" because "aba" is a subsequence of "aba" but not "cdc".
Note that "cdc" is also a longest uncommon subsequence.
```
```
Input: a = "aaa", b = "bbb"
Output: 3
Explanation: The longest uncommon subsequences are "aaa" and "bbb".
```
```
Input: a = "aaa", b = "aaa"
Output: -1
Explanation: Every subsequence of string `a` is also a subsequence of string `b`.
```
### Constraints
* 1 \<= a.length, b.length \<= 100
* `a` and `b` consist of lower-case English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_uncommon_subsequence_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/longest_uncommon_subsequence_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(min(len(a), len(b)))
# Space: O(1)
def find_luslength(self, a: str, b: str) -> int:
# A whole string is always a subsequence of itself, so if a != b the
# longer (or either, on a tie) string cannot be a subsequence of the
# other: equal-length subsequences imply equality. If a == b every
# subsequence is shared, so nothing is uncommon.
return max(len(a), len(b)) if a != b else -1
```
## Complexity
| Time | Space |
| ---------------------- | ----- |
| O(min(len(a), len(b))) | O(1) |
## Tags
# Longest Uncommon Subsequence II
Source: https://leetcode-py.wisl.dev/problems/longest-uncommon-subsequence-ii
Tested Python solution for LeetCode 522 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 522, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/longest-uncommon-subsequence-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 522 # by problem number
lcpy gen -s longest_uncommon_subsequence_ii # by problem name
```
## Problem
Given an array of strings \strs\, return \the length of the \longest uncommon subsequence\ between them\. If the longest uncommon subsequence does not exist, return \-1\.
An \uncommon subsequence\ between an array of strings is a string that is a \subsequence of one string but not the others\.
A \subsequence\ of a string \s\ is a string that can be obtained after deleting any number of characters from \s\.
\
"abc"\ is a subsequence of \"aebdc"\ because you can delete the underlined characters in \"a\e\b\d\c"\ to get \"abc"\. Other subsequences of \"aebdc"\ include \"aebdc"\, \"aeb"\, and \""\ (empty string).\
```
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
```
\
```
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
```
```
Input: root = [1,2], p = 1, q = 2
Output: 1
```
### Constraints
* The number of nodes in the tree is in the range \[2, 10^5].
* -10^9 \<= Node.val \<= 10^9
* All Node.val are unique.
* p != q
* p and q will exist in the tree.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lowest_common_ancestor_of_a_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lowest_common_ancestor_of_a_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def lowest_common_ancestor(
self, root: TreeNode[int], p: TreeNode[int], q: TreeNode[int]
) -> TreeNode[int]:
result = self._lca(root, p, q)
assert result is not None
return result
def _lca(
self, root: TreeNode[int] | None, p: TreeNode[int], q: TreeNode[int]
) -> TreeNode[int] | None:
if root in (p, q) or not root:
return root
left = self._lca(root.left, p, q)
right = self._lca(root.right, p, q)
if left and right:
return root
return left or right
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Lowest Common Ancestor of a Binary Tree III
Source: https://leetcode-py.wisl.dev/problems/lowest-common-ancestor-of-a-binary-tree-iii
Tested Python solution for LeetCode 1650 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1650, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [Binary Tree](/catalog/topics/binary-tree), Lowest Common Ancestor. [View on LeetCode](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-iii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1650 # by problem number
lcpy gen -s lowest_common_ancestor_of_a_binary_tree_iii # by problem name
```
## Problem
Given two nodes of a binary tree `p` and `q`, return *their* *lowest common ancestor (LCA)*.
Each node will have a reference to its parent node. The definition for `Node` is below:
```
class Node {
public int val;
public Node left;
public Node right;
public Node parent;
}
```
According to the **definition of LCA on Wikipedia**: "The lowest common ancestor of two nodes p and q in a tree T is the lowest node that has both p and q as descendants (where we allow a node to be a descendant of itself)."
### Examples

```
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
```

```
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5 since a node can be a descendant of itself according to the LCA definition.
```
```
Input: root = [1,2], p = 1, q = 2
Output: 1
```
### Constraints
* The number of nodes in the tree is in the range `[2, 10^5]`.
* `-10^9 <= Node.val <= 10^9`
* All `Node.val` are **unique**.
* `p != q`
* `p` and `q` exist in the tree.
**Follow up:** Can you find the LCA without using any extra space (excluding recursion) and without knowing the root of the tree?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lowest_common_ancestor_of_a_binary_tree_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lowest_common_ancestor_of_a_binary_tree_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(self, val: int = 0) -> None:
self.val = val
self.left: Node | None = None
self.right: Node | None = None
self.parent: Node | None = None
class Solution:
# Time: O(h) where h is the height of the tree
# Space: O(1)
def lowest_common_ancestor(self, p: Node, q: Node) -> Node:
a: Node | None = p
b: Node | None = q
while a is not b:
a = q if a.parent is None else a.parent
b = p if b.parent is None else b.parent
assert a is not None
return a
```
## Complexity
| Time | Space |
| -------------------------------------- | ----- |
| O(h) where h is the height of the tree | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# LRU Cache Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/lru-cache
Tested Python solution for LeetCode 146 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 146, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list), [Design](/catalog/topics/design), Doubly-Linked List. [View on LeetCode](https://leetcode.com/problems/lru-cache/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 146 # by problem number
lcpy gen -s lru_cache # by problem name
```
## Problem
Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
Implement the `LRUCache` class:
* `LRUCache(int capacity)` Initialize the LRU cache with positive size capacity
* `int get(int key)` Return the value of the key if the key exists, otherwise return -1
* `void put(int key, int value)` Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key
The functions `get` and `put` must each run in `O(1)` average time complexity.
### Examples
```
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
```
### Constraints
* 1 \<= capacity \<= 3000
* 0 \<= key \<= 10^4
* 0 \<= value \<= 10^5
* At most 2 \* 10^5 calls will be made to get and put
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lru_cache/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lru_cache/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import OrderedDict
from leetcode_py.data_structures.doubly_list_node import DoublyListNode
class LRUCache:
# Space: O(capacity)
def __init__(self, capacity: int) -> None:
self.capacity = capacity
self.cache: OrderedDict[int, int] = OrderedDict()
# Time: O(1)
# Space: O(1)
def get(self, key: int) -> int:
if key not in self.cache:
return -1
# Move to end (most recent)
self.cache.move_to_end(key)
return self.cache[key]
# Time: O(1)
# Space: O(1)
def put(self, key: int, value: int) -> None:
if key in self.cache:
# Update existing and move to end
self.cache[key] = value
self.cache.move_to_end(key)
else:
# Add new
if len(self.cache) >= self.capacity:
# Remove LRU (first item)
self.cache.popitem(last=False)
self.cache[key] = value
class CacheNode(DoublyListNode[int]):
def __init__(self, key: int = 0, val: int = 0) -> None:
super().__init__(val)
self.key = key
class LRUCacheWithDoublyList:
def __init__(self, capacity: int) -> None:
self.capacity = capacity
self.cache: dict[int, CacheNode] = {}
# Dummy head and tail nodes
self.head = CacheNode()
self.tail = CacheNode()
self.head.next = self.tail
self.tail.prev = self.head
def _add_node(self, node: CacheNode) -> None:
"""Add node right after head"""
node.prev = self.head
node.next = self.head.next
if self.head.next:
self.head.next.prev = node
self.head.next = node
def _remove_node(self, node: CacheNode) -> None:
"""Remove node from list"""
if node.prev:
node.prev.next = node.next
if node.next:
node.next.prev = node.prev
def _move_to_head(self, node: CacheNode) -> None:
"""Move node to head (most recent)"""
self._remove_node(node)
self._add_node(node)
def _pop_tail(self) -> CacheNode:
"""Remove last node before tail"""
last_node = self.tail.prev
assert isinstance(last_node, CacheNode), "Expected CacheNode"
self._remove_node(last_node)
return last_node
def get(self, key: int) -> int:
node = self.cache.get(key)
if not node:
return -1
# Move to head (most recent)
self._move_to_head(node)
return node.val
def put(self, key: int, value: int) -> None:
node = self.cache.get(key)
if node:
# Update existing
node.val = value
self._move_to_head(node)
else:
# Add new
new_node = CacheNode(key, value)
if len(self.cache) >= self.capacity:
# Remove LRU
tail = self._pop_tail()
del self.cache[tail.key]
self.cache[key] = new_node
self._add_node(new_node)
```
## Complexity
| Time | Space |
| ---- | ----------- |
| O(1) | O(capacity) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Lucky Numbers in a Matrix Python Solution
Source: https://leetcode-py.wisl.dev/problems/lucky-numbers-in-a-matrix
Tested Python solution for LeetCode 1380 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1380, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/lucky-numbers-in-a-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1380 # by problem number
lcpy gen -s lucky_numbers_in_a_matrix # by problem name
```
## Problem
Given an `m x n` matrix of **distinct** numbers, return all **lucky numbers** in the matrix in **any** order.
A **lucky number** is an element of the matrix such that it is the minimum element in its row and maximum in its column.
### Examples
```
Input: matrix = [[3,7,8],[9,11,13],[15,16,17]]
Output: [15]
```
**Explanation:** 15 is the only lucky number since it is the minimum in its row and the maximum in its column.
```
Input: matrix = [[1,10,4,2],[9,3,8,7],[15,16,17,12]]
Output: [12]
```
**Explanation:** 12 is the only lucky number since it is the minimum in its row and the maximum in its column.
```
Input: matrix = [[7,8],[1,2]]
Output: [7]
```
### Constraints
* m == mat.length
* n == mat\[i].length
* 1 \<= n, m \<= 50
* 1 \<= matrix\[i]\[j] \<= 10^5
* All elements in the matrix are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lucky_numbers_in_a_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/lucky_numbers_in_a_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(n)
def lucky_numbers(self, matrix: list[list[int]]) -> list[int]:
col_max = [max(col) for col in zip(*matrix, strict=True)]
return [row_min for row in matrix if (row_min := min(row)) in col_max]
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(m \* n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Magic Squares In Grid Python Solution
Source: https://leetcode-py.wisl.dev/problems/magic-squares-in-grid
Tested Python solution for LeetCode 840 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 840, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/magic-squares-in-grid/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 840 # by problem number
lcpy gen -s magic_squares_in_grid # by problem name
```
## Problem
A `3 x 3` magic square is a `3 x 3` grid filled with **distinct** numbers **from** `1` **to** `9` such that each row, column, and both diagonals all have the same sum.
Given a `row x col` `grid` of integers, how many `3 x 3` magic square subgrids are there?
**Note:** while a magic square can only contain numbers from `1` to `9`, `grid` may contain numbers up to `15`.
### Examples
```
Input: grid = [[4,3,8,4],[9,5,1,9],[2,7,6,2]]
Output: 1
Explanation:
The following subgrid is a 3 x 3 magic square:
while this one is not:
In total, there is only one magic square inside the given grid.
```
```
Input: grid = [[8]]
Output: 0
```
### Constraints
* row == grid.length
* col == grid\[i].length
* 1 \<= row, col \<= 10
* 0 \<= grid\[i]\[j] \<= 15
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/magic_squares_in_grid/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/magic_squares_in_grid/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(rows * cols)
# Space: O(1)
def num_magic_squares_inside(self, grid: list[list[int]]) -> int:
rows, cols = len(grid), len(grid[0])
def is_magic(r: int, c: int) -> bool:
# A 3x3 magic square over 1..9 always has center 5 and sum 15
if grid[r + 1][c + 1] != 5:
return False
vals = [grid[r + i][c + j] for i in range(3) for j in range(3)]
if sorted(vals) != list(range(1, 10)):
return False
if any(sum(grid[r + i][c : c + 3]) != 15 for i in range(3)):
return False
if any(sum(grid[r + i][c + j] for i in range(3)) != 15 for j in range(3)):
return False
return (
grid[r][c] + grid[r + 1][c + 1] + grid[r + 2][c + 2] == 15
and grid[r][c + 2] + grid[r + 1][c + 1] + grid[r + 2][c] == 15
)
return sum(is_magic(r, c) for r in range(rows - 2) for c in range(cols - 2))
```
## Complexity
| Time | Space |
| --------------- | ----- |
| O(rows \* cols) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Magical String Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/magical-string
Tested Python solution for LeetCode 481 with 33 pytest cases. Generate a practice environment with lcpy.
LeetCode 481, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/magical-string/description/).
Generate this problem as a practice environment: tested reference solution, 33 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 481 # by problem number
lcpy gen -s magical_string # by problem name
```
## Problem
A magical string `s` consists of only `'1'` and `'2'` and obeys the following rules:
* Concatenating the sequence of lengths of its consecutive groups of identical characters `'1'` and `'2'` generates the string `s` itself.
The first few elements of `s` is `s = "1221121221221121122......"`. If we group the consecutive 1's and 2's in `s`, it will be `"1 22 11 2 1 22 1 22 11 2 11 22 ......"` and counting the occurrences of 1's or 2's in each group yields the sequence `"1 2 2 1 1 2 1 2 2 1 2 2 ......"`.
You can see that concatenating the occurrence sequence gives us `s` itself.
Given an integer `n`, return the number of 1's in the first n number in the magical string `s`.
### Examples
```
Input: n = 6
Output: 3
Explanation: The first 6 elements of magical string s is "122112" and it contains three 1's, so return 3.
```
```
Input: n = 1
Output: 1
```
### Constraints
* 1 \<= n \<= 10\5\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/magical_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/magical_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def magical_string(self, n: int) -> int:
if n <= 0:
return 0
s = [1, 2, 2]
i = 2
while len(s) < n:
nxt = s[-1] ^ 3
s.extend([nxt] * s[i])
i += 1
return s[:n].count(1)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Majority Element Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/majority-element
Tested Python solution for LeetCode 169 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 169, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Sorting](/catalog/topics/sorting), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/majority-element/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 169 # by problem number
lcpy gen -s majority_element # by problem name
```
## Problem
Given an array `nums` of size `n`, return the majority element.
The majority element is the element that appears more than `⌊n / 2⌋` times. You may assume that the majority element always exists in the array.
### Examples
```
Input: nums = [3,2,3]
Output: 3
```
```
Input: nums = [2,2,1,1,1,2,2]
Output: 2
```
### Constraints
* n == nums.length
* 1 \<= n \<= 5 \* 10^4
* -10^9 \<= nums\[i] \<= 10^9
**Follow-up:** Could you solve the problem in linear time and in O(1) space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/majority_element/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/majority_element/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
# Boyer-Moore Voting Algorithm
def majority_element(self, nums: list[int]) -> int:
candidate = 0
count = 0
for num in nums:
if count == 0:
candidate = num
count += 1 if num == candidate else -1
return candidate
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Majority Element II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/majority-element-ii
Tested Python solution for LeetCode 229 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 229, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/majority-element-ii/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 229 # by problem number
lcpy gen -s majority_element_ii # by problem name
```
## Problem
Given an integer array of size `n`, find all elements that appear more than `⌊n / 3⌋` times.
### Examples
```
Input: nums = [3,2,3]
Output: [3]
```
```
Input: nums = [1]
Output: [1]
```
```
Input: nums = [1,2]
Output: [1,2]
```
### Constraints
* 1 \<= nums.length \<= 5 \* 10^4
* -10^9 \<= nums\[i] \<= 10^9
**Follow up:** Could you solve the problem in linear time and in `O(1)` space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/majority_element_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/majority_element_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def majority_element(self, nums: list[int]) -> list[int]:
candidate1 = 0
candidate2 = 0
count1 = 0
count2 = 0
for num in nums:
if candidate1 == num:
count1 += 1
elif candidate2 == num:
count2 += 1
elif count1 == 0:
candidate1 = num
count1 = 1
elif count2 == 0:
candidate2 = num
count2 = 1
else:
count1 -= 1
count2 -= 1
threshold = len(nums) // 3
result: list[int] = []
if nums.count(candidate1) > threshold:
result.append(candidate1)
if candidate2 != candidate1 and nums.count(candidate2) > threshold:
result.append(candidate2)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Make Lexicographically Smallest Array by
Source: https://leetcode-py.wisl.dev/problems/make-lexicographically-smallest-array-by-swapping-elements
Tested Python solution for LeetCode 2948 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2948, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Union-Find](/catalog/topics/union-find), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/make-lexicographically-smallest-array-by-swapping-elements/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2948 # by problem number
lcpy gen -s make_lexicographically_smallest_array_by_swapping_elements # by problem name
```
## Problem
You are given a 0-indexed array of positive integers `nums` and a positive integer `limit`.
In one operation, you can choose any two indices `i` and `j` and swap `nums[i]` and `nums[j]` **if** `|nums[i] - nums[j]| <= limit`.
Return the lexicographically smallest array that can be obtained by performing the operation any number of times.
An array `a` is lexicographically smaller than an array `b` if in the first position where `a` and `b` differ, array `a` has an element that is less than the corresponding element in `b`. For example, the array `[2,10,3]` is lexicographically smaller than the array `[10,2,3]` because they differ at index `0` and `2 < 10`.
### Examples
```
Input: nums = [1,5,3,9,8], limit = 2
Output: [1,3,5,8,9]
Explanation: Apply the operation 2 times:
- Swap nums[1] with nums[2]. The array becomes [1,3,5,9,8]
- Swap nums[3] with nums[4]. The array becomes [1,3,5,8,9]
We cannot obtain a lexicographically smaller array by applying any more operations.
Note that it may be possible to get the same result by doing different operations.
```
```
Input: nums = [1,7,6,18,2,1], limit = 3
Output: [1,6,7,18,1,2]
Explanation: Apply the operation 3 times:
- Swap nums[1] with nums[2]. The array becomes [1,6,7,18,2,1]
- Swap nums[0] with nums[4]. The array becomes [2,6,7,18,1,1]
- Swap nums[0] with nums[5]. The array becomes [1,6,7,18,1,2]
We cannot obtain a lexicographically smaller array by applying any more operations.
```
```
Input: nums = [1,7,28,19,10], limit = 3
Output: [1,7,28,19,10]
Explanation: [1,7,28,19,10] is the lexicographically smallest array we can obtain because we cannot apply the operation on any two indices.
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= nums[i] <= 10^9`
* `1 <= limit <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_lexicographically_smallest_array_by_swapping_elements/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_lexicographically_smallest_array_by_swapping_elements/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from itertools import pairwise
class Solution:
# Time: O(n log n)
# Space: O(n)
def lexicographically_smallest_array(self, nums: list[int], limit: int) -> list[int]:
order = sorted(range(len(nums)), key=lambda i: nums[i])
result: list[int] = [0] * len(nums)
group: list[int] = [order[0]]
for prev, idx in pairwise(order):
if nums[idx] - nums[prev] > limit:
self._assign_group(result, group, nums)
group = []
group.append(idx)
self._assign_group(result, group, nums)
return result
def _assign_group(self, result: list[int], indices: list[int], nums: list[int]) -> None:
values = sorted(nums[i] for i in indices)
for pos, val in zip(sorted(indices), values, strict=True):
result[pos] = val
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Make Sum Divisible by P Python Solution
Source: https://leetcode-py.wisl.dev/problems/make-sum-divisible-by-p
Tested Python solution for LeetCode 1590 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1590, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/make-sum-divisible-by-p/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1590 # by problem number
lcpy gen -s make_sum_divisible_by_p # by problem name
```
## Problem
Given an array of positive integers \nums\, remove the \smallest\ subarray (possibly \empty\) such that the \sum\ of the remaining elements is divisible by \p\. It is \not\ allowed to remove the whole array.\
\Return \the length of the smallest subarray that you need to remove, or \\-1\\ if it's impossible\.\
A \subarray\ is defined as a contiguous block of elements in the array.\
### Examples ``` Input: nums = [3,1,4,2], p = 6 Output: 1 Explanation: The sum of the elements in nums is 10, which is not divisible by 6. We can remove the subarray [4], and the sum of the remaining elements is 6, which is divisible by 6. ``` ``` Input: nums = [6,3,5,2], p = 9 Output: 2 Explanation: We cannot remove a single element to get a sum divisible by 9. The best way is to remove the subarray [5,2], leaving us with [6,3] with sum 9. ``` ``` Input: nums = [1,2,3], p = 3 Output: 0 Explanation: Here the sum is 6. which is already divisible by 3. Thus we do not need to remove anything. ``` ### Constraints * 1 \<= nums.length \<= 10^5 * 1 \<= nums\[i] \<= 10^9 * 1 \<= p \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_sum_divisible_by_p/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_sum_divisible_by_p/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(min(n, p)) def min_subarray(self, nums: list[int], p: int) -> int: total = sum(nums) % p if total == 0: return 0 n = len(nums) last = {0: -1} cur = 0 best = n for i, num in enumerate(nums): cur = (cur + num) % p need = (cur - total) % p if need in last: best = min(best, i - last[need]) last[cur] = i return -1 if best == n else best ``` ## Complexity | Time | Space | | ---- | ------------ | | O(n) | O(min(n, p)) | ## Tags [NeetCode All](/catalog/neetcode). # Make The String Great Python Solution Source: https://leetcode-py.wisl.dev/problems/make-the-string-great Tested Python solution for LeetCode 1544 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 1544, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/make-the-string-great/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1544 # by problem number lcpy gen -s make_the_string_great # by problem name ``` ## Problem Given a string `s` of lower and upper case English letters. A good string is a string which doesn't have **two adjacent characters** `s[i]` and `s[i + 1]` where: * `0 <= i <= s.length - 2` * `s[i]` is a lower-case letter and `s[i + 1]` is the same letter but in upper-case or **vice-versa**. To make the string good, you can choose **two adjacent** characters that make the string bad and remove them. You can keep doing this until the string becomes good. Return *the string* after making it good. The answer is guaranteed to be unique under the given constraints. **Notice** that an empty string is also good. ### Examples ``` Input: s = "leEeetcode" Output: "leetcode" ``` **Explanation:** In the first step, either you choose i = 1 or i = 2, both will result "leEeetcode" to be reduced to "leetcode". ``` Input: s = "abBAcC" Output: "" ``` **Explanation:** We have many possible scenarios, and all lead to the same answer. For example: "abBAcC" --> "aAcC" --> "cC" --> "" "abBAcC" --> "abBA" --> "aA" --> "" ``` Input: s = "s" Output: "s" ``` ### Constraints * `1 <= s.length <= 100` * `s` contains only lower and upper case English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_the_string_great/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_the_string_great/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def make_good(self, s: str) -> str: stack: list[str] = [] for ch in s: if stack and stack[-1].lower() == ch.lower() and stack[-1] != ch: stack.pop() else: stack.append(ch) return "".join(stack) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Make Two Arrays Equal by Reversing Subarrays Source: https://leetcode-py.wisl.dev/problems/make-two-arrays-equal-by-reversing-subarrays Tested Python solution for LeetCode 1460 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 1460, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/make-two-arrays-equal-by-reversing-subarrays/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1460 # by problem number lcpy gen -s make_two_arrays_equal_by_reversing_subarrays # by problem name ``` ## Problem You are given two integer arrays of equal length `target` and `arr`. In one step, you can select any **non-empty subarray** of `arr` and reverse it. You are allowed to make any number of steps. Return `true` if you can make `arr` equal to `target` or `false` otherwise. ### Examples ``` Input: target = [1,2,3,4], arr = [2,4,1,3] Output: true Explanation: You can follow the next steps to convert arr to target: 1- Reverse subarray [2,4,1], arr becomes [1,4,2,3] 2- Reverse subarray [4,2], arr becomes [1,2,4,3] 3- Reverse subarray [4,3], arr becomes [1,2,3,4] There are multiple ways to convert arr to target, this is not the only way to do so. ``` ``` Input: target = [7], arr = [7] Output: true Explanation: arr is equal to target without any reverses. ``` ``` Input: target = [3,7,9], arr = [3,7,11] Output: false Explanation: arr does not have value 9 and it can never be converted to target. ``` ### Constraints * target.length == arr.length * 1 \<= target.length \<= 1000 * 1 \<= target\[i] \<= 1000 * 1 \<= arr\[i] \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_two_arrays_equal_by_reversing_subarrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/make_two_arrays_equal_by_reversing_subarrays/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n) # Space: O(n) def can_be_equal(self, target: list[int], arr: list[int]) -> bool: return Counter(target) == Counter(arr) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Making A Large Island Python Solution Source: https://leetcode-py.wisl.dev/problems/making-a-large-island Tested Python solution for LeetCode 827 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 827, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/making-a-large-island/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 827 # by problem number lcpy gen -s making_a_large_island # by problem name ``` ## Problem You are given an `n x n` binary matrix `grid`. You are allowed to change **at most one** `0` to be `1`. Return *the size of the largest **island** in* `grid` *after applying this operation*. An **island** is a 4-directionally connected group of `1`s. ### Examples ``` Input: grid = [[1,0],[0,1]] Output: 3 Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3. ``` ``` Input: grid = [[1,1],[1,0]] Output: 4 Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4. ``` ``` Input: grid = [[1,1],[1,1]] Output: 4 Explanation: Can't change any 0 to 1, only one island with area = 4. ``` ### Constraints * n == grid.length * n == grid\[i].length * 1 \<= n \<= 500 * grid\[i]\[j] is either 0 or 1. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/making_a_large_island/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/making_a_large_island/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n^2) def largest_island(self, grid: list[list[int]]) -> int: n = len(grid) sizes = [0, 0] # island ids start at 2 so 0/1 stay sentinel-free label = [[0] * n for _ in range(n)] for r in range(n): for c in range(n): if grid[r][c] == 0 or label[r][c]: continue island_id = len(sizes) stack = [(r, c)] size = 0 while stack: x, y = stack.pop() if not (0 <= x < n and 0 <= y < n) or grid[x][y] != 1 or label[x][y]: continue label[x][y] = island_id size += 1 stack.extend(((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1))) sizes.append(size) best = max(sizes) for r in range(n): for c in range(n): if grid[r][c] != 0: continue nbr_ids = set() for x, y in ((r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)): if 0 <= x < n and 0 <= y < n and grid[x][y] == 1: nbr_ids.add(label[x][y]) best = max(best, 1 + sum(sizes[i] for i in nbr_ids)) return best ``` ## Complexity | Time | Space | | ------ | ------ | | O(n^2) | O(n^2) | ## Tags [NeetCode All](/catalog/neetcode). # Map Sum Pairs Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/map-sum-pairs Tested Python solution for LeetCode 677 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 677, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Design](/catalog/topics/design), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/map-sum-pairs/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 677 # by problem number lcpy gen -s map_sum_pairs # by problem name ``` ## Problem Design a map that allows you to do the following: * Maps a string key to a given value. * Returns the sum of the values that have a key with a prefix equal to a given string. Implement the `MapSum` class: * `MapSum()` Initializes the `MapSum` object. * `void insert(String key, int val)` Inserts the `key-val` pair into the map. If the `key` already existed, the original `key-value` pair will be overridden to the new one. * `int sum(string prefix)` Returns the sum of all the pairs' value whose `key` starts with the `prefix`. ### Examples ``` Input ["MapSum", "insert", "sum", "insert", "sum"] [[], ["apple", 3], ["ap"], ["app", 2], ["ap"]] Output [null, null, 3, null, 5] ``` **Explanation** ``` MapSum mapSum = new MapSum(); mapSum.insert("apple", 3); mapSum.sum("ap"); // return 3 (apple = 3) mapSum.insert("app", 2); mapSum.sum("ap"); // return 5 (apple + app = 3 + 2 = 5) ``` ### Constraints * `1 <= key.length, prefix.length <= 50` * `key` and `prefix` consist of only lowercase English letters. * `1 <= val <= 1000` * At most `50` calls will be made to `insert` and `sum`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/map_sum_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/map_sum_pairs/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from __future__ import annotations class MapSum: # Each node holds the sum of the values of every key passing through it. # Re-inserting a key applies only the value delta to the affected path. def __init__(self) -> None: self.children: dict[str, MapSum] = {} self.total = 0 self.key_values: dict[str, int] = {} # Time: O(k) where k is the key length # Space: O(k) def insert(self, key: str, val: int) -> None: delta = val - self.key_values.get(key, 0) self.key_values[key] = val node: MapSum = self for char in key: node = node.children.setdefault(char, MapSum()) node.total += delta # Time: O(p) where p is the prefix length # Space: O(1) def sum(self, prefix: str) -> int: node: MapSum | None = self for char in prefix: node = node.children.get(char) if node is None: return 0 assert node is not None return node.total ``` ## Complexity | Time | Space | | ------------------------------ | ----- | | O(k) where k is the key length | O(k) | ## Tags # Masking Personal Information Python Solution Source: https://leetcode-py.wisl.dev/problems/masking-personal-information Tested Python solution for LeetCode 831 with 23 pytest cases. Generate a practice environment with lcpy. LeetCode 831, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/masking-personal-information/description/). Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 831 # by problem number lcpy gen -s masking_personal_information # by problem name ``` ## Problem You are given a personal information string `s`, representing either an **email address** or a **phone number**. Return *the **masked** personal information using the below rules*. \**Email address:**\ An email address is: * A **name** consisting of **at least** two uppercase and lowercase English letters, followed by * The `'@'` symbol, followed by * The **domain** consisting of uppercase and lowercase English letters with a dot `'.'` somewhere in the middle (not the first or last character). To mask an email: * The uppercase letters in the **name** and **domain** must be converted to lowercase letters. * The middle letters of the **name** (i.e., all but the first and last letters) must be replaced by 5 asterisks `"*****"`. \**Phone number:**\ A phone number is formatted as follows: * The phone number contains 10-13 digits. * The last 10 digits make up the **local number**. * The remaining 0-3 digits, in the beginning, make up the **country code**. * **Separation characters** from the set `{'+', '-', '(', ')', ' '}` separate the above digits in some way. To mask a phone number: * Remove all **separation characters**. * The masked phone number should have the form: * `"***-***-XXXX"` if the country code has 0 digits. * `"+*-***-***-XXXX"` if the country code has 1 digit. * `"+**-***-***-XXXX"` if the country code has 2 digits. * `"+***-***-***-XXXX"` if the country code has 3 digits. * `"XXXX"` is the last 4 digits of the **local number**. ### Examples ``` Input: s = "LeetCode@LeetCode.com" Output: "l*****e@leetcode.com" Explanation: s is an email address. The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks. ``` ``` Input: s = "AB@qq.com" Output: "a*****b@qq.com" Explanation: s is an email address. The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks. Note that even though "ab" is 2 characters, it still must have 5 asterisks in the middle. ``` ``` Input: s = "1(234)567-890" Output: "***-***-7890" Explanation: s is a phone number. There are 10 digits, so the local number is 10 digits and the country code is 0 digits. Thus, the resulting masked number is "***-***-7890". ``` ### Constraints * s is either a valid email or a phone number. * If s is an email: * 8 \<= s.length \<= 40 * s consists of uppercase and lowercase English letters and exactly one '@' symbol and '.' symbol. * If s is a phone number: * 10 \<= s.length \<= 20 * s consists of digits, spaces, and the symbols '(', ')', '-', and '+'. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/masking_personal_information/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/masking_personal_information/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def mask_pii(self, s: str) -> str: if "@" in s: name, domain = s.split("@") lower_name = name.lower() return f"{lower_name[0]}*****{lower_name[-1]}@{domain.lower()}" digits = [c for c in s if c.isdigit()] country = len(digits) - 10 tail = "".join(digits[-4:]) prefix = "+" + "*" * country if country else "" return f"{prefix}-***-***-{tail}" if prefix else f"***-***-{tail}" ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Matchsticks to Square Python Solution Source: https://leetcode-py.wisl.dev/problems/matchsticks-to-square Tested Python solution for LeetCode 473 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 473, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/matchsticks-to-square/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 473 # by problem number lcpy gen -s matchsticks_to_square # by problem name ``` ## Problem You are given an integer array `matchsticks` where `matchsticks[i]` is the length of the `ith` matchstick. You want to use **all the matchsticks** to make one square. You **should not break** any stick, but you can link them up, and each matchstick must be used **exactly one time**. Return `true` if you can make this square and `false` otherwise. ### Examples  ``` Input: matchsticks = [1,1,2,2,2] Output: true Explanation: You can form a square with length 2, one side of the square came two sticks with length 1. ``` ``` Input: matchsticks = [3,3,3,3,4] Output: false Explanation: You cannot find a way to form a square with all the matchsticks. ``` ### Constraints * 1 \<= matchsticks.length \<= 15 * 1 \<= matchsticks\[i] \<= 10^8 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/matchsticks_to_square/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/matchsticks_to_square/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(4^n) backtracking in the worst case (pruned heavily in practice) # Space: O(n) recursion stack def makesquare(self, matchsticks: list[int]) -> bool: total = sum(matchsticks) if total % 4 != 0: return False side = total // 4 # Sort descending so larger sticks fail fast and prune the search early. sticks = sorted(matchsticks, reverse=True) if sticks[0] > side: return False sides = [0, 0, 0, 0] def backtrack(index: int) -> bool: if index == len(sticks): return all(s == side for s in sides) stick = sticks[index] for i in range(4): if sides[i] + stick > side: continue # Skip duplicate side fills to avoid symmetric permutations. if i > 0 and sides[i] == sides[i - 1]: continue sides[i] += stick if backtrack(index + 1): return True sides[i] -= stick return False return backtrack(0) ``` ## Complexity | Time | Space | | ------------------------------------------------------------------ | -------------------- | | O(4^n) backtracking in the worst case (pruned heavily in practice) | O(n) recursion stack | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Matrix Diagonal Sum Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/matrix-diagonal-sum Tested Python solution for LeetCode 1572 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 1572, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/matrix-diagonal-sum/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1572 # by problem number lcpy gen -s matrix_diagonal_sum # by problem name ``` ## Problem Given a square matrix `mat`, return the sum of the matrix diagonals. Only include the sum of all the elements on the primary diagonal and all the elements on the secondary diagonal that are not part of the primary diagonal. ### Examples  ``` Input: mat = [[1,2,3], [4,5,6], [7,8,9]] Output: 25 Explanation: Diagonals sum: 1 + 5 + 9 + 3 + 7 = 25 Notice that element mat[1][1] = 5 is counted only once. ``` ``` Input: mat = [[1,1,1,1], [1,1,1,1], [1,1,1,1], [1,1,1,1]] Output: 8 ``` ``` Input: mat = [[5]] Output: 5 ``` ### Constraints * n == mat.length == mat\[i].length * 1 \<= n \<= 100 * 1 \<= mat\[i]\[j] \<= 100 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/matrix_diagonal_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/matrix_diagonal_sum/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def diagonal_sum(self, mat: list[list[int]]) -> int: total = 0 n = len(mat) for i in range(n): total += mat[i][i] if i != n - 1 - i: total += mat[i][n - 1 - i] return total ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Max Area of Island Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/max-area-of-island Tested Python solution for LeetCode 695 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 695, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/max-area-of-island/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 695 # by problem number lcpy gen -s max_area_of_island # by problem name ``` ## Problem You are given an `m x n` binary matrix `grid`. An island is a group of `1`'s (representing land) connected **4-directionally** (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. The **area** of an island is the number of cells with a value `1` in the island. Return *the maximum **area** of an island in* `grid`. If there is no island, return `0`. ### Examples  ``` Input: grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]] Output: 6 Explanation: The answer is not 11, because the island must be connected 4-directionally. ``` ``` Input: grid = [[0,0,0,0,0,0,0,0]] Output: 0 ``` ### Constraints * m == grid.length * n == grid\[i].length * 1 \<= m, n \<= 50 * grid\[i]\[j] is either 0 or 1. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_area_of_island/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_area_of_island/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(m * n) def max_area_of_island(self, grid: list[list[int]]) -> int: if not grid or not grid[0]: return 0 rows, cols = len(grid), len(grid[0]) def dfs(row: int, col: int) -> int: if row < 0 or row >= rows or col < 0 or col >= cols or grid[row][col] == 0: return 0 grid[row][col] = 0 # Mark visited by sinking area = 1 area += dfs(row + 1, col) area += dfs(row - 1, col) area += dfs(row, col + 1) area += dfs(row, col - 1) return area max_area = 0 for row in range(rows): for col in range(cols): if grid[row][col] == 1: max_area = max(max_area, dfs(row, col)) return max_area ``` ## Complexity | Time | Space | | --------- | --------- | | O(m \* n) | O(m \* n) | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Max Chunks To Make Sorted Python Solution Source: https://leetcode-py.wisl.dev/problems/max-chunks-to-make-sorted Tested Python solution for LeetCode 769 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 769, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/max-chunks-to-make-sorted/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 769 # by problem number lcpy gen -s max_chunks_to_make_sorted # by problem name ``` ## Problem You are given an integer array `arr` of length `n` that represents a permutation of the integers in the range `[0, n - 1]`. We split `arr` into some number of chunks (i.e., partitions), and individually sort each chunk. After concatenating them, the result should equal the sorted array. Return *the largest number of chunks we can make to sort the array*. ### Examples ``` Input: arr = [4,3,2,1,0] Output: 1 Explanation: Splitting into two or more chunks will not return the required result. For example, splitting into [4, 3], [2, 1, 0] will result in [3, 4, 0, 1, 2], which isn't sorted. ``` ``` Input: arr = [1,0,2,3,4] Output: 4 Explanation: We can split into two chunks, such as [1, 0], [2, 3, 4]. However, splitting into [1, 0], [2], [3], [4] is the highest number of chunks possible. ``` ### Constraints * n == arr.length * 1 \<= n \<= 10 * 0 \<= arr\[i] \< n * All the elements of arr are unique. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_chunks_to_make_sorted/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_chunks_to_make_sorted/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_chunks_to_sorted(self, arr: list[int]) -> int: chunks = 0 mx = 0 for i, v in enumerate(arr): mx = max(mx, v) if mx == i: chunks += 1 return chunks ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Max Chunks To Make Sorted II Python Solution Source: https://leetcode-py.wisl.dev/problems/max-chunks-to-make-sorted-ii Tested Python solution for LeetCode 768 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 768, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/max-chunks-to-make-sorted-ii/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 768 # by problem number lcpy gen -s max_chunks_to_make_sorted_ii # by problem name ``` ## Problem You are given an integer array `arr`. We split `arr` into some number of `chunks` (i.e., partitions), and individually sort each chunk. After concatenating them, the result should equal the sorted array. Return *the largest number of chunks we can make to sort the array*. ### Examples ``` Input: arr = [5,4,3,2,1] Output: 1 Explanation: Splitting into two or more chunks will not return the required result. For example, splitting into [5, 4], [3, 2, 1] will result in [4, 5, 1, 2, 3], which isn't sorted. ``` ``` Input: arr = [2,1,3,4,4] Output: 4 Explanation: We can split into two chunks, such as [2, 1], [3, 4, 4]. However, splitting into [2, 1], [3], [4], [4] is the highest number of chunks possible. ``` ### Constraints * 1 \<= arr.length \<= 2000 * 0 \<= arr\[i] \<= 10^8 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_chunks_to_make_sorted_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_chunks_to_make_sorted_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def max_chunks_to_sorted(self, arr: list[int]) -> int: n = len(arr) prefix_max = [0] * n prefix_max[0] = arr[0] for i in range(1, n): prefix_max[i] = max(prefix_max[i - 1], arr[i]) suffix_min = [0] * n suffix_min[n - 1] = arr[n - 1] for i in range(n - 2, -1, -1): suffix_min[i] = min(suffix_min[i + 1], arr[i]) chunks = 1 for i in range(n - 1): if prefix_max[i] <= suffix_min[i + 1]: chunks += 1 return chunks ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Max Consecutive Ones Python Solution Source: https://leetcode-py.wisl.dev/problems/max-consecutive-ones Tested Python solution for LeetCode 485 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 485, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/max-consecutive-ones/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 485 # by problem number lcpy gen -s max_consecutive_ones # by problem name ``` ## Problem Given a binary array `nums`, return *the maximum number of consecutive* `1`*'s in the array*. ### Examples ``` Input: nums = [1,1,0,1,1,1] Output: 3 Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3. ``` ``` Input: nums = [1,0,1,1,0,1] Output: 2 ``` ### Constraints * `1 <= nums.length <= 10^5` * `nums[i]` is either `0` or `1`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_consecutive_ones/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_consecutive_ones/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def find_max_consecutive_ones(self, nums: list[int]) -> int: best = 0 current = 0 for num in nums: if num == 1: current += 1 best = max(best, current) else: current = 0 return best ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Max Consecutive Ones II Python Solution Source: https://leetcode-py.wisl.dev/problems/max-consecutive-ones-ii Tested Python solution for LeetCode 487 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 487, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/max-consecutive-ones-ii/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 487 # by problem number lcpy gen -s max_consecutive_ones_ii # by problem name ``` ## Problem Given a binary array `nums`, return the maximum number of consecutive `1`'s in the array if you can flip at most one `0`. **Follow up:** What if the input numbers come in one by one as an infinite stream? In other words, you can't store all numbers coming from the stream as it's too large to hold in memory. Could you solve it efficiently? ### Examples ``` Input: nums = [1,0,1,1,0] Output: 4 Explanation: - If we flip the first zero, nums becomes [1,1,1,1,0] and we have 4 consecutive ones. - If we flip the second zero, nums becomes [1,0,1,1,1] and we have 3 consecutive ones. The max number of consecutive ones is 4. ``` ``` Input: nums = [1,0,1,1,0,1] Output: 4 Explanation: - If we flip the first zero, nums becomes [1,1,1,1,0,1] and we have 4 consecutive ones. - If we flip the second zero, nums becomes [1,0,1,1,1,1] and we have 4 consecutive ones. The max number of consecutive ones is 4. ``` ### Constraints * `1 <= nums.length <= 10^5` * `nums[i]` is either `0` or `1`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_consecutive_ones_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_consecutive_ones_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def find_max_ones(self, nums: list[int]) -> int: left = zeros = best = 0 for right, value in enumerate(nums): if value == 0: zeros += 1 while zeros > 1: if nums[left] == 0: zeros -= 1 left += 1 best = max(best, right - left + 1) return best ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Max Consecutive Ones III Python Solution Source: https://leetcode-py.wisl.dev/problems/max-consecutive-ones-iii Tested Python solution for LeetCode 1004 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 1004, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Sliding Window](/catalog/topics/sliding-window), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/max-consecutive-ones-iii/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1004 # by problem number lcpy gen -s max_consecutive_ones_iii # by problem name ``` ## Problem 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. ### Examples ``` Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2 Output: 6 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. ``` ``` Input: nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3 Output: 10 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. ``` ### Constraints * `1 <= nums.length <= 10^5` * `nums[i]` is either `0` or `1`. * `0 <= k <= nums.length` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_consecutive_ones_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_consecutive_ones_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def longest_ones(self, nums: list[int], k: int) -> int: left = 0 zeros = 0 best = 0 for right, num in enumerate(nums): if num == 0: zeros += 1 while zeros > k: if nums[left] == 0: zeros -= 1 left += 1 best = max(best, right - left + 1) return best ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Max Increase to Keep City Skyline Source: https://leetcode-py.wisl.dev/problems/max-increase-to-keep-city-skyline Tested Python solution for LeetCode 807 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 807, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/max-increase-to-keep-city-skyline/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 807 # by problem number lcpy gen -s max_increase_to_keep_city_skyline # by problem name ``` ## Problem There is a city composed of `n x n` blocks, where each block contains a single building shaped like a vertical square prism. You are given a **0-indexed** `n x n` integer matrix `grid` where `grid[r][c]` represents the **height** of the building located in the block at row `r` and column `c`. A city's **skyline** is the outer contour formed by all the building when viewing the side of the city from a distance. The **skyline** from each cardinal direction north, east, south, and west may be different. We are allowed to increase the height of **any number of buildings by any amount** (the amount can be different per building). The height of a `0`-height building can also be increased. However, increasing the height of a building should **not** affect the city's **skyline** from any cardinal direction. Return *the **maximum total sum** that the height of the buildings can be increased by **without** changing the city's **skyline** from any cardinal direction*. ### Examples  ``` Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]] Output: 35 Explanation: The building heights are shown in the center of the above image. The skylines when viewed from each cardinal direction are drawn in red. The grid after increasing the height of buildings without affecting skylines is: gridNew = [ [8, 4, 8, 7], [7, 4, 7, 7], [9, 4, 8, 7], [3, 3, 3, 3] ] ``` ``` Input: grid = [[0,0,0],[0,0,0],[0,0,0]] Output: 0 Explanation: Increasing the height of any building will result in the skyline changing. ``` ### Constraints * n == grid.length * n == grid\[r].length * 2 \<= n \<= 50 * 0 \<= grid\[r]\[c] \<= 100 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_increase_to_keep_city_skyline/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_increase_to_keep_city_skyline/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n) def max_increase_keeping_skyline(self, grid: list[list[int]]) -> int: row_max = [max(row) for row in grid] col_max = [max(col) for col in zip(*grid, strict=True)] return sum( min(row_max[r], col_max[c]) - grid[r][c] for r, row in enumerate(grid) for c in range(len(row)) ) ``` ## Complexity | Time | Space | | ------ | ----- | | O(n^2) | O(n) | ## Tags # Max Points on a Line Python Solution Source: https://leetcode-py.wisl.dev/problems/max-points-on-a-line Tested Python solution for LeetCode 149 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 149, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry). [View on LeetCode](https://leetcode.com/problems/max-points-on-a-line/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 149 # by problem number lcpy gen -s max_points_on_a_line # by problem name ``` ## Problem Given an array of `points` where `points[i] = [xi, yi]` represents a point on the X-Y plane, return the maximum number of points that lie on the same straight line. ### Examples  ``` Input: points = [[1,1],[2,2],[3,3]] Output: 3 ```  ``` Input: points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] Output: 4 ``` ### Constraints * 1 \<= points.length \<= 300 * points\[i].length == 2 * -10^4 \<= xi, yi \<= 10^4 * All the points are unique. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_points_on_a_line/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_points_on_a_line/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import math from collections import defaultdict class Solution: # Time: O(n^2) where n is the number of points # Space: O(n) for the hash map def max_points(self, points: list[list[int]]) -> int: if len(points) <= 2: return len(points) max_count = 0 for i in range(len(points)): slope_count: defaultdict[tuple[int, int], int] = defaultdict(int) duplicate = 0 current_max = 0 x1, y1 = points[i] for j in range(i + 1, len(points)): x2, y2 = points[j] # Handle duplicate points if x1 == x2 and y1 == y2: duplicate += 1 continue # Calculate slope as a reduced fraction (dx, dy) dx = x2 - x1 dy = y2 - y1 # Reduce to lowest terms using GCD gcd_val = math.gcd(dx, dy) if gcd_val != 0: dx //= gcd_val dy //= gcd_val # Normalize the direction (ensure consistent representation) if dx < 0: dx = -dx dy = -dy elif dx == 0: dy = abs(dy) slope = (dx, dy) slope_count[slope] += 1 current_max = max(current_max, slope_count[slope]) max_count = max(max_count, current_max + duplicate + 1) return max_count ``` ## Complexity | Time | Space | | -------------------------------------- | --------------------- | | O(n^2) where n is the number of points | O(n) for the hash map | ## Tags [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Max Stack Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/max-stack Tested Python solution for LeetCode 716 with 61 pytest cases. Generate a practice environment with lcpy. LeetCode 716, [Hard](/catalog/hard). Topics: [Linked List](/catalog/topics/linked-list), [Stack](/catalog/topics/stack), [Design](/catalog/topics/design), Doubly-Linked List, [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/max-stack/description/). Generate this problem as a practice environment: tested reference solution, 61 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 716 # by problem number lcpy gen -s max_stack # by problem name ``` ## Problem Design a max stack data structure that supports the stack operations and supports finding the stack's maximum element. Implement the `MaxStack` class: * `MaxStack()` Initializes the stack object. * `void push(int x)` Pushes element x onto the stack. * `int pop()` Removes the element on top of the stack and returns it. * `int top()` Gets the element on the top of the stack without removing it. * `int peekMax()` Retrieves the maximum element in the stack without removing it. * `int popMax()` Retrieves the maximum element in the stack and removes it. If there is more than one maximum element, only remove the top-most one. You must come up with a solution that supports `O(1)` for each `top` call and `O(logn)` for each other call. ### Examples ``` Input ['MaxStack', 'push', 'push', 'push', 'top', 'pop_max', 'top', 'peek_max', 'pop', 'top'] [[], [5], [1], [5], [], [], [], [], [], []] Output [null, null, null, null, 5, 5, 1, 5, 1, 5] ``` ### Constraints * -10^7 \<= x \<= 10^7 * At most 10^5 calls will be made to push, pop, top, peek\_max, and pop\_max. * There will be at least one element in the stack when pop, top, peek\_max, or pop\_max is called. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_stack/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_stack/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import heapq from itertools import count class Node: def __init__(self, val: int = 0): self.val = val self.seq = 0 self.prev: Node = self self.next: Node = self class DoubleLinkedList: def __init__(self): self.head = Node() self.tail = Node() self.head.next = self.tail self.tail.prev = self.head def append(self, val: int) -> Node: node = Node(val) node.next = self.tail node.prev = self.tail.prev self.tail.prev = node node.prev.next = node return node @staticmethod def remove(node: Node) -> Node: node.prev.next = node.next node.next.prev = node.prev node.prev = node.next = node return node def pop(self) -> Node: return self.remove(self.tail.prev) def peek(self) -> int: return self.tail.prev.val class MaxStack: # Time: push O(log n), pop O(n), top O(1), # peek_max O(log n) amortized, pop_max O(log n) amortized # Space: O(n) def __init__(self): self.stk = DoubleLinkedList() self.sl: list[tuple[int, int, Node]] = [] self.seq = count() def push(self, x: int) -> None: node = self.stk.append(x) node.seq = next(self.seq) heapq.heappush(self.sl, (-x, -node.seq, node)) def pop(self) -> int: node = self.stk.pop() return node.val def top(self) -> int: return self.stk.peek() def peek_max(self) -> int: while True: neg_val, _, node = self.sl[0] if node.prev is not node: return -neg_val heapq.heappop(self.sl) def pop_max(self) -> int: while True: neg_val, _, node = heapq.heappop(self.sl) if node.prev is not node: break DoubleLinkedList.remove(node) return -neg_val ``` ## Complexity | Time | Space | | ---------------------------------- | ----- | | push O(log n), pop O(n), top O(1), | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Max Sum of Rectangle No Larger Than K Source: https://leetcode-py.wisl.dev/problems/max-sum-of-rectangle-no-larger-than-k Tested Python solution for LeetCode 363 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 363, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Matrix](/catalog/topics/matrix), [Prefix Sum](/catalog/topics/prefix-sum), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 363 # by problem number lcpy gen -s max_sum_of_rectangle_no_larger_than_k # by problem name ``` ## Problem Given an \m x n\ matrix \matrix\ and an integer \k\, return \the max sum of a rectangle in the matrix such that its sum is no larger than\ \k\.
It is \guaranteed\ that there will be a rectangle with a sum no larger than \k\.
### Examples

```
Input: matrix = [[1,0,1],[0,-2,3]], k = 2
Output: 2
Explanation: Because the sum of the blue rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).
```
```
Input: matrix = [[2,2,-1]], k = 3
Output: 3
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m, n \<= 100
* -100 \<= matrix\[i]\[j] \<= 100
* -10^5 \<= k \<= 10^5
**Follow up:** What if the number of rows is much larger than the number of columns?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_sum_of_rectangle_no_larger_than_k/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/max_sum_of_rectangle_no_larger_than_k/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_left, insort
class Solution:
# Time: O(m^2 * n * log n)
# Space: O(n)
def max_sum_submatrix(self, matrix: list[list[int]], k: int) -> int:
rows, cols = len(matrix), len(matrix[0])
best = -(10**9)
for top in range(rows):
col_sums = [0] * cols
for bottom in range(top, rows):
row = matrix[bottom]
for c in range(cols):
col_sums[c] += row[c]
sorted_sums = [0]
running = 0
for s in col_sums:
running += s
i = bisect_left(sorted_sums, running - k)
if i < len(sorted_sums):
best = max(best, running - sorted_sums[i])
insort(sorted_sums, running)
return best
```
## Complexity
| Time | Space |
| -------------------- | ----- |
| O(m^2 \* n \* log n) | O(n) |
## Tags
# Maximal Rectangle Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/maximal-rectangle
Tested Python solution for LeetCode 85 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 85, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Stack](/catalog/topics/stack), [Matrix](/catalog/topics/matrix), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/maximal-rectangle/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 85 # by problem number
lcpy gen -s maximal_rectangle # by problem name
```
## Problem
Given a \rows x cols\ binary \matrix\ filled with \0\'s and \1\'s, find the largest rectangle containing only \1\'s and return \its area\.
### Examples

```
Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.
```
```
Input: matrix = [["0"]]
Output: 0
```
```
Input: matrix = [["1"]]
Output: 1
```
### Constraints
* rows == matrix.length
* cols == matrix\[i].length
* 1 \<= rows, cols \<= 200
* matrix\[i]\[j] is '0' or '1'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximal_rectangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximal_rectangle/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(rows * cols)
# Space: O(cols)
def maximal_rectangle(self, matrix: list[list[str]]) -> int:
if not matrix or not matrix[0]:
return 0
cols = len(matrix[0])
heights = [0] * cols
best = 0
for row in matrix:
for j, val in enumerate(row):
heights[j] = heights[j] + 1 if val == "1" else 0
best = max(best, self.largest_rectangle_area(heights))
return best
def largest_rectangle_area(self, heights: list[int]) -> int:
stack: list[int] = []
best = 0
extended = [*heights, 0]
for i, h in enumerate(extended):
while stack and extended[stack[-1]] >= h:
height = extended[stack.pop()]
left = stack[-1] if stack else -1
best = max(best, height * (i - left - 1))
stack.append(i)
return best
```
## Complexity
| Time | Space |
| --------------- | ------- |
| O(rows \* cols) | O(cols) |
## Tags
# Maximal Score After Applying K Operations
Source: https://leetcode-py.wisl.dev/problems/maximal-score-after-applying-k-operations
Tested Python solution for LeetCode 2530 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 2530, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/maximal-score-after-applying-k-operations/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2530 # by problem number
lcpy gen -s maximal_score_after_applying_k_operations # by problem name
```
## Problem
You are given a 0-indexed integer array `nums` and an integer `k`. You have a starting score of 0.
In one operation:
* choose an index `i` such that `0 <= i < nums.length`,
* increase your score by `nums[i]`, and
* replace `nums[i]` with `ceil(nums[i] / 3)`.
Return the maximum possible score you can attain after applying exactly `k` operations.
The ceiling function `ceil(val)` is the least integer greater than or equal to `val`.
### Examples
```
Input: nums = [10,10,10,10,10], k = 5
Output: 50
Explanation: Apply the operation to each array element exactly once. The final score is 10 + 10 + 10 + 10 + 10 = 50.
```
```
Input: nums = [1,10,3,3,3], k = 3
Output: 17
Explanation: You can do the following operations:
Operation 1: Select i = 1, so nums becomes [1,4,3,3,3]. Your score increases by 10.
Operation 2: Select i = 1, so nums becomes [1,2,3,3,3]. Your score increases by 4.
Operation 3: Select i = 2, so nums becomes [1,2,1,3,3]. Your score increases by 3.
The final score is 10 + 4 + 3 = 17.
```
### Constraints
* 1 \<= nums.length, k \<= 10^5
* 1 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximal_score_after_applying_k_operations/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximal_score_after_applying_k_operations/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n + k * log n)
# Space: O(n)
def max_kelements(self, nums: list[int], k: int) -> int:
heap = [-num for num in nums]
heapq.heapify(heap)
score = 0
for _ in range(k):
num = -heapq.heappop(heap)
score += num
heapq.heappush(heap, -((num + 2) // 3))
return score
```
## Complexity
| Time | Space |
| ----------------- | ----- |
| O(n + k \* log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximal Square Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/maximal-square
Tested Python solution for LeetCode 221 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 221, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/maximal-square/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 221 # by problem number
lcpy gen -s maximal_square # by problem name
```
## Problem
Given an `m x n` binary `matrix` filled with `0`'s and `1`'s, find the largest square containing only `1`'s and return its area.
### Examples

```
Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 4
```

```
Input: matrix = [["0","1"],["1","0"]]
Output: 1
```
```
Input: matrix = [["0"]]
Output: 0
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m, n \<= 300
* matrix\[i]\[j] is '0' or '1'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximal_square/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximal_square/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n) — one pass over the matrix
# Space: O(n) — single-row DP array
def maximal_square(self, matrix: list[list[str]]) -> int:
if not matrix or not matrix[0]:
return 0
cols = len(matrix[0])
dp = [0] * (cols + 1)
max_side = 0
prev = 0 # holds dp[i-1][j-1] during the in-place update
for row in matrix:
for j in range(cols):
temp = dp[j + 1]
if row[j] == "1":
dp[j + 1] = min(dp[j + 1], dp[j], prev) + 1
max_side = max(max_side, dp[j + 1])
else:
dp[j + 1] = 0
prev = temp
return max_side * max_side
```
## Complexity
| Time | Space |
| ------------------------------------ | -------------------------- |
| O(m \* n) — one pass over the matrix | O(n) — single-row DP array |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Maximize Distance to Closest Person
Source: https://leetcode-py.wisl.dev/problems/maximize-distance-to-closest-person
Tested Python solution for LeetCode 849 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 849, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/maximize-distance-to-closest-person/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 849 # by problem number
lcpy gen -s maximize_distance_to_closest_person # by problem name
```
## Problem
You are given an array representing a row of `seats` where `seats[i] = 1` represents a person sitting in the `ith` seat, and `seats[i] = 0` represents that the `ith` seat is empty **(0-indexed)**.
There is at least one empty seat, and at least one person sitting.
Alex wants to sit in the seat such that the distance between him and the closest person to him is maximized.
Return *that maximum distance to the closest person*.
### Examples

```
Input: seats = [1,0,0,0,1,0,1]
Output: 2
Explanation:
If Alex sits in the second open seat (i.e. seats[2]), then the closest person has distance 2.
If Alex sits in any other open seat, the closest person has distance 1.
Thus, the maximum distance to the closest person is 2.
```
```
Input: seats = [1,0,0,0]
Output: 3
Explanation:
If Alex sits in the last seat (i.e. seats[3]), the closest person is 3 seats away.
This is the maximum distance possible, so the answer is 3.
```
```
Input: seats = [0,1]
Output: 1
```
### Constraints
* 2 \<= seats.length \<= 2 \* 10^4
* seats\[i] is 0 or 1.
* At least one seat is empty.
* At least one seat is occupied.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximize_distance_to_closest_person/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximize_distance_to_closest_person/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_dist_to_closest(self, seats: list[int]) -> int:
best = 0
prev = -1
n = len(seats)
for i, occupied in enumerate(seats):
if occupied:
best = i if prev < 0 else max(best, (i - prev) // 2)
prev = i
return max(best, n - 1 - prev)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Maximize Score After N Operations
Source: https://leetcode-py.wisl.dev/problems/maximize-score-after-n-operations
Tested Python solution for LeetCode 1799 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1799, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Number Theory](/catalog/topics/number-theory), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/maximize-score-after-n-operations/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1799 # by problem number
lcpy gen -s maximize_score_after_n_operations # by problem name
```
## Problem
\You are given \nums\, an array of positive integers of size \2 \* n\. You must perform \n\ operations on this array.\
In the \i\th\\ operation \(1-indexed)\, you will:\
x\ and \y\.\i \* gcd(x, y)\.\x\ and \y\ from \nums\.\Return \the maximum score you can receive after performing \\n\\ operations.\\
The function \gcd(x, y)\ is the greatest common divisor of \x\ and \y\.\
x\ and \y\, each of length \n\. You must choose three \distinct\ indices \i\, \j\, and \k\ such that:
\x\[i] != x\[j]\\x\[j] != x\[k]\\x\[k] != x\[i]\\y\[i] + y\[j] + y\[k]\ under these conditions. Return the \maximum\ possible sum that can be obtained by choosing such a triplet of indices.
If no such triplet exists, return -1.
### Examples
```
Input: x = [1,2,1,3,2], y = [5,3,4,6,2]
Output: 14
Explanation: Choose i = 0 (x[i] = 1, y[i] = 5), j = 1 (x[j] = 2, y[j] = 3), k = 3 (x[k] = 3, y[k] = 6). All three values chosen from x are distinct. 5 + 3 + 6 = 14 is the maximum we can obtain.
```
```
Input: x = [1,2,1,2], y = [4,5,6,7]
Output: -1
Explanation: There are only two distinct values in x. Hence, the output is -1.
```
### Constraints
* n == x.length == y.length
* 3 \<= n \<= 10^5
* 1 \<= x\[i], y\[i] \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def max_sum_distinct_triplet(self, x: list[int], y: list[int]) -> int:
best: dict[int, int] = {}
for xi, yi in zip(x, y, strict=True):
if yi > best.get(xi, 0):
best[xi] = yi
if len(best) < 3:
return -1
return sum(sorted(best.values(), reverse=True)[:3])
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Absolute Sum of Any Subarray
Source: https://leetcode-py.wisl.dev/problems/maximum-absolute-sum-of-any-subarray
Tested Python solution for LeetCode 1749 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 1749, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/maximum-absolute-sum-of-any-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1749 # by problem number
lcpy gen -s maximum_absolute_sum_of_any_subarray # by problem name
```
## Problem
You are given an integer array `nums`. The **absolute sum** of a subarray `[nums_l, nums_l+1, ..., nums_r-1, nums_r]` is `abs(nums_l + nums_l+1 + ... + nums_r-1 + nums_r)`.
Return the maximum absolute sum of any (possibly empty) subarray of `nums`.
Note that `abs(x)` is defined as follows:
* If `x` is a negative integer, then `abs(x) = -x`.
* If `x` is a non-negative integer, then `abs(x) = x`.
### Examples
```
Input: nums = [1,-3,2,3,-4]
Output: 5
```
**Explanation:** The subarray `[2,3]` has absolute sum = abs(2+3) = abs(5) = 5.
```
Input: nums = [2,-5,1,-4,3,-2]
Output: 8
```
**Explanation:** The subarray `[-5,1,-4]` has absolute sum = abs(-5+1-4) = abs(-8) = 8.
### Constraints
* `1 <= nums.length <= 10^5`
* `-10^4 <= nums[i] <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_absolute_sum_of_any_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_absolute_sum_of_any_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_absolute_sum(self, nums: list[int]) -> int:
max_sum = 0
min_sum = 0
best = 0
for num in nums:
max_sum = max(max_sum + num, num)
min_sum = min(min_sum + num, num)
best = max(best, max_sum, -min_sum)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Alternating Subsequence Sum
Source: https://leetcode-py.wisl.dev/problems/maximum-alternating-subsequence-sum
Tested Python solution for LeetCode 1911 with 44 pytest cases. Generate a practice environment with lcpy.
LeetCode 1911, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/maximum-alternating-subsequence-sum/description/).
Generate this problem as a practice environment: tested reference solution, 44 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1911 # by problem number
lcpy gen -s maximum_alternating_subsequence_sum # by problem name
```
## Problem
The \alternating sum\ of a \0-indexed\ array is defined as the \sum\ of the elements at \even\ indices \minus\ the \sum\ of the elements at \odd\ indices.
\\[4,2,5,3]\ is \(4 + 5) - (2 + 3) = 4\.\nums\, return \the \maximum alternating sum\ of any subsequence of \\nums\\ (after \reindexing\ the elements of the subsequence)\.
\A \subsequence\ of an array is a new array generated from the original array by deleting some elements (possibly none) without changing the remaining elements' relative order. For example, \\[2,7,4]\ is a subsequence of \\[4,2,\3\,7,2,1,\4\]\ (the underlined elements), while \\[2,4,2]\ is not.\
candies\. Each element in the array denotes a pile of candies of size \candies\[i]\. You can divide each pile into any number of \sub piles\, but you \cannot\ merge two piles together.
You are also given an integer \k\. You should allocate piles of candies to \k\ children such that each child gets the \same\ number of candies. Each child can be allocated candies from \only one\ pile of candies and some piles of candies may go unused.
Return \the \maximum number of candies\ each child can get.\
### Examples
```
Input: candies = [5,8,6], k = 3
Output: 5
Explanation: We can divide candies[1] into 2 piles of size 5 and 3, and candies[2] into 2 piles of size 5 and 1. We now have five piles of candies of sizes 5, 5, 3, 5, and 1. We can allocate the 3 piles of size 5 to 3 children. It can be proven that each child cannot receive more than 5 candies.
```
```
Input: candies = [2,5], k = 11
Output: 0
Explanation: There are 11 children but only 7 candies in total, so it is impossible to ensure each child receives at least one candy. Thus, each child gets no candy and the answer is 0.
```
### Constraints
* 1 \<= candies.length \<= 10\5\
* 1 \<= candies\[i] \<= 10\7\
* 1 \<= k \<= 10\12\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_candies_allocated_to_k_children/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_candies_allocated_to_k_children/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * log(max(candies)))
# Space: O(1)
def maximum_candies(self, candies: list[int], k: int) -> int:
lo, hi = 1, max(candies)
while lo <= hi:
mid = (lo + hi) // 2
if sum(pile // mid for pile in candies) >= k:
lo = mid + 1
else:
hi = mid - 1
return hi
```
## Complexity
| Time | Space |
| ------------------------- | ----- |
| O(n \* log(max(candies))) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Depth of Binary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-depth-of-binary-tree
Tested Python solution for LeetCode 104 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 104, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 104 # by problem number
lcpy gen -s maximum_depth_of_binary_tree # by problem name
```
## Problem
Given the `root` of a binary tree, return *its maximum depth*.
A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.
### Examples

```
Input: root = [3,9,20,null,null,15,7]
Output: 3
```
```
Input: root = [1,null,2]
Output: 2
```
### Constraints
* The number of nodes in the tree is in the range `[0, 10^4]`.
* `-100 <= Node.val <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_depth_of_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_depth_of_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def max_depth(self, root: TreeNode[int] | None) -> int:
if not root:
return 0
left_depth = self.max_depth(root.left)
right_depth = self.max_depth(root.right)
return 1 + max(left_depth, right_depth)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Maximum Depth of N-ary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-depth-of-n-ary-tree
Tested Python solution for LeetCode 559 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 559, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/maximum-depth-of-n-ary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 559 # by problem number
lcpy gen -s maximum_depth_of_n_ary_tree # by problem name
```
## Problem
Given a n-ary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
Nary-Tree input serialization is represented in their level order traversal, each group of children is separated by the null value (See examples).
### Examples

```
Input: root = [1,null,3,2,4,null,5,6]
Output: 3
```

```
Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Output: 5
```
### Constraints
* The total number of nodes is in the range \[0, 10^4].
* The depth of the n-ary tree is less than or equal to 1000.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_depth_of_n_ary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_depth_of_n_ary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class NaryNode:
def __init__(self, val: int = 0, children: list[NaryNode] | None = None) -> None:
self.val = val
self.children = children if children is not None else []
class Solution:
# Time: O(n)
# Space: O(w)
def max_depth(self, root: NaryNode | None) -> int:
if root is None:
return 0
depth = 0
level: list[NaryNode] = [root]
while level:
depth += 1
next_level: list[NaryNode] = []
for node in level:
next_level.extend(node.children)
level = next_level
return depth
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(w) |
## Tags
# Maximum Difference Between Even and Odd
Source: https://leetcode-py.wisl.dev/problems/maximum-difference-between-even-and-odd-frequency-i
Tested Python solution for LeetCode 3442 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 3442, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/maximum-difference-between-even-and-odd-frequency-i/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3442 # by problem number
lcpy gen -s maximum_difference_between_even_and_odd_frequency_i # by problem name
```
## Problem
You are given a string `s` consisting of lowercase English letters.
Your task is to find the **maximum** difference `diff = freq(a1) - freq(a2)` between the frequency of characters `a1` and `a2` in the string such that:
* `a1` has an **odd frequency** in the string.
* `a2` has an **even frequency** in the string.
Return this **maximum** difference.
### Examples
```
Input: s = "aaaaabbc"
Output: 3
Explanation: The character 'a' has an odd frequency of 5, and 'b' has an even frequency of 2.
The maximum difference is 5 - 2 = 3.
```
```
Input: s = "abcabcab"
Output: 1
Explanation: The character 'a' has an odd frequency of 3, and 'c' has an even frequency of 2.
The maximum difference is 3 - 2 = 1.
```
### Constraints
* `3 <= s.length <= 100`
* `s` consists only of lowercase English letters.
* `s` contains at least one character with an odd frequency and one with an even frequency.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_difference_between_even_and_odd_frequency_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_difference_between_even_and_odd_frequency_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(1)
def max_difference(self, s: str) -> int:
freqs = Counter(s).values()
return max(f for f in freqs if f % 2 == 1) - min(f for f in freqs if f % 2 == 0)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Distance in Arrays Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-distance-in-arrays
Tested Python solution for LeetCode 624 with 11 pytest cases. Generate a practice environment with lcpy.
LeetCode 624, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/maximum-distance-in-arrays/description/).
Generate this problem as a practice environment: tested reference solution, 11 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 624 # by problem number
lcpy gen -s maximum_distance_in_arrays # by problem name
```
## Problem
You are given `m` `arrays`, where each array is sorted in **ascending order**.
You can pick up two integers from two different arrays (each array picks one) and calculate the distance. We define the distance between two integers `a` and `b` to be their absolute difference `|a - b|`.
Return *the maximum distance*.
### Examples
```
Input: arrays = [[1,2,3],[4,5],[1,2,3]]
Output: 4
Explanation: One way to reach the maximum distance 4 is to pick 1 in the first or third array and pick 5 in the second array.
```
```
Input: arrays = [[1],[1]]
Output: 0
```
### Constraints
* m == arrays.length
* 2 \<= m \<= 10^5
* 1 \<= arrays\[i].length \<= 500
* -10^4 \<= arrays\[i]\[j] \<= 10^4
* arrays\[i] is sorted in ascending order.
* There will be at most 10^5 integers in all the arrays.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_distance_in_arrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_distance_in_arrays/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m) where m = len(arrays)
# Space: O(1)
def max_distance(self, arrays: list[list[int]]) -> int:
result = 0
cur_min, cur_max = arrays[0][0], arrays[0][-1]
for arr in arrays[1:]:
# Pair the current array against the best extremes seen so far;
# avoids using two extremes from the same array.
result = max(result, arr[-1] - cur_min, cur_max - arr[0])
cur_min = min(cur_min, arr[0])
cur_max = max(cur_max, arr[-1])
return result
```
## Complexity
| Time | Space |
| -------------------------- | ----- |
| O(m) where m = len(arrays) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Element After Decreasing and
Source: https://leetcode-py.wisl.dev/problems/maximum-element-after-decreasing-and-rearranging
Tested Python solution for LeetCode 1846 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1846, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/maximum-element-after-decreasing-and-rearranging/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1846 # by problem number
lcpy gen -s maximum_element_after_decreasing_and_rearranging # by problem name
```
## Problem
You are given an array of positive integers `arr`. Perform some operations (possibly none) on `arr` so that it satisfies these conditions:
* The value of the first element in `arr` must be 1.
* The absolute difference between any 2 adjacent elements must be less than or equal to 1. In other words, `abs(arr[i] - arr[i - 1]) <= 1` for each `i` where `1 <= i < arr.length` (0-indexed). `abs(x)` is the absolute value of `x`.
There are 2 types of operations that you can perform any number of times:
* Decrease the value of any element of `arr` to a smaller positive integer.
* Rearrange the elements of `arr` to be in any order.
Return *the **maximum** possible value of an element in* `arr` *after performing the operations to satisfy the conditions*.
### Examples
```
Input: arr = [2,2,1,2,1]
Output: 2
```
**Explanation:** We can satisfy the conditions by rearranging arr so it becomes \[1,2,2,2,1]. The largest element in arr is 2.
```
Input: arr = [100,1,1000]
Output: 3
```
**Explanation:** Rearrange arr so it becomes \[1,100,1000]. Decrease the second element to 2 and the third element to 3. Now arr = \[1,2,3], which satisfies the conditions. The largest element in arr is 3.
```
Input: arr = [1,2,3,4,5]
Output: 5
```
**Explanation:** The array already satisfies the conditions, and the largest element is 5.
### Constraints
* 1 \<= arr.length \<= 10^5
* 1 \<= arr\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_element_after_decreasing_and_rearranging/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_element_after_decreasing_and_rearranging/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(1) extra (sorting in place)
def maximum_element(self, arr: list[int]) -> int:
arr.sort()
prev = 0
for value in arr:
prev = min(prev + 1, value)
return prev
```
## Complexity
| Time | Space |
| ---------- | ----------------------------- |
| O(n log n) | O(1) extra (sorting in place) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Employees to Be Invited to a Meeting
Source: https://leetcode-py.wisl.dev/problems/maximum-employees-to-be-invited-to-a-meeting
Tested Python solution for LeetCode 2127 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2127, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Depth-First Search](/catalog/topics/depth-first-search), [Graph](/catalog/topics/graph), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/maximum-employees-to-be-invited-to-a-meeting/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2127 # by problem number
lcpy gen -s maximum_employees_to_be_invited_to_a_meeting # by problem name
```
## Problem
A company is organizing a meeting and has a list of \n\ employees, waiting to be invited. They have arranged for a large \circular\ table, capable of seating \any number\ of employees.\
\The employees are numbered from \0\ to \n - 1\. Each employee has a \favorite\ person and they will attend the meeting \only if\ they can sit next to their favorite person at the table. The favorite person of an employee is \not\ themself.\
Given a \0-indexed\ integer array \favorite\, where \favorite\[i]\ denotes the favorite person of the \i\th\\ employee, return \the \maximum number of employees\ that can be invited to the meeting\.
### Examples

```
Input: favorite = [2,2,1,2]
Output: 3
Explanation:
The above figure shows how the company can invite employees 0, 1, and 2, and seat them at the round table.
All employees cannot be invited because employee 2 cannot sit beside employees 0, 1, and 3, simultaneously.
Note that the company can also invite employees 1, 2, and 3, and give them their desired seats.
The maximum number of employees that can be invited to the meeting is 3.
```
```
Input: favorite = [1,2,0]
Output: 3
Explanation:
Each employee is the favorite person of at least one other employee, and the only way the company can invite them is if they invite every employee.
The seating arrangement will be the same as that in the figure given in example 1:
- Employee 0 will sit between employees 2 and 1.
- Employee 1 will sit between employees 0 and 2.
- Employee 2 will sit between employees 1 and 0.
The maximum number of employees that can be invited to the meeting is 3.
```

```
Input: favorite = [3,0,1,4,1]
Output: 4
Explanation:
The above figure shows how the company will invite employees 0, 1, 3, and 4, and seat them at the round table.
Employee 2 cannot be invited because the two spots next to their favorite employee 1 are taken.
So the company leaves them out of the meeting.
The maximum number of employees that can be invited to the meeting is 4.
```
### Constraints
* n == favorite.length
* 2 \<= n \<= 10^5
* 0 \<= favorite\[i] \<= n - 1
* favorite\[i] != i
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_employees_to_be_invited_to_a_meeting/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_employees_to_be_invited_to_a_meeting/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n)
# Space: O(n)
def maximum_invitations(self, favorite: list[int]) -> int:
n = len(favorite)
depth = [1] * n
indegree = [0] * n
for fav in favorite:
indegree[fav] += 1
# Peel off chain nodes so only cycle nodes keep indegree > 0, recording
# for each cycle node the longest chain of excluded employees hanging
# off it (depth counts the cycle node itself).
queue = deque(i for i in range(n) if indegree[i] == 0)
in_cycle = [True] * n
while queue:
node = queue.popleft()
in_cycle[node] = False
nxt = favorite[node]
depth[nxt] = max(depth[nxt], depth[node] + 1)
indegree[nxt] -= 1
if indegree[nxt] == 0:
queue.append(nxt)
visited = [False] * n
best_cycle = 0
pair_total = 0
for start in range(n):
if not in_cycle[start] or visited[start]:
continue
length = 0
node = start
while not visited[node]:
visited[node] = True
node = favorite[node]
length += 1
if length == 2:
# Mutual pairs can all sit together if their chains face them.
pair_total += depth[start] + depth[favorite[start]]
else:
best_cycle = max(best_cycle, length)
return max(best_cycle, pair_total)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Frequency After Subarray Operation
Source: https://leetcode-py.wisl.dev/problems/maximum-frequency-after-subarray-operation
Tested Python solution for LeetCode 3434 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 3434, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Enumeration](/catalog/topics/enumeration), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/maximum-frequency-after-subarray-operation/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3434 # by problem number
lcpy gen -s maximum_frequency_after_subarray_operation # by problem name
```
## Problem
You are given an array `nums` of length `n`. You are also given an integer `k`.
You perform the following operation on `nums` **once**:
* Select a subarray `nums[i..j]` where `0 <= i <= j <= n - 1`.
* Select an integer `x` and add `x` to **all** the elements in `nums[i..j]`.
Find the **maximum** frequency of the value `k` after the operation.
### Examples
```
Input: nums = [1,2,3,4,5,6], k = 1
Output: 2
```
**Explanation:** After adding -5 to `nums[2..5]`, 1 has a frequency of 2 in `[1, 2, -2, -1, 0, 1]`.
```
Input: nums = [10,2,3,4,5,5,4,3,2,2], k = 10
Output: 4
```
**Explanation:** After adding 8 to `nums[1..9]`, 10 has a frequency of 4 in `[10, 10, 11, 12, 13, 13, 12, 11, 10, 10]`.
### Constraints
* 1 \<= n == nums.length \<= 10^5
* 1 \<= nums\[i] \<= 50
* 1 \<= k \<= 50
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_frequency_after_subarray_operation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_frequency_after_subarray_operation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(50 * n) ~ O(n); Space: O(1)
def max_frequency(self, nums: list[int], k: int) -> int:
base = nums.count(k)
best_gain = 0
for target in sorted(set(nums) - {k}):
# Kadane: +1 for target values (convertible to k), -1 for k values
# (lost by the operation), 0 otherwise.
cur = 0
for num in nums:
weight = 1 if num == target else (-1 if num == k else 0)
cur = max(weight, cur + weight)
best_gain = max(best_gain, cur)
return base + best_gain
```
## Complexity
| Time | Space |
| ------------------------------- | ----- |
| O(50 \* n) \~ O(n); Space: O(1) | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Frequency Stack Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-frequency-stack
Tested Python solution for LeetCode 895 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 895, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [Stack](/catalog/topics/stack), [Design](/catalog/topics/design), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/maximum-frequency-stack/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 895 # by problem number
lcpy gen -s maximum_frequency_stack # by problem name
```
## Problem
Design a stack-like data structure to push elements to the stack and pop the most frequent element from the stack.
Implement the `FreqStack` class:
* `FreqStack()` constructs the empty frequency stack.
* `void push(int val)` pushes an integer `val` onto the top of the stack.
* `int pop()` removes and returns the most frequent element in the stack.
* If there is a tie for the most frequent element, the element closest to the stack's top is removed and returned.
### Examples
```
Input
["FreqStack", "push", "push", "push", "push", "push", "push", "pop", "pop", "pop", "pop"]
[[], [5], [7], [5], [7], [4], [5], [], [], [], []]
Output
[null, null, null, null, null, null, null, 5, 7, 5, 4]
```
**Explanation:**
```
FreqStack freqStack = new FreqStack();
freqStack.push(5); // The stack is [5]
freqStack.push(7); // The stack is [5,7]
freqStack.push(5); // The stack is [5,7,5]
freqStack.push(7); // The stack is [5,7,5,7]
freqStack.push(4); // The stack is [5,7,5,7,4]
freqStack.push(5); // The stack is [5,7,5,7,4,5]
freqStack.pop(); // return 5, as 5 is the most frequent. The stack becomes [5,7,5,7,4].
freqStack.pop(); // return 7, as 5 and 7 is the most frequent, but 7 is closest to the top. The stack becomes [5,7,5,4].
freqStack.pop(); // return 5, as 5 is the most frequent. The stack becomes [5,7,4].
freqStack.pop(); // return 4, as 4, 5 and 7 is the most frequent, but 4 is closest to the top. The stack becomes [5,7].
```
### Constraints
* `0 <= val <= 10^9`
* At most `2 * 10^4` calls will be made to `push` and `pop`.
* It is guaranteed that there will be at least one element in the stack before calling `pop`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_frequency_stack/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_frequency_stack/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class FreqStack:
def __init__(self) -> None:
self.freq: dict[int, int] = {}
self.group: dict[int, list[int]] = {}
self.max_freq = 0
# Time: O(1)
# Space: O(n)
def push(self, val: int) -> None:
count = self.freq.get(val, 0) + 1
self.freq[val] = count
if count > self.max_freq:
self.max_freq = count
self.group.setdefault(count, []).append(val)
# Time: O(1)
# Space: O(n)
def pop(self) -> int:
val = self.group[self.max_freq].pop()
self.freq[val] -= 1
if not self.group[self.max_freq]:
self.max_freq -= 1
return val
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(n) |
## Tags
[Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Maximum Gap Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/maximum-gap
Tested Python solution for LeetCode 164 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 164, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting), Bucket Sort, Radix Sort, Pigeonhole Principle. [View on LeetCode](https://leetcode.com/problems/maximum-gap/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 164 # by problem number
lcpy gen -s maximum_gap # by problem name
```
## Problem
Given an integer array \nums\, return \the maximum difference between two successive elements in its sorted form\. If the array contains less than two elements, return \0\.
You must write an algorithm that runs in linear time and uses linear extra space.
### Examples
```
Input: nums = [3,6,9,1]
Output: 3
```
**Explanation:** The sorted form of the array is \[1,3,6,9], either (3,6) or (6,9) has the maximum difference 3.
```
Input: nums = [10]
Output: 0
```
**Explanation:** The array contains less than 2 elements, therefore return 0.
### Constraints
* `1 <= nums.length <= 10^5`
* `0 <= nums[i] <= 10^9`
**Follow up:** Could you solve it without using any built-in sorting function?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_gap/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_gap/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def maximum_gap(self, nums: list[int]) -> int:
n = len(nums)
if n < 2:
return 0
low, high = min(nums), max(nums)
if low == high:
return 0
# Pigeonhole: the answer is at least ceil((high - low) / (n - 1)),
# so buckets narrower than that guarantee the max gap spans buckets.
size = max(1, (high - low) // (n - 1))
count = (high - low) // size + 1
bucket_min: list[int | None] = [None] * count
bucket_max: list[int | None] = [None] * count
for num in nums:
idx = (num - low) // size
lo = bucket_min[idx]
hi = bucket_max[idx]
if lo is None or hi is None:
bucket_min[idx] = num
bucket_max[idx] = num
elif num < lo:
bucket_min[idx] = num
elif num > hi:
bucket_max[idx] = num
result = 0
prev_max = low
for idx in range(count):
cur_min = bucket_min[idx]
cur_max = bucket_max[idx]
if cur_min is None or cur_max is None:
continue
result = max(result, cur_min - prev_max)
prev_max = cur_max
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Maximum Length of a Concatenated String with
Source: https://leetcode-py.wisl.dev/problems/maximum-length-of-a-concatenated-string-with-unique-characters
Tested Python solution for LeetCode 1239 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1239, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1239 # by problem number
lcpy gen -s maximum_length_of_a_concatenated_string_with_unique_characters # by problem name
```
## Problem
You are given an array of strings `arr`. A string `s` is formed by the **concatenation** of a **subsequence** of `arr` that has **unique characters**.
Return *the **maximum** possible length* of `s`.
A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
### Examples
```
Input: arr = ["un","iq","ue"]
Output: 4
Explanation: All the valid concatenations are:
- ""
- "un"
- "iq"
- "ue"
- "uniq" ("un" + "iq")
- "ique" ("iq" + "ue")
Maximum length is 4.
```
```
Input: arr = ["cha","r","act","ers"]
Output: 6
Explanation: Possible longest valid concatenations are "chaers" ("cha" + "ers") and "acters" ("act" + "ers").
```
```
Input: arr = ["abcdefghijklmnopqrstuvwxyz"]
Output: 26
Explanation: The only string in arr has all 26 characters.
```
### Constraints
* `1 <= arr.length <= 16`
* `1 <= arr[i].length <= 26`
* `arr[i]` contains only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_length_of_a_concatenated_string_with_unique_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_length_of_a_concatenated_string_with_unique_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^n * n) worst case
# Space: O(n)
def max_len(self, arr: list[str]) -> int:
masks: list[int] = []
for s in arr:
mask = 0
for char in s:
bit = 1 << (ord(char) - ord("a"))
if mask & bit:
break
mask |= bit
else:
masks.append(mask)
best = 0
def dfs(i: int, current: int) -> None:
nonlocal best
best = max(best, current.bit_count())
for j in range(i, len(masks)):
if not (current & masks[j]):
dfs(j + 1, current | masks[j])
dfs(0, 0)
return best
```
## Complexity
| Time | Space |
| ---------------------- | ----- |
| O(2^n \* n) worst case | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Length of Pair Chain Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-length-of-pair-chain
Tested Python solution for LeetCode 646 with 11 pytest cases. Generate a practice environment with lcpy.
LeetCode 646, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), Longest Increasing Subsequence. [View on LeetCode](https://leetcode.com/problems/maximum-length-of-pair-chain/description/).
Generate this problem as a practice environment: tested reference solution, 11 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 646 # by problem number
lcpy gen -s maximum_length_of_pair_chain # by problem name
```
## Problem
You are given an array of `n` pairs `pairs` where `pairs[i] = [lefti, righti]` and `lefti < righti`.
A pair `p2 = [c, d]` **follows** a pair `p1 = [a, b]` if `b < c`. A **chain** of pairs can be formed in this fashion.
Return *the length longest chain which can be formed*.
You do not need to use up all the given intervals. You can select pairs in any order.
### Examples
```
Input: pairs = [[1,2],[2,3],[3,4]]
Output: 2
Explanation: The longest chain is [1,2] -> [3,4].
```
```
Input: pairs = [[1,2],[7,8],[4,5]]
Output: 3
Explanation: The longest chain is [1,2] -> [4,5] -> [7,8].
```
### Constraints
* n == pairs.length
* 1 \<= n \<= 1000
* -1000 \<= lefti \< righti \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_length_of_pair_chain/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_length_of_pair_chain/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n) for the sorted copy
def find_longest_chain(self, pairs: list[list[int]]) -> int:
count = 0
chain_end = float("-inf")
for left, right in sorted(pairs, key=lambda pair: pair[1]):
if left > chain_end:
count += 1
chain_end = right
return count
```
## Complexity
| Time | Space |
| ---------- | ------------------------ |
| O(n log n) | O(n) for the sorted copy |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Length of Repeated Subarray
Source: https://leetcode-py.wisl.dev/problems/maximum-length-of-repeated-subarray
Tested Python solution for LeetCode 718 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 718, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sliding Window](/catalog/topics/sliding-window), Rolling Hash, [Hash Function](/catalog/topics/hash-function). [View on LeetCode](https://leetcode.com/problems/maximum-length-of-repeated-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 718 # by problem number
lcpy gen -s maximum_length_of_repeated_subarray # by problem name
```
## Problem
Given two integer arrays `nums1` and `nums2`, return *the maximum length of a subarray that appears in **both** arrays*.
### Examples
```
Input: nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
Output: 3
Explanation: The repeated subarray with maximum length is [3,2,1].
```
```
Input: nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
Output: 5
Explanation: The repeated subarray with maximum length is [0,0,0,0,0].
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 1000
* 0 \<= nums1\[i], nums2\[i] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_length_of_repeated_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_length_of_repeated_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(nums1) * len(nums2))
# Space: O(len(nums2))
def find_length(self, nums1: list[int], nums2: list[int]) -> int:
best = 0
prev = [0] * (len(nums2) + 1)
for a in nums1:
cur = [0] * (len(nums2) + 1)
for j, b in enumerate(nums2, start=1):
if a == b:
cur[j] = prev[j - 1] + 1
if cur[j] > best:
best = cur[j]
prev = cur
return best
```
## Complexity
| Time | Space |
| --------------------------- | ------------- |
| O(len(nums1) \* len(nums2)) | O(len(nums2)) |
## Tags
# Maximum Matrix Sum Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/maximum-matrix-sum
Tested Python solution for LeetCode 1975 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1975, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/maximum-matrix-sum/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1975 # by problem number
lcpy gen -s maximum_matrix_sum # by problem name
```
## Problem
You are given an `n x n` integer `matrix`. You can do the following operation **any** number of times:
* Choose any two **adjacent** elements of `matrix` and **multiply** each of them by `-1`.
Two elements are considered **adjacent** if and only if they share a **border**.
Your goal is to **maximize** the summation of the matrix's elements. Return *the **maximum** sum of the matrix's elements using the operation mentioned above.*
### Examples

```
Input: matrix = [[1,-1],[-1,1]]
Output: 4
Explanation: We can follow the following steps to reach sum equals 4:
- Multiply the 2 elements in the first row by -1.
- Multiply the 2 elements in the first column by -1.
```

```
Input: matrix = [[1,2,3],[-1,-2,-3],[1,2,3]]
Output: 16
Explanation: We can follow the following step to reach sum equals 16:
- Multiply the 2 last elements in the second row by -1.
```
### Constraints
* `n == matrix.length == matrix[i].length`
* `2 <= n <= 250`
* `-10^5 <= matrix[i][j] <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_matrix_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_matrix_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(1)
def max_matrix_sum(self, matrix: list[list[int]]) -> int:
total = 0
neg_count = 0
min_abs = 10**9
for row in matrix:
for value in row:
total += abs(value)
neg_count += value < 0
min_abs = min(min_abs, abs(value))
if neg_count % 2:
total -= 2 * min_abs
return total
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Nesting Depth of the Parentheses
Source: https://leetcode-py.wisl.dev/problems/maximum-nesting-depth-of-the-parentheses
Tested Python solution for LeetCode 1614 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 1614, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), Bracket Sequences. [View on LeetCode](https://leetcode.com/problems/maximum-nesting-depth-of-the-parentheses/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1614 # by problem number
lcpy gen -s maximum_nesting_depth_of_the_parentheses # by problem name
```
## Problem
Given a valid parentheses string `s`, return the nesting depth of `s`. The nesting depth is the maximum number of nested parentheses.
### Examples
```
Input: s = "(1+(2*3)+((8)/4))+1"
Output: 3
Explanation: Digit 8 is inside of 3 nested parentheses in the string.
```
```
Input: s = "(1)+((2))+(((3)))"
Output: 3
Explanation: Digit 3 is inside of 3 nested parentheses in the string.
```
```
Input: s = "()(())((()()))"
Output: 3
```
### Constraints
* `1 <= s.length <= 100`
* `s` consists of digits `0-9` and characters `'+'`, `'-'`, `'*'`, `'/'`, `'('`, and `')'`.
* It is guaranteed that parentheses expression `s` is a VPS.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_nesting_depth_of_the_parentheses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_nesting_depth_of_the_parentheses/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_depth(self, s: str) -> int:
depth = 0
best = 0
for char in s:
if char == "(":
depth += 1
if depth > best:
best = depth
elif char == ")":
depth -= 1
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Balloons Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-balloons
Tested Python solution for LeetCode 1189 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1189, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-balloons/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1189 # by problem number
lcpy gen -s maximum_number_of_balloons # by problem name
```
## Problem
Given a string `text`, you want to use the characters of `text` to form as many instances of the word **"balloon"** as possible.
You can use each character in `text` **at most once**. Return the maximum number of instances that can be formed.
### Examples

```
Input: text = "nlaebolko"
Output: 1
```

```
Input: text = "loonbalxballpoon"
Output: 2
```
```
Input: text = "leetcode"
Output: 0
```
### Constraints
* `1 <= text.length <= 10^4`
* `text` consists of lower case English letters only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_balloons/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_balloons/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(len(text))
# Space: O(1)
def max_number_of_balloons(self, text: str) -> int:
counts = Counter(text)
return min(counts["b"], counts["a"], counts["l"] // 2, counts["o"] // 2, counts["n"])
```
## Complexity
| Time | Space |
| ------------ | ----- |
| O(len(text)) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Fish in a Grid
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-fish-in-a-grid
Tested Python solution for LeetCode 2658 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2658, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-fish-in-a-grid/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2658 # by problem number
lcpy gen -s maximum_number_of_fish_in_a_grid # by problem name
```
## Problem
You are given a **0-indexed** 2D matrix `grid` of size `m x n`, where `(r, c)` represents:
* A **land** cell if `grid[r][c] = 0`, or
* A **water** cell containing `grid[r][c]` fish, if `grid[r][c] > 0`.
A fisher can start at any **water** cell `(r, c)` and can do the following operations any number of times:
* Catch all the fish at cell `(r, c)`, or
* Move to any adjacent **water** cell.
Return *the **maximum** number of fish the fisher can catch if he chooses his starting cell optimally*, or `0` if no water cell exists.
An **adjacent** cell of the cell `(r, c)`, is one of the cells `(r, c + 1)`, `(r, c - 1)`, `(r + 1, c)` or `(r - 1, c)` if it exists.
### Examples

```
Input: grid = [[0,2,1,0],[4,0,0,3],[1,0,0,4],[0,3,2,0]]
Output: 7
Explanation: The fisher can start at cell (1,3) and collect 3 fish, then move to cell (2,3) and collect 4 fish.
```

```
Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]]
Output: 1
Explanation: The fisher can start at cells (0,0) or (3,3) and collect a single fish.
```
### Constraints
* m == grid.length
* n == grid\[i].length
* 1 \<= m, n \<= 10
* 0 \<= grid\[i]\[j] \<= 10
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_fish_in_a_grid/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_fish_in_a_grid/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def find_max_fish(self, grid: list[list[int]]) -> int:
rows, cols = len(grid), len(grid[0])
seen = [[False] * cols for _ in range(rows)]
best = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] > 0 and not seen[r][c]:
seen[r][c] = True
queue = deque([(r, c)])
total = 0
while queue:
cr, cc = queue.popleft()
total += grid[cr][cc]
for nr, nc in ((cr + 1, cc), (cr - 1, cc), (cr, cc + 1), (cr, cc - 1)):
if (
0 <= nr < rows
and 0 <= nc < cols
and grid[nr][nc] > 0
and not seen[nr][nc]
):
seen[nr][nc] = True
queue.append((nr, nc))
best = max(best, total)
return best
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of K-Divisible Components
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-k-divisible-components
Tested Python solution for LeetCode 2872 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 2872, [Hard](/catalog/hard). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-k-divisible-components/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2872 # by problem number
lcpy gen -s maximum_number_of_k_divisible_components # by problem name
```
## Problem
There is an undirected tree with `n` nodes labeled from `0` to `n - 1`. You are given the integer `n` and a 2D integer array `edges` of length `n - 1`, where `edges[i] = [ai, bi]` indicates that there is an edge between nodes `ai` and `bi` in the tree.
You are also given a **0-indexed** integer array `values` of length `n`, where `values[i]` is the **value** associated with the `ith` node, and an integer `k`.
A **valid split** of the tree is obtained by removing any set of edges, possibly empty, from the tree such that the resulting components all have values that are divisible by `k`, where the **value of a connected component** is the sum of the values of its nodes.
Return *the **maximum number of components** in any valid split*.
### Examples

```
Input: n = 5, edges = [[0,2],[1,2],[1,3],[2,4]], values = [1,8,1,4,4], k = 6
Output: 2
Explanation: We remove the edge connecting node 1 with 2. The resulting split is valid because:
- The value of the component containing nodes 1 and 3 is values[1] + values[3] = 12.
- The value of the component containing nodes 0, 2, and 4 is values[0] + values[2] + values[4] = 6.
It can be shown that no other valid split has more than 2 connected components.
```

```
Input: n = 7, edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], values = [3,0,6,1,5,2,1], k = 3
Output: 3
Explanation: We remove the edge connecting node 0 with 2, and the edge connecting node 0 with 1. The resulting split is valid because:
- The value of the component containing node 0 is values[0] = 3.
- The value of the component containing nodes 2, 5, and 6 is values[2] + values[5] + values[6] = 9.
- The value of the component containing nodes 1, 3, and 4 is values[1] + values[3] + values[4] = 6.
It can be shown that no other valid split has more than 3 connected components.
```
### Constraints
* 1 \<= n \<= 3 \* 10^4
* edges.length == n - 1
* edges\[i].length == 2
* 0 \<= ai, bi \< n
* values.length == n
* 0 \<= values\[i] \<= 10^9
* 1 \<= k \<= 10^9
* Sum of values is divisible by k.
* The input is generated such that edges represents a valid tree.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_k_divisible_components/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_k_divisible_components/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def max_k_divisible_components(
self, n: int, edges: list[list[int]], values: list[int], k: int
) -> int:
adj: list[list[int]] = [[] for _ in range(n)]
for a, b in edges:
adj[a].append(b)
adj[b].append(a)
# Iterative post-order DFS from node 0 (n up to 3 * 10^4, avoid recursion).
parent = [-1] * n
order = [0]
parent[0] = 0
for node in order:
for nxt in adj[node]:
if parent[nxt] == -1:
parent[nxt] = node
order.append(nxt)
subtree = values[:]
count = 0
for node in reversed(order):
if subtree[node] % k == 0:
count += 1
else:
subtree[parent[node]] += subtree[node]
return count
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Ones Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-ones
Tested Python solution for LeetCode 1183 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1183, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-ones/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1183 # by problem number
lcpy gen -s maximum_number_of_ones # by problem name
```
## Problem
Consider a matrix `M` with dimensions `width * height`, such that every cell has value `0` or `1`, and any **square** sub-matrix of `M` of size `sideLength * sideLength` has at most `maxOnes` ones.
Return the maximum possible number of ones that the matrix `M` can have.
### Examples
```
Input: width = 3, height = 3, sideLength = 2, maxOnes = 1
Output: 4
```
**Explanation:**
In a 3*3 matrix, no 2*2 sub-matrix can have more than 1 one.
The best solution that has 4 ones is:
\[1,0,1]
\[0,0,0]
\[1,0,1]
```
Input: width = 3, height = 3, sideLength = 2, maxOnes = 2
Output: 6
```
**Explanation:**
\[1,0,1]
\[1,0,1]
\[1,0,1]
### Constraints
* 1 \<= width, height \<= 100
* 1 \<= sideLength \<= width, height
* 0 \<= maxOnes \<= sideLength \* sideLength
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_ones/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_ones/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(width * height)
# Space: O(sideLength^2)
def maximum_number_of_ones(
self, width: int, height: int, side_length: int, max_ones: int
) -> int:
x = side_length
counts = [0] * (x * x)
for i in range(width):
for j in range(height):
counts[(i % x) * x + (j % x)] += 1
counts.sort(reverse=True)
return sum(counts[:max_ones])
```
## Complexity
| Time | Space |
| ------------------ | --------------- |
| O(width \* height) | O(sideLength^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Points From Grid Queries
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-points-from-grid-queries
Tested Python solution for LeetCode 2503 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 2503, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-points-from-grid-queries/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2503 # by problem number
lcpy gen -s maximum_number_of_points_from_grid_queries # by problem name
```
## Problem
You are given an `m x n` integer matrix `grid` and an array `queries` of size `k`.
Find an array `answer` of size `k` such that for each integer `queries[i]` you start in the top left cell of the matrix and repeat the following process:
* If `queries[i]` is strictly greater than the value of the current cell that you are in, then you get one point if it is your first time visiting this cell, and you can move to any adjacent cell in all `4` directions: up, down, left, and right.
* Otherwise, you do not get any points, and you end this process.
After the process, `answer[i]` is the maximum number of points you can get. Note that for each query you are allowed to visit the same cell multiple times.
Return the resulting array `answer`.
### Examples

```
Input: grid = [[1,2,3],[2,5,7],[3,5,1]]
queries = [5,6,2]
Output: [5,8,1]
Explanation: The diagrams above show which cells we visit to get points for each query.
```
```
Input: grid = [[5,2,1],[1,1,2]]
queries = [3]
Output: [0]
Explanation: We can not get any points because the value of the top left cell is already greater than or equal to 3.
```
### Constraints
* `m == grid.length`
* `n == grid[i].length`
* `2 <= m, n <= 10^3`
* `4 <= m * n <= 10^5`
* `k == queries.length`
* `1 <= k <= 10^4`
* `1 <= grid[i][j], queries[i] <= 10^6`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_points_from_grid_queries/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_points_from_grid_queries/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(m*n*log(m*n) + k*log k)
# Space: O(m*n)
def max_points(self, grid: list[list[int]], queries: list[int]) -> list[int]:
rows, cols = len(grid), len(grid[0])
visited = [[False] * cols for _ in range(rows)]
visited[0][0] = True
heap: list[tuple[int, int, int]] = [(grid[0][0], 0, 0)]
count = 0
counts: dict[int, int] = {}
for query in sorted(set(queries)):
while heap and heap[0][0] < query:
_, i, j = heapq.heappop(heap)
count += 1
for ni, nj in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)):
if 0 <= ni < rows and 0 <= nj < cols and not visited[ni][nj]:
visited[ni][nj] = True
heapq.heappush(heap, (grid[ni][nj], ni, nj))
counts[query] = count
return [counts[query] for query in queries]
```
## Complexity
| Time | Space |
| ------------------------- | ------- |
| O(m*n*log(m*n) + k*log k) | O(m\*n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Points with Cost
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-points-with-cost
Tested Python solution for LeetCode 1937 with 32 pytest cases. Generate a practice environment with lcpy.
LeetCode 1937, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-points-with-cost/description/).
Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1937 # by problem number
lcpy gen -s maximum_number_of_points_with_cost # by problem name
```
## Problem
You are given an `m x n` integer matrix `points` (**0-indexed**). Starting with `0` points, you want to **maximize** the number of points you can get from the matrix.
To gain points, you must pick one cell in **each row**. Picking the cell at coordinates `(r, c)` will **add** `points[r][c]` to your score.
However, you will lose points if you pick a cell too far from the cell that you picked in the previous row. For every two adjacent rows `r` and `r + 1` (where `0 <= r < m - 1`), picking cells at coordinates `(r, c1)` and `(r + 1, c2)` will **subtract** `abs(c1 - c2)` from your score.
Return *the **maximum** number of points you can achieve*.
`abs(x)` is defined as:
* `x` for `x >= 0`.
* `-x` for `x < 0`.
### Examples

```
Input: points = [[1,2,3],[1,5,1],[3,1,1]]
Output: 9
```
**Explanation:** The blue cells denote the optimal cells to pick, which have coordinates (0, 2), (1, 1), and (2, 0). You add 3 + 5 + 3 = 11 to your score. However, you must subtract abs(2 - 1) + abs(1 - 0) = 2 from your score. Your final score is 11 - 2 = 9.

```
Input: points = [[1,5],[2,3],[4,2]]
Output: 11
```
**Explanation:** The blue cells denote the optimal cells to pick, which have coordinates (0, 1), (1, 1), and (2, 0). You add 5 + 3 + 4 = 12 to your score. However, you must subtract abs(1 - 1) + abs(1 - 0) = 1 from your score. Your final score is 12 - 1 = 11.
### Constraints
* `1 <= m, n <= 10^5`
* `1 <= m * n <= 10^5`
* `0 <= points[r][c] <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_points_with_cost/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_points_with_cost/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(n)
def max_points(self, points: list[list[int]]) -> int:
n = len(points[0])
dp = list(points[0])
for row in points[1:]:
left = [0] * n
left[0] = dp[0]
for c in range(1, n):
left[c] = max(left[c - 1] - 1, dp[c])
right = [0] * n
right[n - 1] = dp[n - 1]
for c in range(n - 2, -1, -1):
right[c] = max(right[c + 1] - 1, dp[c])
dp = [max(left[c], right[c]) + row[c] for c in range(n)]
return max(dp)
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(m \* n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Removable Characters
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-removable-characters
Tested Python solution for LeetCode 1898 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1898, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-removable-characters/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1898 # by problem number
lcpy gen -s maximum_number_of_removable_characters # by problem name
```
## Problem
You are given two strings `s` and `p` where `p` is a subsequence of `s`. You are also given a **distinct 0-indexed** integer array `removable` containing a subset of indices of `s` (`s` is also **0-indexed**).
You want to choose an integer `k` (`0 <= k <= removable.length`) such that, after removing `k` characters from `s` using the **first** `k` indices in `removable`, `p` is still a subsequence of `s`. More formally, you will mark the character at `s[removable[i]]` for each `0 <= i < k`, then remove all marked characters and check if `p` is still a subsequence.
Return *the **maximum** `k` you can choose such that `p` is still a subsequence of `s` after the removals*.
A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.
### Examples
```
Input: s = "abcacb", p = "ab", removable = [3,1,0]
Output: 2
```
**Explanation:** After removing the characters at indices 3 and 1, `"abcacb"` becomes `"accb"`. `"ab"` is a subsequence of `"accb"`. If we remove the characters at indices 3, 1, and 0, `"abcacb"` becomes `"ccb"`, and `"ab"` is no longer a subsequence. Hence, the maximum k is 2.
```
Input: s = "abcbddddd", p = "abcd", removable = [3,2,1,4,5,6]
Output: 1
```
**Explanation:** After removing the character at index 3, `"abcbddddd"` becomes `"abcddddd"`. `"abcd"` is a subsequence of `"abcddddd"`.
```
Input: s = "abcab", p = "abc", removable = [0,1,2,3,4]
Output: 0
```
**Explanation:** If you remove the first index in the array removable, `"abc"` is no longer a subsequence.
### Constraints
* `1 <= p.length <= s.length <= 10^5`
* `0 <= removable.length < s.length`
* `0 <= removable[i] < s.length`
* `p` is a subsequence of `s`.
* `s` and `p` both consist of lowercase English letters.
* The elements in `removable` are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_removable_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_removable_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(s) * log(len(removable)))
# Space: O(len(removable))
def maximum_removals(self, s: str, p: str, removable: list[int]) -> int:
def is_subsequence(removed: set[int]) -> bool:
i = 0
for j, ch in enumerate(s):
if i == len(p):
return True
if j in removed or ch != p[i]:
continue
i += 1
return i == len(p)
lo, hi = 0, len(removable)
while lo < hi:
mid = (lo + hi + 1) // 2
if is_subsequence(set(removable[:mid])):
lo = mid
else:
hi = mid - 1
return lo
```
## Complexity
| Time | Space |
| -------------------------------- | ----------------- |
| O(len(s) \* log(len(removable))) | O(len(removable)) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Number of Vowels in a Substring of
Source: https://leetcode-py.wisl.dev/problems/maximum-number-of-vowels-in-a-substring-of-given-length
Tested Python solution for LeetCode 1456 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1456, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1456 # by problem number
lcpy gen -s maximum_number_of_vowels_in_a_substring_of_given_length # by problem name
```
## Problem
Given a string `s` and an integer `k`, return *the maximum number of vowel letters in any substring of* `s` *with length* `k`.
**Vowel letters** in English are `'a'`, `'e'`, `'i'`, `'o'`, and `'u'`.
### Examples
```
Input: s = "abciiidef", k = 3
Output: 3
```
**Explanation:** The substring "iii" contains 3 vowel letters.
```
Input: s = "aeiou", k = 2
Output: 2
```
**Explanation:** Any substring of length 2 contains 2 vowels.
```
Input: s = "leetcode", k = 3
Output: 2
```
**Explanation:** "lee", "eet" and "ode" contain 2 vowels.
### Constraints
* 1 \<= s.length \<= 10^5
* s consists of lowercase English letters.
* 1 \<= k \<= s.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_vowels_in_a_substring_of_given_length/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_number_of_vowels_in_a_substring_of_given_length/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_vowels(self, s: str, k: int) -> int:
vowels = frozenset("aeiou")
count = sum(c in vowels for c in s[:k])
best = count
for i in range(k, len(s)):
count += (s[i] in vowels) - (s[i - k] in vowels)
if count > best:
best = count
if best == k:
return best
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Odd Binary Number Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-odd-binary-number
Tested Python solution for LeetCode 2864 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 2864, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/maximum-odd-binary-number/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2864 # by problem number
lcpy gen -s maximum_odd_binary_number # by problem name
```
## Problem
You are given a **binary** string `s` that contains at least one `'1'`.
You have to **rearrange** the bits in such a way that the resulting binary number is the **maximum odd binary number** that can be created from this combination.
Return *a string representing the maximum odd binary number that can be created from the given combination.*
**Note** that the resulting string **can** have leading zeros.
### Examples
```
Input: s = "010"
Output: "001"
Explanation: Because there is just one '1', it must be in the last position. So the answer is "001".
```
```
Input: s = "0101"
Output: "1001"
Explanation: One of the '1's must be in the last position. The maximum number that can be made with the remaining digits is "100". So the answer is "1001".
```
### Constraints
* `1 <= s.length <= 100`
* `s` consists only of `'0'` and `'1'`.
* `s` contains at least one `'1'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_odd_binary_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_odd_binary_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def maximum_odd_binary_number(self, s: str) -> str:
ones = s.count("1")
zeros = len(s) - ones
return "1" * (ones - 1) + "0" * zeros + "1"
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Performance of a Team Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-performance-of-a-team
Tested Python solution for LeetCode 1383 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1383, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/maximum-performance-of-a-team/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1383 # by problem number
lcpy gen -s maximum_performance_of_a_team # by problem name
```
## Problem
You are given two integers `n` and `k` and two integer arrays `speed` and `efficiency` both of length `n`. There are `n` engineers numbered from `1` to `n`. `speed[i]` and `efficiency[i]` represent the speed and efficiency of the `i`th engineer respectively.
Choose **at most** `k` different engineers out of the `n` engineers to form a team with the maximum **performance**.
The performance of a team is the sum of its engineers' speeds multiplied by the minimum efficiency among its engineers.
Return the maximum performance of this team. Since the answer can be a huge number, return it **modulo** `10^9 + 7`.
### Examples
```
Input: n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 2
Output: 60
```
**Explanation:** We have the maximum performance of the team by selecting engineer 2 (with speed=10 and efficiency=4) and engineer 5 (with speed=5 and efficiency=7). That is, performance = (10 + 5) \* min(4, 7) = 60.
```
Input: n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 3
Output: 68
```
**Explanation:** This is the same example as the first but k = 3. We can select engineer 1, engineer 2 and engineer 5 to get the maximum performance of the team. That is, performance = (2 + 10 + 5) \* min(5, 4, 7) = 68.
```
Input: n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 4
Output: 72
```
### Constraints
* `1 <= k <= n <= 10^5`
* `speed.length == n`
* `efficiency.length == n`
* `1 <= speed[i] <= 10^5`
* `1 <= efficiency[i] <= 10^8`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_performance_of_a_team/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_performance_of_a_team/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log n)
# Space: O(k)
def max_performance(self, n: int, speed: list[int], efficiency: list[int], k: int) -> int:
mod = 1_000_000_007
engineers = sorted(zip(speed, efficiency, strict=True), key=lambda x: -x[1])
heap: list[int] = []
total = 0
best = 0
for spd, eff in engineers:
heapq.heappush(heap, spd)
total += spd
if len(heap) > k:
total -= heapq.heappop(heap)
best = max(best, total * eff)
return best % mod
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Points You Can Obtain from Cards
Source: https://leetcode-py.wisl.dev/problems/maximum-points-you-can-obtain-from-cards
Tested Python solution for LeetCode 1423 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1423, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/maximum-points-you-can-obtain-from-cards/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1423 # by problem number
lcpy gen -s maximum_points_you_can_obtain_from_cards # by problem name
```
## Problem
There are several cards \arranged in a row\, and each card has an associated number of points. The points are given in the integer array \cardPoints\.
In one step, you can take one card from the beginning or from the end of the row. You have to take exactly \k\ cards.
Your score is the sum of the points of the cards you have taken.
Given the integer array \cardPoints\ and the integer \k\, return the \maximum score\ you can obtain.
### Examples
```
Input: cardPoints = [1,2,3,4,5,6,1], k = 3
Output: 12
```
**Explanation:** After the first step, your score will always be 1. However, choosing the rightmost card first will maximize your total score. The optimal strategy is to take the three cards on the right, giving a final score of 1 + 6 + 5 = 12.
```
Input: cardPoints = [2,2,2], k = 2
Output: 4
```
**Explanation:** Regardless of which two cards you take, your score will always be 4.
```
Input: cardPoints = [9,7,7,9,7,7,9], k = 7
Output: 55
```
**Explanation:** You have to take all the cards. Your score is the sum of points of all cards.
### Constraints
* `1 <= cardPoints.length <= 10^5`
* `1 <= cardPoints[i] <= 10^4`
* `1 <= k <= cardPoints.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_points_you_can_obtain_from_cards/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_points_you_can_obtain_from_cards/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(k)
# Space: O(1)
def max_score(self, card_points: list[int], k: int) -> int:
window = sum(card_points[:k])
best = window
for i in range(1, k + 1):
window += card_points[-i] - card_points[k - i]
best = max(best, window)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(k) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Product Difference Between Two Pairs
Source: https://leetcode-py.wisl.dev/problems/maximum-product-difference-between-two-pairs
Tested Python solution for LeetCode 1913 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 1913, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting), Quicksort. [View on LeetCode](https://leetcode.com/problems/maximum-product-difference-between-two-pairs/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1913 # by problem number
lcpy gen -s maximum_product_difference_between_two_pairs # by problem name
```
## Problem
The **product difference** between two pairs `(a, b)` and `(c, d)` is defined as `(a * b) - (c * d)`.
* For example, the product difference between `(5, 6)` and `(2, 7)` is `(5 * 6) - (2 * 7) = 16`.
Given an integer array `nums`, choose four **distinct** indices `w`, `x`, `y`, and `z` such that the **product difference** between pairs `(nums[w], nums[x])` and `(nums[y], nums[z])` is **maximized**.
Return *the **maximum** such product difference*.
### Examples
```
Input: nums = [5,6,2,7,4]
Output: 34
Explanation: We can choose indices 1 and 3 for the first pair (6, 7) and indices 2 and 4 for the second pair (2, 4).
The product difference is (6 * 7) - (2 * 4) = 34.
```
```
Input: nums = [4,2,5,9,7,4,8]
Output: 64
Explanation: We can choose indices 3 and 6 for the first pair (9, 8) and indices 1 and 5 for the second pair (2, 4).
The product difference is (9 * 8) - (2 * 4) = 64.
```
### Constraints
* 4 \<= nums.length \<= 10^4
* 1 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_difference_between_two_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_difference_between_two_pairs/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_product_difference(self, nums: list[int]) -> int:
max1 = max2 = 0
min1 = min2 = 10_001
for num in nums:
if num > max1:
max1, max2 = num, max1
elif num > max2:
max2 = num
if num < min1:
min1, min2 = num, min1
elif num < min2:
min2 = num
return max1 * max2 - min1 * min2
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Product of the Length of Two
Source: https://leetcode-py.wisl.dev/problems/maximum-product-of-the-length-of-two-palindromic-subsequences
Tested Python solution for LeetCode 2002 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2002, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/maximum-product-of-the-length-of-two-palindromic-subsequences/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2002 # by problem number
lcpy gen -s maximum_product_of_the_length_of_two_palindromic_subsequences # by problem name
```
## Problem
Given a string `s`, find two **disjoint palindromic subsequences** of `s` such that the **product** of their lengths is **maximized**. The two subsequences are **disjoint** if they do not both pick a character at the same index.
Return *the **maximum** possible **product** of the lengths of the two palindromic subsequences*.
A **subsequence** is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters. A string is **palindromic** if it reads the same forward and backward.
### Examples

```
Input: s = "leetcodecom"
Output: 9
Explanation: An optimal solution is to choose "ete" for the 1st subsequence and "cdc" for the 2nd subsequence.
The product of their lengths is: 3 * 3 = 9.
```
```
Input: s = "bb"
Output: 1
Explanation: An optimal solution is to choose "b" (the first character) for the 1st subsequence and "b" (the second character) for the 2nd subsequence.
The product of their lengths is: 1 * 1 = 1.
```
```
Input: s = "accbcaxxcxx"
Output: 25
Explanation: An optimal solution is to choose "accca" for the 1st subsequence and "xxcxx" for the 2nd subsequence.
The product of their lengths is: 5 * 5 = 25.
```
### Constraints
* `2 <= s.length <= 12`
* `s` consists of lowercase English letters only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_of_the_length_of_two_palindromic_subsequences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_of_the_length_of_two_palindromic_subsequences/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^n * n + 3^n) with n = len(s)
# Space: O(2^n)
def max_product(self, s: str) -> int:
n = len(s)
def is_palindrome(mask: int) -> bool:
chars = [s[i] for i in range(n) if mask >> i & 1]
return chars == chars[::-1]
length = [0] * (1 << n)
palindromes: list[int] = []
for mask in range(1, 1 << n):
if is_palindrome(mask):
length[mask] = mask.bit_count()
palindromes.append(mask)
best = 0
for a in palindromes:
if length[a] * length[a] <= best:
continue
remaining = ((1 << n) - 1) ^ a
# enumerate all submasks of the complement of a
sub = remaining
while sub:
if length[sub]:
best = max(best, length[a] * length[sub])
sub = (sub - 1) & remaining
return best
```
## Complexity
| Time | Space |
| --------------------------------- | ------ |
| O(2^n \* n + 3^n) with n = len(s) | O(2^n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Product of Three Numbers
Source: https://leetcode-py.wisl.dev/problems/maximum-product-of-three-numbers
Tested Python solution for LeetCode 628 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 628, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/maximum-product-of-three-numbers/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 628 # by problem number
lcpy gen -s maximum_product_of_three_numbers # by problem name
```
## Problem
You are given an integer array `nums`.
Find three numbers whose product is maximum and return the maximum product.
### Examples
```
Input: nums = [1,2,3]
Output: 6
Explanation: The only three numbers are 1, 2, and 3, so the maximum product is 1 * 2 * 3 = 6.
```
```
Input: nums = [1,2,3,4]
Output: 24
Explanation: The largest product comes from the three greatest numbers: 2 * 3 * 4 = 24.
```
```
Input: nums = [-1,-2,-3]
Output: -6
Explanation: The only three numbers are -1, -2, and -3, so the maximum product is (-1) * (-2) * (-3) = -6.
```
### Constraints
* `3 <= nums.length <= 10^4`
* `-1000 <= nums[i] <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_of_three_numbers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_of_three_numbers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def maximum_product(self, nums: list[int]) -> int:
max1 = max2 = max3 = -(10**18)
min1 = min2 = 10**18
for num in nums:
if num > max1:
max1, max2, max3 = num, max1, max2
elif num > max2:
max2, max3 = num, max2
elif num > max3:
max3 = num
if num < min1:
min1, min2 = num, min1
elif num < min2:
min2 = num
return max(max1 * max2 * max3, max1 * min1 * min2)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Maximum Product of Word Lengths
Source: https://leetcode-py.wisl.dev/problems/maximum-product-of-word-lengths
Tested Python solution for LeetCode 318 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 318, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/maximum-product-of-word-lengths/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 318 # by problem number
lcpy gen -s maximum_product_of_word_lengths # by problem name
```
## Problem
Given a string array \words\, return \the maximum value of\ \length(word\[i]) \* length(word\[j])\ \where the two words do not share common letters\. If no such two words exist, return \0\.
### Examples
```
Input: words = ["abcw","baz","foo","bar","xtfn","abcdef"]
Output: 16
Explanation: The two words can be "abcw", "xtfn".
```
```
Input: words = ["a","ab","abc","d","cd","bcd","abcd"]
Output: 4
Explanation: The two words can be "ab", "cd".
```
```
Input: words = ["a","aa","aaa","aaaa"]
Output: 0
Explanation: No such pair of words.
```
### Constraints
* 2 \<= words.length \<= 1000
* 1 \<= words\[i].length \<= 1000
* words\[i] consists only of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_of_word_lengths/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_of_word_lengths/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * (L + n)) where n = len(words) and L = max word length
# Space: O(n)
def max_product(self, words: list[str]) -> int:
masks = [self._letter_mask(word) for word in words]
best = 0
for i, mask_i in enumerate(masks):
for j in range(i + 1, len(masks)):
if mask_i & masks[j] == 0:
best = max(best, len(words[i]) * len(words[j]))
return best
def _letter_mask(self, word: str) -> int:
mask = 0
for char in word:
mask |= 1 << (ord(char) - ord("a"))
return mask
```
## Complexity
| Time | Space |
| ------------------------------------------------------------ | ----- |
| O(n \* (L + n)) where n = len(words) and L = max word length | O(n) |
## Tags
# Maximum Product Subarray Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-product-subarray
Tested Python solution for LeetCode 152 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 152, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/maximum-product-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 152 # by problem number
lcpy gen -s maximum_product_subarray # by problem name
```
## Problem
Given an integer array `nums`, find a subarray that has the largest product, and return the product.
The test cases are generated so that the answer will fit in a **32-bit** integer.
### Examples
```
Input: nums = [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
```
```
Input: nums = [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
```
### Constraints
* `1 <= nums.length <= 2 * 10^4`
* `-10 <= nums[i] <= 10`
* The product of any subarray of `nums` is **guaranteed** to fit in a **32-bit** integer.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_product_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_product(self, nums: list[int]) -> int:
max_prod = min_prod = result = nums[0]
for num in nums[1:]:
if num < 0:
max_prod, min_prod = min_prod, max_prod
max_prod = max(num, max_prod * num)
min_prod = min(num, min_prod * num)
result = max(result, max_prod)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Maximum Profit in Job Scheduling
Source: https://leetcode-py.wisl.dev/problems/maximum-profit-in-job-scheduling
Tested Python solution for LeetCode 1235 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1235, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/maximum-profit-in-job-scheduling/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1235 # by problem number
lcpy gen -s maximum_profit_in_job_scheduling # by problem name
```
## Problem
We have `n` jobs, where every job is scheduled to be done from `startTime[i]` to `endTime[i]`, obtaining a profit of `profit[i]`.
You're given the `startTime`, `endTime` and `profit` arrays, return the maximum profit you can take such that there are no two jobs in the subset with overlapping time range.
If you choose a job that ends at time `X` you will be able to start another job that starts at time `X`.
### Examples

```
Input: startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70]
Output: 120
```
**Explanation:** The subset chosen is the first and fourth job. Time range \[1-3]+\[3-6] , we get profit of 120 = 50 + 70.

```
Input: startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60]
Output: 150
```
**Explanation:** The subset chosen is the first, fourth and fifth job. Profit obtained 150 = 20 + 70 + 60.

```
Input: startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4]
Output: 6
```
### Constraints
* `1 <= startTime.length == endTime.length == profit.length <= 5 * 10^4`
* `1 <= startTime[i] < endTime[i] <= 10^9`
* `1 <= profit[i] <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_profit_in_job_scheduling/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_profit_in_job_scheduling/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import bisect
class Solution:
# Time: O(n log n)
# Space: O(n)
def job_scheduling(self, start_time: list[int], end_time: list[int], profit: list[int]) -> int:
jobs = sorted(zip(end_time, start_time, profit, strict=False))
dp = [0] * len(jobs)
for i, (_end, start, p) in enumerate(jobs):
# Binary search for latest non-overlapping job
j = bisect.bisect_right([job[0] for job in jobs[:i]], start) - 1
# Take current job + best profit from non-overlapping jobs
take = p + (dp[j] if j >= 0 else 0)
# Skip current job
skip = dp[i - 1] if i > 0 else 0
dp[i] = max(take, skip)
return dp[-1] if jobs else 0
# bisect and insort Explanation:
#
# Etymology: "bisect" = bi (two) + sect (cut) = cut into two parts
# Bisection method = binary search algorithm that repeatedly cuts search space in half
#
# bisect module provides binary search for SORTED lists (O(log n)):
# - bisect_left(arr, x): leftmost insertion position
# - bisect_right(arr, x): rightmost insertion position (default)
# - bisect(arr, x): alias for bisect_right
#
# insort module maintains sorted order while inserting:
# - insort_left(arr, x): insert at leftmost position
# - insort_right(arr, x): insert at rightmost position (default)
# - insort(arr, x): alias for insort_right
#
# Examples:
# arr = [1, 3, 3, 5]
# bisect_left(arr, 3) → 1 (before existing 3s)
# bisect_right(arr, 3) → 3 (after existing 3s)
# bisect_right(arr, 4) → 3 (between 3 and 5)
#
# insort(arr, 4) → arr becomes [1, 3, 3, 4, 5]
#
# In our solution:
# bisect_right([2,4,6], 5) = 2 (insertion position)
# j = 2 - 1 = 1 (index of latest job ending ≤ start_time)
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Maximum Score After Splitting a String
Source: https://leetcode-py.wisl.dev/problems/maximum-score-after-splitting-a-string
Tested Python solution for LeetCode 1422 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1422, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/maximum-score-after-splitting-a-string/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1422 # by problem number
lcpy gen -s maximum_score_after_splitting_a_string # by problem name
```
## Problem
Given a string `s` of zeros and ones, return the maximum score after splitting the string into two **non-empty** substrings (i.e. left substring and right substring).
The score after splitting a string is the number of **zeros** in the **left** substring plus the number of **ones** in the **right** substring.
### Examples
```
Input: s = "011101"
Output: 5
```
**Explanation:** All possible ways of splitting `s` into two non-empty substrings are: `left = "0"` and `right = "11101"`, score = 1 + 4 = 5; `left = "01"` and `right = "1101"`, score = 1 + 3 = 4; `left = "011"` and `right = "101"`, score = 1 + 2 = 3; `left = "0111"` and `right = "01"`, score = 1 + 1 = 2; `left = "01110"` and `right = "1"`, score = 2 + 1 = 3.
```
Input: s = "00111"
Output: 5
```
**Explanation:** When `left = "00"` and `right = "111"`, we get the maximum score = 2 + 3 = 5.
```
Input: s = "1111"
Output: 3
```
### Constraints
* `2 <= s.length <= 500`
* The string `s` consists of characters `'0'` and `'1'` only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_after_splitting_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_after_splitting_a_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_score(self, s: str) -> int:
left_zeros = 1 if s[0] == "0" else 0
right_ones = s[1:].count("1")
best = left_zeros + right_ones
for ch in s[1:-1]:
if ch == "0":
left_zeros += 1
else:
right_ones -= 1
best = max(best, left_zeros + right_ones)
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Score From Removing Substrings
Source: https://leetcode-py.wisl.dev/problems/maximum-score-from-removing-substrings
Tested Python solution for LeetCode 1717 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1717, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/maximum-score-from-removing-substrings/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1717 # by problem number
lcpy gen -s maximum_score_from_removing_substrings # by problem name
```
## Problem
You are given a string `s` and two integers `x` and `y`. You can perform two types of operations any number of times.
* Remove substring `"ab"` and gain `x` points.
* For example, when removing `"ab"` from `"cabxbae"` it becomes `"cxbae"`.
* Remove substring `"ba"` and gain `y` points.
* For example, when removing `"ba"` from `"cabxbae"` it becomes `"cabxe"`.
Return *the maximum points you can gain after applying the above operations on* `s`.
### Examples
```
Input: s = "cdbcbbaaabab", x = 4, y = 5
Output: 19
Explanation:
- Remove the "ba" underlined in "cdbcbbaaabab". Now, s = "cdbcbbaaab" and 5 points are added to the score.
- Remove the "ab" underlined in "cdbcbbaaab". Now, s = "cdbcbbaa" and 4 points are added to the score.
- Remove the "ba" underlined in "cdbcbbaa". Now, s = "cdbcba" and 5 points are added to the score.
- Remove the "ba" underlined in "cdbcba". Now, s = "cdbc" and 5 points are added to the score.
Total score = 5 + 4 + 5 + 5 = 19.
```
```
Input: s = "aabbaaxybbaabb", x = 5, y = 4
Output: 20
```
### Constraints
* 1 \<= s.length \<= 10^5
* 1 \<= x, y \<= 10^4
* s consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_from_removing_substrings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_from_removing_substrings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def maximum_gain(self, s: str, x: int, y: int) -> int:
hi_first, hi_second, hi = "a", "b", x
lo_first, lo_second, lo = "b", "a", y
if x < y:
hi_first, hi_second, hi = "b", "a", y
lo_first, lo_second, lo = "a", "b", x
total = 0
stack: list[str] = []
for ch in s:
if stack and stack[-1] == hi_first and ch == hi_second:
stack.pop()
total += hi
else:
stack.append(ch)
leftover: list[str] = []
for ch in stack:
if leftover and leftover[-1] == lo_first and ch == lo_second:
leftover.pop()
total += lo
else:
leftover.append(ch)
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Score of a Good Subarray
Source: https://leetcode-py.wisl.dev/problems/maximum-score-of-a-good-subarray
Tested Python solution for LeetCode 1793 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1793, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack), Cartesian Tree. [View on LeetCode](https://leetcode.com/problems/maximum-score-of-a-good-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1793 # by problem number
lcpy gen -s maximum_score_of_a_good_subarray # by problem name
```
## Problem
You are given an array of integers `nums` (0-indexed) and an integer `k`.
The **score** of a subarray `(i, j)` is defined as `min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1)`. A **good** subarray is a subarray where `i <= k <= j`.
Return the maximum possible score of a good subarray.
### Examples
```
Input: nums = [1,4,3,7,4,5], k = 3
Output: 15
Explanation: The optimal subarray is (1, 5) with a score of min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15.
```
```
Input: nums = [5,5,4,5,4,1,1,1], k = 0
Output: 20
Explanation: The optimal subarray is (0, 4) with a score of min(5,5,4,5,4) * (4-0+1) = 4 * 5 = 20.
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= nums[i] <= 2 * 10^4`
* `0 <= k < nums.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_of_a_good_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_of_a_good_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def maximum_score(self, nums: list[int], k: int) -> int:
left = right = k
cur_min = nums[k]
best = cur_min
while left > 0 or right < len(nums) - 1:
next_left = nums[left - 1] if left > 0 else 0
next_right = nums[right + 1] if right < len(nums) - 1 else 0
if next_left >= next_right:
left -= 1
else:
right += 1
cur_min = min(cur_min, max(next_left, next_right))
best = max(best, cur_min * (right - left + 1))
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Score Words Formed by Letters
Source: https://leetcode-py.wisl.dev/problems/maximum-score-words-formed-by-letters
Tested Python solution for LeetCode 1255 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1255, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Counting](/catalog/topics/counting), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/maximum-score-words-formed-by-letters/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1255 # by problem number
lcpy gen -s maximum_score_words_formed_by_letters # by problem name
```
## Problem
Given a list of words, list of single letters (might be repeating) and score of every character.
Return the maximum score of any valid set of words formed by using the given letters (words\[i] cannot be used two or more times).
It is not necessary to use all characters in \letters\ and each letter can only be used once. Score of letters \'a'\, \'b'\, \'c'\, ... ,\'z'\ is given by \score\[0]\, \score\[1]\, ... , \score\[25]\ respectively.
### Examples
```
Input: words = ["dog","cat","dad","good"], letters = ["a","a","c","d","d","d","g","o","o"], score = [1,0,9,5,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0]
Output: 23
Explanation:
Score a=1, c=9, d=5, g=3, o=2
Given letters, we can form the words "dad" (5+1+5) and "good" (3+2+2+5) with a score of 23.
Words "dad" and "dog" only get a score of 21.
```
```
Input: words = ["xxxz","ax","bx","cx"], letters = ["z","a","b","c","x","x","x"], score = [4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,10]
Output: 27
Explanation:
Score a=4, b=4, c=4, x=5, z=10
Given letters, we can form the words "ax" (4+5), "bx" (4+5) and "cx" (4+5) with a score of 27.
Word "xxxz" only get a score of 25.
```
```
Input: words = ["leetcode"], letters = ["l","e","t","c","o","d"], score = [0,0,1,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0]
Output: 0
Explanation:
Letter "e" can only be used once.
```
### Constraints
* 1 \<= words.length \<= 14
* 1 \<= words\[i].length \<= 15
* 1 \<= letters.length \<= 100
* letters\[i].length == 1
* score.length == 26
* 0 \<= score\[i] \<= 10
* words\[i], letters\[i] contains only lower case English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_words_formed_by_letters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_score_words_formed_by_letters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
def max_score_words(self, words: list[str], letters: list[str], score: list[int]) -> int:
word_counts = [Counter(word) for word in words]
word_scores = [
sum(score[ord(c) - 97] * cnt for c, cnt in Counter(word).items()) for word in words
]
n = len(words)
def backtrack(i: int, available: Counter) -> int:
if i == n:
return 0
best = backtrack(i + 1, available)
counts = word_counts[i]
if all(available[c] >= cnt for c, cnt in counts.items()):
for c, cnt in counts.items():
available[c] -= cnt
best = max(best, word_scores[i] + backtrack(i + 1, available))
for c, cnt in counts.items():
available[c] += cnt
return best
return backtrack(0, Counter(letters))
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Size Subarray Sum Equals k
Source: https://leetcode-py.wisl.dev/problems/maximum-size-subarray-sum-equals-k
Tested Python solution for LeetCode 325 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 325, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 325 # by problem number
lcpy gen -s maximum_size_subarray_sum_equals_k # by problem name
```
## Problem
Given an integer array `nums` and an integer `k`, return *the maximum length of a* subarray *that sums to* `k`. If there is not one, return `0` instead.
### Examples
```
Input: nums = [1,-1,5,-2,3], k = 3
Output: 4
Explanation: The subarray [1, -1, 5, -2] sums to 3 and is the longest.
```
```
Input: nums = [-2,-1,2,1], k = 1
Output: 2
Explanation: The subarray [-1, 2] sums to 1 and is the longest.
```
### Constraints
* `1 <= nums.length <= 2 * 10^5`
* `-10^4 <= nums[i] <= 10^4`
* `-10^9 <= k <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_size_subarray_sum_equals_k/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_size_subarray_sum_equals_k/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) — single pass, O(1) hash lookups
# Space: O(n) — first-occurrence index per prefix sum
def max_sub_array_len(self, nums: list[int], k: int) -> int:
first_index = {0: -1}
prefix_sum = 0
best = 0
for i, num in enumerate(nums):
prefix_sum += num
if prefix_sum - k in first_index:
best = max(best, i - first_index[prefix_sum - k])
if prefix_sum not in first_index:
first_index[prefix_sum] = i
return best
```
## Complexity
| Time | Space |
| ------------------------------------- | -------------------------------------------- |
| O(n) — single pass, O(1) hash lookups | O(n) — first-occurrence index per prefix sum |
## Tags
# Maximum Subarray Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/maximum-subarray
Tested Python solution for LeetCode 53 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 53, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/maximum-subarray/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 53 # by problem number
lcpy gen -s maximum_subarray # by problem name
```
## Problem
Given an integer array `nums`, find the subarray with the largest sum, and return its sum.
### Examples
```
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
```
**Explanation:** The subarray \[4,-1,2,1] has the largest sum 6.
```
Input: nums = [1]
Output: 1
```
**Explanation:** The subarray \[1] has the largest sum 1.
```
Input: nums = [5,4,-1,7,8]
Output: 23
```
**Explanation:** The subarray \[5,4,-1,7,8] has the largest sum 23.
### Constraints
* `1 <= nums.length <= 10^5`
* `-10^4 <= nums[i] <= 10^4`
**Follow up:** If you have figured out the `O(n)` solution, try coding another solution using the **divide and conquer** approach, which is more subtle.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_subarray/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def max_sub_array(self, nums: list[int]) -> int:
max_sum = current_sum = nums[0]
for i in range(1, len(nums)):
current_sum = max(nums[i], current_sum + nums[i])
max_sum = max(max_sum, current_sum)
return max_sum
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Maximum Subarray Min-Product Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-subarray-min-product
Tested Python solution for LeetCode 1856 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1856, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack), [Prefix Sum](/catalog/topics/prefix-sum), Cartesian Tree. [View on LeetCode](https://leetcode.com/problems/maximum-subarray-min-product/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1856 # by problem number
lcpy gen -s maximum_subarray_min_product # by problem name
```
## Problem
The **min-product** of an array is equal to the **minimum value** in the array **multiplied by** the array's **sum**.
* For example, the array `[3,2,5]` (minimum value is `2`) has a min-product of `2 * (3+2+5) = 2 * 10 = 20`.
Given an array of integers `nums`, return *the **maximum min-product** of any **non-empty subarray** of* `nums`. Since the answer may be large, return it **modulo** `10^9 + 7`.
Note that the min-product should be maximized **before** performing the modulo operation. Testcases are generated such that the maximum min-product **without** modulo will fit in a **64-bit signed integer**.
A **subarray** is a **contiguous** part of an array.
### Examples
```
Input: nums = [1,2,3,2]
Output: 14
Explanation: The maximum min-product is achieved with the subarray [2,3,2] (minimum value is 2).
2 * (2+3+2) = 2 * 7 = 14.
```
```
Input: nums = [2,3,3,1,2]
Output: 18
Explanation: The maximum min-product is achieved with the subarray [3,3] (minimum value is 3).
3 * (3+3) = 3 * 6 = 18.
```
```
Input: nums = [3,1,5,6,4,2]
Output: 60
Explanation: The maximum min-product is achieved with the subarray [5,6,4] (minimum value is 4).
4 * (5+6+4) = 4 * 15 = 60.
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= nums[i] <= 10^7`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_subarray_min_product/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/maximum_subarray_min_product/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def max_sum_min_product(self, nums: list[int]) -> int:
mod = 1_000_000_007
prefix = [0]
for num in nums:
prefix.append(prefix[-1] + num)
stack: list[int] = []
best = 0
for i, num in enumerate([*nums, 0]):
while stack and nums[stack[-1]] >= num:
height = nums[stack.pop()]
left = stack[-1] if stack else -1
best = max(best, height * (prefix[i] - prefix[left + 1]))
stack.append(i)
return best % mod
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Maximum Subsequence Score Python Solution
Source: https://leetcode-py.wisl.dev/problems/maximum-subsequence-score
Tested Python solution for LeetCode 2542 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2542, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/maximum-subsequence-score/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2542 # by problem number
lcpy gen -s maximum_subsequence_score # by problem name
```
## Problem
You are given two \0-indexed\ integer arrays \nums1\ and \nums2\ of equal length \n\ and a positive integer \k\. You must choose a \subsequence\ of indices from \nums1\ of length \k\.
\
For chosen indices \i\0\\, \i\1\\, ..., \i\k - 1\\, your \score\ is defined as:\
nums1\ multiplied with the \minimum\ of the selected elements from \nums2\.\(nums1\[i\0\] + nums1\[i\1\] +...+ nums1\[i\k - 1\]) \* min(nums2\[i\0\] , nums2\[i\1\], ... ,nums2\[i\k - 1\])\.\Return \the \maximum\ possible score.\\
\A \subsequence\ of indices of an array is a set that can be derived from the set \\{0, 1, ..., n-1}\ by deleting some or no elements.\
head\ of a linked list, which contains a series of integers \separated\ by \0\'s. The \beginning\ and \end\ of the linked list will have \Node.val == 0\.
For \every\ two consecutive \0\'s, \merge\ all the nodes lying in between them into a single node whose value is the \sum\ of all the merged nodes. The modified list should not contain any \0\'s.
Return \the head of the modified linked list\.
### Examples

```
Input: head = [0,3,1,0,4,5,2,0]
Output: [4,11]
Explanation: The modified list contains the sum of the nodes marked in green: 3 + 1 = 4, and the sum of the nodes marked in red: 4 + 5 + 2 = 11.
```

```
Input: head = [0,1,0,3,0,2,2,0]
Output: [1,3,4]
Explanation: The modified list contains the sum of the nodes marked in green: 1 = 1, the sum of the nodes marked in red: 3 = 3, and the sum of the nodes marked in yellow: 2 + 2 = 4.
```
### Constraints
* The number of nodes in the list is in the range `[3, 2 * 10^5]`.
* `0 <= Node.val <= 1000`
* There are no two consecutive nodes with `Node.val == 0`.
* The beginning and end of the linked list have `Node.val == 0`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_nodes_in_between_zeros/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_nodes_in_between_zeros/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n) where n is the number of nodes in the input list
# Space: O(1), nodes are merged in place
def merge_nodes(self, head: ListNode[int] | None) -> ListNode[int] | None:
if head is None:
return None
tail = head
node = head.next
total = 0
first = True
while node is not None:
if node.val == 0:
if first:
head.val = total
first = False
else:
nxt = tail.next
assert nxt is not None
nxt.val = total
tail = nxt
total = 0
else:
total += node.val
node = node.next
tail.next = None
return head
```
## Complexity
| Time | Space |
| ----------------------------------------------------- | ------------------------------- |
| O(n) where n is the number of nodes in the input list | O(1), nodes are merged in place |
## Tags
[NeetCode All](/catalog/neetcode).
# Merge Sorted Array Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/merge-sorted-array
Tested Python solution for LeetCode 88 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 88, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/merge-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 88 # by problem number
lcpy gen -s merge_sorted_array # by problem name
```
## Problem
You are given two integer arrays `nums1` and `nums2`, sorted in **non-decreasing order**, and two integers `m` and `n`, representing the number of elements in `nums1` and `nums2` respectively.
**Merge** `nums1` and `nums2` into a single array sorted in **non-decreasing order**.
The final sorted array should not be returned by the function, but instead be *stored inside the array* `nums1`. To accommodate this, `nums1` has a length of `m + n`, where the first `m` elements denote the elements that should be merged, and the last `n` elements are set to `0` and should be ignored. `nums2` has a length of `n`.
### Examples
```
Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
```
**Explanation:** The arrays we are merging are \[1,2,3] and \[2,5,6].
The result of the merge is \[\1\,\2\,2,\3\,5,6], with the underlined elements coming from nums1.
```
Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]
```
**Explanation:** The arrays we are merging are \[1] and \[].
The result of the merge is \[1].
```
Input: nums1 = [0], m = 0, nums2 = [1], n = 1
Output: [1]
```
**Explanation:** The arrays we are merging are \[] and \[1].
The result of the merge is \[1].
Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1.
### Constraints
* nums1.length == m + n
* nums2.length == n
* 0 \<= m, n \<= 200
* 1 \<= m + n \<= 200
* -10^9 \<= nums1\[i], nums2\[j] \<= 10^9
**Follow up:** Can you come up with an algorithm that runs in `O(m + n)` time?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m + n)
# Space: O(1)
def merge(self, nums1: list[int], m: int, nums2: list[int], n: int) -> None:
# Fill from the back to avoid overwriting nums1's real elements
index = m + n - 1
i = m - 1
j = n - 1
while i >= 0 and j >= 0:
if nums1[i] > nums2[j]:
nums1[index] = nums1[i]
i -= 1
else:
nums1[index] = nums2[j]
j -= 1
index -= 1
# Only nums2 leftovers can remain
while j >= 0:
nums1[index] = nums2[j]
j -= 1
index -= 1
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(m + n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Merge Strings Alternately Python Solution
Source: https://leetcode-py.wisl.dev/problems/merge-strings-alternately
Tested Python solution for LeetCode 1768 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 1768, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/merge-strings-alternately/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1768 # by problem number
lcpy gen -s merge_strings_alternately # by problem name
```
## Problem
You are given two strings `word1` and `word2`. Merge the strings by adding letters in alternating order, starting with `word1`. If a string is longer than the other, append the additional letters onto the end of the merged string.
Return *the merged string.*
### Examples
```
Input: word1 = "abc", word2 = "pqr"
Output: "apbqcr"
Explanation: The merged string will be merged as so:
word1: a b c
word2: p q r
merged: a p b q c r
```
```
Input: word1 = "ab", word2 = "pqrs"
Output: "apbqrs"
Explanation: Notice that as word2 is longer, "rs" is appended to the end.
word1: a b
word2: p q r s
merged: a p b q r s
```
```
Input: word1 = "abcd", word2 = "pq"
Output: "apbqcd"
Explanation: Notice that as word1 is longer, "cd" is appended to the end.
word1: a b c d
word2: p q
merged: a p b q c d
```
### Constraints
* 1 \<= word1.length, word2.length \<= 100
* word1 and word2 consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_strings_alternately/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_strings_alternately/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(n + m)
def merge_alternately(self, word1: str, word2: str) -> str:
result: list[str] = []
i = 0
n, m = len(word1), len(word2)
while i < n or i < m:
if i < n:
result.append(word1[i])
if i < m:
result.append(word2[i])
i += 1
return "".join(result)
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + m) | O(n + m) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Merge Triplets to Form Target Triplet
Source: https://leetcode-py.wisl.dev/problems/merge-triplets-to-form-target-triplet
Tested Python solution for LeetCode 1899 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1899, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/merge-triplets-to-form-target-triplet/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1899 # by problem number
lcpy gen -s merge_triplets_to_form_target_triplet # by problem name
```
## Problem
A **triplet** is an array of three integers. You are given a 2D integer array `triplets`, where `triplets[i] = [a_i, b_i, c_i]` describes the `i^th` **triplet**. You are also given an integer array `target = [x, y, z]` that describes the **triplet** you want to obtain.
To obtain `target`, you may apply the following operation on `triplets` **any number** of times (possibly **zero**):
* Choose two indices (**0-indexed**) `i` and `j` (`i != j`) and **update** `triplets[j]` to become `[max(a_i, a_j), max(b_i, b_j), max(c_i, c_j)]`.
Return `true` *if it is possible to obtain the* `target` \* **triplet** `[x, y, z]` as an **element** of\* `triplets`, or `false` otherwise.
### Examples
```
Input: triplets = [[2,5,3],[1,8,4],[1,7,5]], target = [2,7,5]
Output: true
Explanation: Perform the following operations:
- Choose the first and last triplets [[2,5,3],[1,8,4],[1,7,5]]. Update the last triplet to be [max(2,1), max(5,7), max(3,5)] = [2,7,5]. triplets = [[2,5,3],[1,8,4],[2,7,5]].
The target triplet [2,7,5] is now an element of triplets.
```
```
Input: triplets = [[3,4,5],[4,5,6]], target = [3,2,5]
Output: false
Explanation: It is impossible to have [3,2,5] as an element because there is no 2 in any of the triplets.
```
```
Input: triplets = [[2,5,3],[2,3,4],[1,2,5],[5,2,3]], target = [5,5,5]
Output: true
Explanation: Perform the following operations:
- Choose the first and third triplets [[2,5,3],[2,3,4],[1,2,5],[5,2,3]]. Update the third triplet to be [max(2,1), max(5,2), max(3,5)] = [2,5,5]. triplets = [[2,5,3],[2,3,4],[2,5,5],[5,2,3]].
- Choose the third and fourth triplets [[2,5,3],[2,3,4],[2,5,5],[5,2,3]]. Update the fourth triplet to be [max(2,5), max(5,2), max(5,3)] = [5,5,5]. triplets = [[2,5,3],[2,3,4],[2,5,5],[5,5,5]].
The target triplet [5,5,5] is now an element of triplets.
```
### Constraints
* 1 \<= triplets.length \<= 10^5
* `triplets[i].length == target.length == 3`
* 1 \<= a\_i, b\_i, c\_i, x, y, z \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_triplets_to_form_target_triplet/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_triplets_to_form_target_triplet/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def merge_triplets(self, triplets: list[list[int]], target: list[int]) -> bool:
tx, ty, tz = target
found_x = found_y = found_z = False
for a, b, c in triplets:
# Skip any triplet that would push a component past the target.
if a > tx or b > ty or c > tz:
continue
if a == tx:
found_x = True
if b == ty:
found_y = True
if c == tz:
found_z = True
if found_x and found_y and found_z:
return True
return found_x and found_y and found_z
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Merge Two 2D Arrays by Summing Values
Source: https://leetcode-py.wisl.dev/problems/merge-two-2d-arrays-by-summing-values
Tested Python solution for LeetCode 2570 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2570, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/merge-two-2d-arrays-by-summing-values/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2570 # by problem number
lcpy gen -s merge_two_2d_arrays_by_summing_values # by problem name
```
## Problem
You are given two \2D\ integer arrays \nums1\ and \nums2\.
* \nums1\[i] = \[id\i\, val\i\]\ indicate that the number with the id \id\i\\ has a value equal to \val\i\\.
* \nums2\[i] = \[id\i\, val\i\]\ indicate that the number with the id \id\i\\ has a value equal to \val\i\\.
Each array contains \unique\ ids and is sorted in \ascending\ order by id.
Merge the two arrays into one array that is sorted in ascending order by id, respecting the following conditions:
* Only ids that appear in at least one of the two arrays should be included in the resulting array.
* Each id should be included \only once\ and its value should be the sum of the values of this id in the two arrays. If the id does not exist in one of the two arrays, then assume its value in that array to be \0\.
Return \the resulting array\. The returned array must be sorted in ascending order by id.
### Examples
```
Input: nums1 = [[1,2],[2,3],[4,5]], nums2 = [[1,4],[3,2],[4,1]]
Output: [[1,6],[2,3],[3,2],[4,6]]
Explanation: The resulting array contains the following:
- id = 1, the value of this id is 2 + 4 = 6.
- id = 2, the value of this id is 3.
- id = 3, the value of this id is 2.
- id = 4, the value of this id is 5 + 1 = 6.
```
```
Input: nums1 = [[2,4],[3,6],[5,5]], nums2 = [[1,3],[4,3]]
Output: [[1,3],[2,4],[3,6],[4,3],[5,5]]
Explanation: There are no common ids, so we just include each id with its value in the resulting list.
```
### Constraints
* 1 \<= nums1.length, nums2.length \<= 200
* nums1\[i].length == nums2\[j].length == 2
* 1 \<= id\i\, val\i\ \<= 1000
* Both arrays contain unique ids.
* Both arrays are in strictly ascending order by id.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_two_2d_arrays_by_summing_values/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_two_2d_arrays_by_summing_values/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m + n)
# Space: O(m + n) for the output
def merge_arrays(self, nums1: list[list[int]], nums2: list[list[int]]) -> list[list[int]]:
result: list[list[int]] = []
i = 0
j = 0
while i < len(nums1) and j < len(nums2):
id1, val1 = nums1[i]
id2, val2 = nums2[j]
if id1 == id2:
result.append([id1, val1 + val2])
i += 1
j += 1
elif id1 < id2:
result.append([id1, val1])
i += 1
else:
result.append([id2, val2])
j += 1
result.extend(nums1[i:])
result.extend(nums2[j:])
return result
```
## Complexity
| Time | Space |
| -------- | ----------------------- |
| O(m + n) | O(m + n) for the output |
## Tags
[NeetCode All](/catalog/neetcode).
# Merge Two Binary Trees Python Solution
Source: https://leetcode-py.wisl.dev/problems/merge-two-binary-trees
Tested Python solution for LeetCode 617 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 617, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/merge-two-binary-trees/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 617 # by problem number
lcpy gen -s merge_two_binary_trees # by problem name
```
## Problem
You are given two binary trees `root1` and `root2`.
Imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge the two trees into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of the new tree.
Return *the merged tree*.
**Note:** The merging process must start from the root nodes of both trees.
### Examples

```
Input: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
Output: [3,4,5,5,4,null,7]
```
```
Input: root1 = [1], root2 = [1,2]
Output: [2,2]
```
### Constraints
* The number of nodes in both trees is in the range \[0, 2000].
* -10^4 \<= Node.val \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_two_binary_trees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_two_binary_trees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) where n is the smaller tree's node count
# Space: O(h)
def merge_trees(
self, root1: TreeNode[int] | None, root2: TreeNode[int] | None
) -> TreeNode[int] | None:
if root1 is None:
return root2
if root2 is None:
return root1
root1.val += root2.val
root1.left = self.merge_trees(root1.left, root2.left)
root1.right = self.merge_trees(root1.right, root2.right)
return root1
```
## Complexity
| Time | Space |
| --------------------------------------------- | ----- |
| O(n) where n is the smaller tree's node count | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Merge Two Sorted Lists Python Solution
Source: https://leetcode-py.wisl.dev/problems/merge-two-sorted-lists
Tested Python solution for LeetCode 21 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 21, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/merge-two-sorted-lists/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 21 # by problem number
lcpy gen -s merge_two_sorted_lists # by problem name
```
## Problem
You are given the heads of two sorted linked lists `list1` and `list2`.
Merge the two lists into one **sorted** list. The list should be made by splicing together the nodes of the first two lists.
Return *the head of the merged linked list*.
### Examples

```
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
```
```
Input: list1 = [], list2 = []
Output: []
```
```
Input: list1 = [], list2 = [0]
Output: [0]
```
### Constraints
* The number of nodes in both lists is in the range `[0, 50]`.
* `-100 <= Node.val <= 100`
* Both `list1` and `list2` are sorted in **non-decreasing** order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_two_sorted_lists/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/merge_two_sorted_lists/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(m + n)
# Space: O(1)
def merge_two_lists(
self, list1: ListNode[int] | None, list2: ListNode[int] | None
) -> ListNode[int] | None:
dummy = ListNode(0)
current = dummy
while list1 and list2:
if list1.val <= list2.val:
current.next = list1
list1 = list1.next
else:
current.next = list2
list2 = list2.next
current = current.next
current.next = list1 or list2
return dummy.next
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(m + n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Middle of the Linked List Python Solution
Source: https://leetcode-py.wisl.dev/problems/middle-of-the-linked-list
Tested Python solution for LeetCode 876 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 876, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/middle-of-the-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 876 # by problem number
lcpy gen -s middle_of_the_linked_list # by problem name
```
## Problem
Given the `head` of a singly linked list, return *the middle node of the linked list*.
If there are two middle nodes, return **the second middle** node.
### Examples

```
Input: head = [1,2,3,4,5]
Output: [3,4,5]
```
**Explanation:** The middle node of the list is node 3.

```
Input: head = [1,2,3,4,5,6]
Output: [4,5,6]
```
**Explanation:** Since the list has two middle nodes with values 3 and 4, we return the second one.
### Constraints
* The number of nodes in the list is in the range `[1, 100]`.
* `1 <= Node.val <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/middle_of_the_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/middle_of_the_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def middle_node(self, head: ListNode[int] | None) -> ListNode[int] | None:
slow = fast = head
while fast and fast.next:
assert slow is not None
slow = slow.next
fast = fast.next.next
return slow
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Min Cost Climbing Stairs Python Solution
Source: https://leetcode-py.wisl.dev/problems/min-cost-climbing-stairs
Tested Python solution for LeetCode 746 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 746, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/min-cost-climbing-stairs/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 746 # by problem number
lcpy gen -s min_cost_climbing_stairs # by problem name
```
## Problem
You are given an integer array `cost` where `cost[i]` is the cost of `ith` step on a staircase. Once you pay the cost, you can either climb one or two steps.
You can either start from the step with index `0`, or the step with index `1`.
Return *the minimum cost to reach the top of the floor*.
### Examples
```
Input: cost = [10,15,20]
Output: 15
Explanation: You will start at index 1.
- Pay 15 and climb two steps to reach the top.
The total cost is 15.
```
```
Input: cost = [1,100,1,1,1,100,1,1,100,1]
Output: 6
Explanation: You will start at index 0.
- Pay 1 and climb two steps to reach index 2.
- Pay 1 and climb two steps to reach index 4.
- Pay 1 and climb two steps to reach index 6.
- Pay 1 and climb one step to reach index 7.
- Pay 1 and climb two steps to reach index 9.
- Pay 1 and climb one step to reach the top.
The total cost is 6.
```
### Constraints
* 2 \<= cost.length \<= 1000
* 0 \<= cost\[i] \<= 999
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_cost_climbing_stairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_cost_climbing_stairs/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def min_cost_climbing_stairs(self, cost: list[int]) -> int:
# dp[i] = min cost to reach step i (top is index n).
# Start at step 0 or 1 for free, so dp[0] = dp[1] = 0.
prev_two, prev_one = 0, 0 # dp[i-2], dp[i-1]
for step_cost in cost:
current = step_cost + min(prev_one, prev_two)
prev_two, prev_one = prev_one, current
# Top reached from either of the last two steps (already paid)
return min(prev_one, prev_two)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Min Cost to Connect All Points Python Solution
Source: https://leetcode-py.wisl.dev/problems/min-cost-to-connect-all-points
Tested Python solution for LeetCode 1584 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 1584, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory), Minimum Spanning Tree. [View on LeetCode](https://leetcode.com/problems/min-cost-to-connect-all-points/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1584 # by problem number
lcpy gen -s min_cost_to_connect_all_points # by problem name
```
## Problem
You are given an array `points` representing integer coordinates of some points on a 2D-plane, where `points[i] = [xi, yi]`.
The cost of connecting two points `[xi, yi]` and `[xj, yj]` is the **manhattan distance** between them: `|xi - xj| + |yi - yj|`, where `|val|` denotes the absolute value of `val`.
Return *the minimum cost to make all points connected*. All points are connected if there is **exactly one** simple path between any two points.
### Examples

```
Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
Output: 20
Explanation:

We can connect the points as shown above to get the minimum cost of 20.
Notice that there is a unique path between every pair of points.
```
```
Input: points = [[3,12],[-2,5],[-4,1]]
Output: 18
```
### Constraints
* 1 \<= points.length \<= 1000
* -10^6 \<= xi, yi \<= 10^6
* All pairs (xi, yi) are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_cost_to_connect_all_points/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_cost_to_connect_all_points/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n^2 * log(n)) for Prim's algorithm
# Space: O(n)
def min_cost_connect_points(self, points: list[list[int]]) -> int:
n = len(points)
if n <= 1:
return 0
def manhattan_distance(p1: list[int], p2: list[int]) -> int:
return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])
visited = [False] * n
min_heap: list[tuple[int, int]] = [(0, 0)] # (cost, node)
total_cost = 0
edges_used = 0
while min_heap and edges_used < n:
cost, node = heapq.heappop(min_heap)
if visited[node]:
continue
visited[node] = True
total_cost += cost
edges_used += 1
for neighbor in range(n):
if not visited[neighbor]:
distance = manhattan_distance(points[node], points[neighbor])
heapq.heappush(min_heap, (distance, neighbor))
return total_cost
```
## Complexity
| Time | Space |
| ------------------------------------- | ----- |
| O(n^2 \* log(n)) for Prim's algorithm | O(n) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Minimum Distance Between BST Nodes
Source: https://leetcode-py.wisl.dev/problems/min-distance-in-bst
Tested Python solution for LeetCode 783 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 783, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/min-distance-in-bst/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 783 # by problem number
lcpy gen -s min_distance_in_bst # by problem name
```
## Problem
Given the `root` of a Binary Search Tree (BST), return *the minimum difference between the values of any two different nodes in the tree*.
### Examples

```
Input: root = [4,2,6,1,3]
Output: 1
```

```
Input: root = [1,0,48,null,null,12,49]
Output: 1
```
### Constraints
* The number of nodes in the tree is in the range \[2, 100].
* 0 \<= Node.val \<= 10^5
* Note: This question is the same as 530: [https://leetcode.com/problems/minimum-absolute-difference-in-bst/](https://leetcode.com/problems/minimum-absolute-difference-in-bst/)
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_distance_in_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_distance_in_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def min_diff_in_bst(self, root: TreeNode[int]) -> int:
prev: int | None = None
best = 10**5
node: TreeNode[int] | None = root
stack: list[TreeNode[int]] = []
while stack or node:
while node:
stack.append(node)
node = node.left
node = stack.pop()
if prev is not None:
best = min(best, node.val - prev)
prev = node.val
node = node.right
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Min Stack Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/min-stack
Tested Python solution for LeetCode 155 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 155, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Design](/catalog/topics/design). [View on LeetCode](https://leetcode.com/problems/min-stack/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 155 # by problem number
lcpy gen -s min_stack # by problem name
```
## Problem
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
Implement the `MinStack` class:
* `MinStack()` initializes the stack object.
* `void push(int val)` pushes the element `val` onto the stack.
* `void pop()` removes the element on the top of the stack.
* `int top()` gets the top element of the stack.
* `int getMin()` retrieves the minimum element in the stack.
You must implement a solution with `O(1)` time complexity for each function.
### Examples
```
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
```
### Constraints
* `-2^31 <= val <= 2^31 - 1`
* Methods `pop`, `top` and `getMin` operations will always be called on **non-empty** stacks.
* At most `3 * 10^4` calls will be made to `push`, `pop`, `top`, and `getMin`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_stack/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/min_stack/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class MinStack:
# Time: O(1) for all operations
# Space: O(n) where n is number of elements
def __init__(self) -> None:
self.stack: list[int] = []
self.min_stack: list[int] = []
# Time: O(1)
# Space: O(1)
def push(self, val: int) -> None:
self.stack.append(val)
if not self.min_stack or val <= self.min_stack[-1]:
self.min_stack.append(val)
# Time: O(1)
# Space: O(1)
def pop(self) -> None:
if self.stack[-1] == self.min_stack[-1]:
self.min_stack.pop()
self.stack.pop()
# Time: O(1)
# Space: O(1)
def top(self) -> int:
return self.stack[-1]
# Time: O(1)
# Space: O(1)
def get_min(self) -> int:
return self.min_stack[-1]
# Example walkthrough: push(-2), push(0), push(-3), getMin(), pop(), top(), getMin()
#
# Initial: stack=[], min_stack=[]
#
# push(-2): stack=[-2], min_stack=[-2] (first element, add to both)
# push(0): stack=[-2,0], min_stack=[-2] (0 > -2, don't add to min_stack)
# push(-3): stack=[-2,0,-3], min_stack=[-2,-3] (-3 <= -2, add to min_stack)
# getMin(): return -3 (top of min_stack)
# pop(): stack=[-2,0], min_stack=[-2] (-3 was min, remove from both stacks)
# top(): return 0 (top of main stack)
# getMin(): return -2 (top of min_stack after pop)
```
## Complexity
| Time | Space |
| ----------------------- | ---------------------------------- |
| O(1) for all operations | O(n) where n is number of elements |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Minesweeper Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/minesweeper
Tested Python solution for LeetCode 529 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 529, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/minesweeper/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 529 # by problem number
lcpy gen -s minesweeper # by problem name
```
## Problem
Let's play the minesweeper game ([Wikipedia](https://en.wikipedia.org/wiki/Minesweeper_%28video_game%29), [online game](http://minesweeperonline.com))!
You are given an `m x n` char matrix `board` representing the game board where:
* `'M'` represents an unrevealed mine,
* `'E'` represents an unrevealed empty square,
* `'B'` represents a revealed blank square that has no adjacent mines (i.e., above, below, left, right, and all 4 diagonals),
* digit (`'1'` to `'8'`) represents how many mines are adjacent to this revealed square, and
* `'X'` represents a revealed mine.
You are also given an integer array `click` where `click = [clickr, clickc]` represents the next click position among all the unrevealed squares (`'M'` or `'E'`).
Return *the board after revealing this position according to the following rules*:
1. If a mine `'M'` is revealed, then the game is over. You should change it to `'X'`.
2. If an empty square `'E'` with no adjacent mines is revealed, then change it to a revealed blank `'B'` and all of its adjacent unrevealed squares should be revealed recursively.
3. If an empty square `'E'` with at least one adjacent mine is revealed, then change it to a digit (`'1'` to `'8'`) representing the number of adjacent mines.
4. Return the board when no more squares will be revealed.
### Examples

```
Input: board = [["E","E","E","E","E"],["E","E","M","E","E"],["E","E","E","E","E"],["E","E","E","E","E"]], click = [3,0]
Output: [["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]
```

```
Input: board = [["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]], click = [1,2]
Output: [["B","1","E","1","B"],["B","1","X","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]
```
### Constraints
* `m == board.length`
* `n == board[i].length`
* `1 <= m, n <= 50`
* `board[i][j]` is either `'M'`, `'E'`, `'B'`, or a digit from `'1'` to `'8'`.
* `click.length == 2`
* `0 <= clickr < m`
* `0 <= clickc < n`
* `board[clickr][clickc]` is either `'M'` or `'E'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minesweeper/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minesweeper/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
DIRECTIONS: tuple[tuple[int, int], ...] = (
(-1, -1),
(-1, 0),
(-1, 1),
(0, -1),
(0, 1),
(1, -1),
(1, 0),
(1, 1),
)
# Time: O(m * n)
# Space: O(m * n)
def update_board(self, board: list[list[str]], click: list[int]) -> list[list[str]]:
rows, cols = len(board), len(board[0])
row, col = click
if board[row][col] == "M":
board[row][col] = "X"
return board
queue: deque[tuple[int, int]] = deque([(row, col)])
while queue:
r, c = queue.popleft()
mines = self._adjacent_mines(board, r, c)
if mines:
board[r][c] = str(mines)
continue
board[r][c] = "B"
for dr, dc in self.DIRECTIONS:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and board[nr][nc] == "E":
board[nr][nc] = "B"
queue.append((nr, nc))
return board
def _adjacent_mines(self, board: list[list[str]], r: int, c: int) -> int:
rows, cols = len(board), len(board[0])
return sum(
1
for dr, dc in self.DIRECTIONS
if 0 <= r + dr < rows and 0 <= c + dc < cols and board[r + dr][c + dc] == "M"
)
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
# Mini Parser Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/mini-parser
Tested Python solution for LeetCode 385 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 385, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Depth-First Search](/catalog/topics/depth-first-search). [View on LeetCode](https://leetcode.com/problems/mini-parser/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 385 # by problem number
lcpy gen -s mini_parser # by problem name
```
## Problem
Given a string s represents the serialization of a nested list, implement a parser to deserialize it and return the deserialized `NestedInteger`.
Each element is either an integer or a list whose elements may also be integers or other lists.
### Examples
```
Input: s = "324"
Output: 324
Explanation: You should return a NestedInteger object which contains a single integer 324.
```
```
Input: s = "[123,[456,[789]]]"
Output: [123,[456,[789]]]
Explanation: Return a NestedInteger object containing a nested list with 2 elements:
1. An integer containing value 123.
2. A nested list containing two elements:
i. An integer containing value 456.
ii. A nested list with one element:
a. An integer containing value 789
```
### Constraints
* 1 \<= s.length \<= 5 \* 10\4\
* s consists of digits, square brackets `"[]"`, negative sign `'-'`, and commas `','`.
* s is the serialization of valid `NestedInteger`.
* All the values in the input are in the range \[-10\6\, 10\6\].
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/mini_parser/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/mini_parser/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class NestedInteger:
def __init__(self, value: int | None = None) -> None:
self._integer: int | None = value
self._list: list[NestedInteger] | None = None if value is not None else []
def is_integer(self) -> bool:
return self._list is None
def add(self, elem: NestedInteger) -> None:
items = self._list
if items is None:
items = []
self._integer = None
self._list = items
items.append(elem)
def set_integer(self, value: int) -> None:
self._integer = value
self._list = None
def get_integer(self) -> int | None:
return self._integer
def get_list(self) -> list[NestedInteger] | None:
return self._list
class Solution:
# Time: O(n) - each character is consumed exactly once
# Space: O(d) - stack holds one NestedInteger per open bracket (d = nesting depth)
def deserialize(self, s: str) -> NestedInteger:
stack: list[NestedInteger] = []
result: NestedInteger | None = None
num: int | None = None
i = 0
while i < len(s):
char = s[i]
if char.isdigit() or char == "-":
end = i + 1
while end < len(s) and s[end].isdigit():
end += 1
num = int(s[i:end])
i = end
continue
if char == "[":
stack.append(NestedInteger())
else:
if num is not None:
stack[-1].add(NestedInteger(num))
num = None
if char == "]":
top = stack.pop()
if stack:
stack[-1].add(top)
else:
result = top
i += 1
return result if result is not None else NestedInteger(num)
```
## Complexity
| Time | Space |
| ---------------------------------------------- | ------------------------------------------------------------------------- |
| O(n) - each character is consumed exactly once | O(d) - stack holds one NestedInteger per open bracket (d = nesting depth) |
## Tags
# Minimize Deviation in Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimize-deviation-in-array
Tested Python solution for LeetCode 1675 with 45 pytest cases. Generate a practice environment with lcpy.
LeetCode 1675, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/minimize-deviation-in-array/description/).
Generate this problem as a practice environment: tested reference solution, 45 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1675 # by problem number
lcpy gen -s minimize_deviation_in_array # by problem name
```
## Problem
You are given an array `nums` of `n` positive integers.
You can perform two types of operations on any element of the array any number of times:
* If the element is **even**, **divide** it by `2`. For example, if the array is `[1,2,3,4]`, then you can do this operation on the last element, and the array will be `[1,2,3,2]`.
* If the element is **odd**, **multiply** it by `2`. For example, if the array is `[1,2,3,4]`, then you can do this operation on the first element, and the array will be `[2,2,3,4]`.
The **deviation** of the array is the **maximum difference** between any two elements in the array.
Return *the **minimum deviation** the array can have after performing some number of operations*.
### Examples
```
Input: nums = [1,2,3,4]
Output: 1
Explanation: You can transform the array to [1,2,3,2], then to [2,2,3,2], then the deviation will be 3 - 2 = 1.
```
```
Input: nums = [4,1,5,20,3]
Output: 3
Explanation: You can transform the array after two operations to [4,2,5,5,3], then the deviation will be 5 - 2 = 3.
```
```
Input: nums = [2,10,8]
Output: 3
```
### Constraints
* n == nums.length
* 2 \<= n \<= 5 \* 10^4
* 1 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_deviation_in_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_deviation_in_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n * log(max(nums)) * log n)
# Space: O(n)
def minimum_deviation(self, nums: list[int]) -> int:
# Raise every element to its largest reachable form (an odd x can only
# grow once, to 2x); then repeatedly shrink the current max while it is
# even, tracking the tightest window seen.
heap: list[int] = []
low = 1 << 62
for num in nums:
value = num * 2 if num % 2 else num
heapq.heappush(heap, -value)
low = min(low, value)
best = 1 << 62
while True:
high = -heapq.heappop(heap)
best = min(best, high - low)
if high % 2:
break
half = high // 2
low = min(low, half)
heapq.heappush(heap, -half)
return best
```
## Complexity
| Time | Space |
| ------------------------------- | ----- |
| O(n \* log(max(nums)) \* log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimize Malware Spread Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimize-malware-spread
Tested Python solution for LeetCode 924 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 924, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find), [Graph](/catalog/topics/graph). [View on LeetCode](https://leetcode.com/problems/minimize-malware-spread/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 924 # by problem number
lcpy gen -s minimize_malware_spread # by problem name
```
## Problem
You are given a network of `n` nodes represented as an `n x n` adjacency matrix `graph`, where the `ith` node is directly connected to the `jth` node if `graph[i][j] == 1`.
Some nodes `initial` are initially infected by malware. Whenever two nodes are directly connected, and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner.
Suppose `M(initial)` is the final number of nodes infected with malware in the entire network after the spread of malware stops. We will remove **exactly one node** from `initial`.
Return the node that, if removed, would minimize `M(initial)`. If multiple nodes could be removed to minimize `M(initial)`, return such a node with **the smallest index**.
Note that if a node was removed from the `initial` list of infected nodes, it might still be infected later due to the malware spread.
### Examples
```
Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
Output: 0
```
**Explanation:** Removing node 0 leaves nodes 1 and 2 infected, so `M(1) = 2`. Removing node 1 leaves nodes 0 and 2 infected, so `M(0) = 2`. Both give the same `M`, so return the smaller index, 0.
```
Input: graph = [[1,0,0],[0,1,0],[0,0,1]], initial = [0,2]
Output: 0
```
**Explanation:** Removing node 0 leaves only node 2 infected, so `M(2) = 1`.
```
Input: graph = [[1,1,1],[1,1,1],[1,1,1]], initial = [1,2]
Output: 1
```
**Explanation:** Removing either node still leaves all 3 nodes infected, so the smallest index is returned.
### Constraints
* `n == graph.length`
* `n == graph[i].length`
* `2 <= n <= 300`
* `graph[i][j]` is `0` or `1`.
* `graph[i][j] == graph[j][i]`
* `graph[i][i] == 1`
* `1 <= initial.length <= n`
* `0 <= initial[i] <= n - 1`
* All the integers in `initial` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_malware_spread/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_malware_spread/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n^2 * alpha(n)) for the union pass plus O(len(initial)) for the scan
# Space: O(n)
def min_malware_spread(self, graph: list[list[int]], initial: list[int]) -> int:
n = len(graph)
parent = list(range(n))
def find(node: int) -> int:
while parent[node] != node:
parent[node] = parent[parent[node]]
node = parent[node]
return node
for i in range(n):
for j in range(i + 1, n):
if graph[i][j]:
root_i, root_j = find(i), find(j)
if root_i != root_j:
parent[root_i] = root_j
size = Counter(find(i) for i in range(n))
infected_in = Counter(find(x) for x in initial)
best_node = -1
best_saved = -1
for x in sorted(initial):
root = find(x)
saved = size[root] if infected_in[root] == 1 else 0
if saved > best_saved:
best_saved = saved
best_node = x
return best_node
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------------- | ----- |
| O(n^2 \* alpha(n)) for the union pass plus O(len(initial)) for the scan | O(n) |
## Tags
# Minimize Malware Spread II Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimize-malware-spread-ii
Tested Python solution for LeetCode 928 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 928, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find), [Graph](/catalog/topics/graph). [View on LeetCode](https://leetcode.com/problems/minimize-malware-spread-ii/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 928 # by problem number
lcpy gen -s minimize_malware_spread_ii # by problem name
```
## Problem
You are given a network of `n` nodes represented as an `n x n` adjacency matrix `graph`, where the `ith` node is directly connected to the `jth` node if `graph[i][j] == 1`.
Some nodes `initial` are initially infected by malware. Whenever two nodes are directly connected, and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner.
Suppose `M(initial)` is the final number of nodes infected with malware in the entire network after the spread of malware stops.
We will remove **exactly one node** from `initial`, **completely removing it and any connections from this node to any other node**.
Return the node that, if removed, would minimize `M(initial)`. If multiple nodes could be removed to minimize `M(initial)`, return such a node with **the smallest index**.
### Examples
```
Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
Output: 0
```
**Explanation:** Removing node 0 leaves only node 1 infected, `M(1) = 1`. Removing node 1 leaves only node 0 infected, `M(0) = 1`. Both give the same `M`, so return the smaller index, 0.
```
Input: graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1]
Output: 1
```
**Explanation:** Removing node 0 still lets the infection reach nodes 1 and 2, `M(2) = 2`. Removing node 1 leaves only node 0 infected, `M(0) = 1`, so return 1.
```
Input: graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1]
Output: 1
```
**Explanation:** Removing node 0 lets the infection spread through the chain to nodes 1, 2 and 3, `M(3) = 3`. Removing node 1 leaves only node 0 infected, `M(0) = 1`, so return 1.
### Constraints
* `n == graph.length`
* `n == graph[i].length`
* `2 <= n <= 300`
* `graph[i][j]` is `0` or `1`.
* `graph[i][j] == graph[j][i]`
* `graph[i][i] == 1`
* `1 <= initial.length < n`
* `0 <= initial[i] <= n - 1`
* All the integers in `initial` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_malware_spread_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_malware_spread_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2 * alpha(n))
# Space: O(n)
def min_malware_spread(self, graph: list[list[int]], initial: list[int]) -> int:
n = len(graph)
initial_set = set(initial)
clean = [node for node in range(n) if node not in initial_set]
parent: dict[int, int] = {node: node for node in clean}
def find(x: int) -> int:
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
for i in range(n):
for j in range(i + 1, n):
if graph[i][j] == 1 and i in parent and j in parent:
root_i, root_j = find(i), find(j)
if root_i != root_j:
parent[root_i] = root_j
size: dict[int, int] = {}
for node in clean:
root = find(node)
size[root] = size.get(root, 0) + 1
infecting: dict[int, set[int]] = {}
for node in clean:
for source in initial:
if graph[node][source] == 1:
infecting.setdefault(find(node), set()).add(source)
saved = dict.fromkeys(initial, 0)
for root, sources in infecting.items():
if len(sources) == 1:
saved[next(iter(sources))] += size[root]
best = initial[0]
for node in initial:
if saved[node] > saved[best] or (saved[node] == saved[best] and node < best):
best = node
return best
```
## Complexity
| Time | Space |
| ------------------ | ----- |
| O(n^2 \* alpha(n)) | O(n) |
## Tags
# Minimize Max Distance to Gas Station
Source: https://leetcode-py.wisl.dev/problems/minimize-max-distance-to-gas-station
Tested Python solution for LeetCode 774 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 774, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/minimize-max-distance-to-gas-station/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 774 # by problem number
lcpy gen -s minimize_max_distance_to_gas_station # by problem name
```
## Problem
You are given an integer array `stations` that represents the positions of the gas stations on the x-axis. You are also given an integer `k`.
You should add `k` new gas stations. You can add the stations anywhere on the x-axis, and not necessarily on an integer position.
Let `penalty()` be the **maximum** distance between adjacent gas stations after adding the `k` new stations.
Return the smallest possible value of `penalty()`. Answers within `10^-6` of the actual answer will be accepted.
### Examples
```
Input: stations = [1,2,3,4,5,6,7,8,9,10], k = 9
Output: 0.50000
```
```
Input: stations = [23,24,36,39,46,56,57,65,84,98], k = 1
Output: 14.00000
```
### Constraints
* 10 \<= stations.length \<= 2000
* 0 \<= stations\[i] \<= 10^8
* stations is sorted in a strictly increasing order.
* 1 \<= k \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_max_distance_to_gas_station/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_max_distance_to_gas_station/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log M) where M = max gap
# Space: O(1)
def minmax_gas_dist(self, stations: list[int], k: int) -> float:
gaps = [stations[i + 1] - stations[i] for i in range(len(stations) - 1)]
def check(x: float) -> bool:
return sum(int(g / x) for g in gaps) <= k
left, right = 0.0, float(max(gaps))
while right - left > 1e-6:
mid = (left + right) / 2
if check(mid):
right = mid
else:
left = mid
return left
```
## Complexity
| Time | Space |
| ---------------------------- | ----- |
| O(n log M) where M = max gap | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimize Maximum of Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimize-maximum-of-array
Tested Python solution for LeetCode 2439 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2439, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/minimize-maximum-of-array/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2439 # by problem number
lcpy gen -s minimize_maximum_of_array # by problem name
```
## Problem
You are given a 0-indexed array `nums` comprising of `n` non-negative integers.
In one operation, you must:
* Choose an integer `i` such that `1 <= i < n` and `nums[i] > 0`.
* Decrease `nums[i]` by 1.
* Increase `nums[i - 1]` by 1.
Return *the **minimum** possible value of the **maximum** integer of* `nums` *after performing **any** number of operations*.
### Examples
```
Input: nums = [3,7,1,6]
Output: 5
Explanation:
One set of optimal operations is as follows:
1. Choose i = 1, and nums becomes [4,6,1,6].
2. Choose i = 3, and nums becomes [4,6,2,5].
3. Choose i = 1, and nums becomes [5,5,2,5].
The maximum integer of nums is 5. It can be shown that the maximum number cannot be less than 5.
Therefore, we return 5.
```
```
Input: nums = [10,1]
Output: 10
Explanation:
It is optimal to leave nums as is, and since 10 is the maximum value, we return 10.
```
### Constraints
* n == nums.length
* 2 \<= n \<= 10^5
* 0 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_maximum_of_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_maximum_of_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def minimize_array_value(self, nums: list[int]) -> int:
# Operations never change a prefix sum, so every prefix must be levelable
# under the answer: prefix sum <= answer * prefix length. The answer is the
# largest such ceil(prefix_sum / length) over all prefixes.
ans = 0
prefix = 0
for i, num in enumerate(nums):
prefix += num
ans = max(ans, -(-prefix // (i + 1)))
return ans
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimize Rounding Error to Meet Target
Source: https://leetcode-py.wisl.dev/problems/minimize-rounding-error-to-meet-target
Tested Python solution for LeetCode 1058 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1058, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/minimize-rounding-error-to-meet-target/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1058 # by problem number
lcpy gen -s minimize_rounding_error_to_meet_target # by problem name
```
## Problem
Given an array of prices `[p1,p2...,pn]` and a `target`, round each price `pi` to `Roundi(pi)` so that the rounded array `[Round1(p1),Round2(p2)...,Roundn(pn)]` sums to the given `target`. Each operation `Roundi(pi)` could be either `Floor(pi)` or `Ceil(pi)`.
Return the string `"-1"` if the rounded array is impossible to sum to `target`. Otherwise, return the smallest rounding error, which is defined as `Σ |Roundi(pi) - (pi)|` for `i` from `1` to `n`, as a string with three places after the decimal.
### Examples
```
Input: prices = ["0.700","2.800","4.900"], target = 8
Output: "1.000"
Explanation: Use Floor, Ceil and Ceil operations to get (0.7 - 0) + (3 - 2.8) + (5 - 4.9) = 0.7 + 0.2 + 0.1 = 1.0.
```
```
Input: prices = ["1.500","2.500","3.500"], target = 10
Output: "-1"
Explanation: It is impossible to meet the target.
```
```
Input: prices = ["1.500","2.500","3.500"], target = 9
Output: "1.500"
```
### Constraints
* 1 \<= prices.length \<= 500
* Each string prices\[i] represents a real number in the range \[0.0, 1000.0] and has exactly 3 decimal places.
* 0 \<= target \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_rounding_error_to_meet_target/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_rounding_error_to_meet_target/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from decimal import Decimal
class Solution:
# Time: O(n log n)
# Space: O(n)
def minimize_error(self, prices: list[str], target: int) -> str:
floor_sum = 0
fracs: list[Decimal] = []
for p in prices:
d = Decimal(p)
floor_sum += int(d)
if frac := d - int(d):
fracs.append(frac)
if not floor_sum <= target <= floor_sum + len(fracs):
return "-1"
ceils = target - floor_sum
fracs.sort(reverse=True)
error = ceils - sum(fracs[:ceils]) + sum(fracs[ceils:])
return f"{error:.3f}"
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
# Minimize the Maximum Difference of Pairs
Source: https://leetcode-py.wisl.dev/problems/minimize-the-maximum-difference-of-pairs
Tested Python solution for LeetCode 2616 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2616, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/minimize-the-maximum-difference-of-pairs/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2616 # by problem number
lcpy gen -s minimize_the_maximum_difference_of_pairs # by problem name
```
## Problem
You are given a **0-indexed** integer array `nums` and an integer `p`. Find `p` pairs of indices of `nums` such that the **maximum** difference amongst all the pairs is **minimized**. Also, ensure no index appears more than once amongst the `p` pairs.
Note that for a pair of elements at the index `i` and `j`, the difference of this pair is `|nums[i] - nums[j]|`, where `|x|` represents the **absolute** **value** of `x`.
Return *the **minimum** **maximum** difference among all* `p` *pairs.* We define the maximum of an empty set to be zero.
### Examples
```
Input: nums = [10,1,2,7,1,3], p = 2
Output: 1
Explanation: The first pair is formed from the indices 1 and 4, and the second pair is formed from the indices 2 and 5.
The maximum difference is max(|nums[1] - nums[4]|, |nums[2] - nums[5]|) = max(0, 1) = 1. Therefore, we return 1.
```
```
Input: nums = [4,2,1,2], p = 1
Output: 0
Explanation: Let the indices 1 and 3 form a pair. The difference of that pair is |2 - 2| = 0, which is the minimum we can attain.
```
### Constraints
* 1 \<= nums.length \<= 10^5
* 0 \<= nums\[i] \<= 10^9
* 0 \<= p \<= nums.length / 2
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_the_maximum_difference_of_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_the_maximum_difference_of_pairs/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n + n log m) where m = max(nums) - min(nums)
# Space: O(n) for the sorted copy
def minimize_max(self, nums: list[int], p: int) -> int:
vals = sorted(nums)
n = len(vals)
def can_pair(target: int) -> bool:
count = 0
i = 0
while i < n - 1:
if vals[i + 1] - vals[i] <= target:
count += 1
i += 2
else:
i += 1
return count >= p
low, high = 0, vals[-1] - vals[0]
while low < high:
mid = (low + high) // 2
if can_pair(mid):
high = mid
else:
low = mid + 1
return low
```
## Complexity
| Time | Space |
| ---------------------------------------------------- | ------------------------ |
| O(n log n + n log m) where m = max(nums) - min(nums) | O(n) for the sorted copy |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimize XOR Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/minimize-xor
Tested Python solution for LeetCode 2429 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2429, [Medium](/catalog/medium). Topics: [Greedy](/catalog/topics/greedy), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/minimize-xor/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2429 # by problem number
lcpy gen -s minimize_xor # by problem name
```
## Problem
Given two positive integers `num1` and `num2`, find the positive integer `x` such that:
* `x` has the same number of set bits as `num2`, and
* The value `x XOR num1` is **minimal**.
Note that XOR is the bitwise XOR operation.
Return the integer `x`. The test cases are generated such that `x` is uniquely determined.
The number of set bits of an integer is the number of `1`'s in its binary representation.
### Examples
```
Input: num1 = 3, num2 = 5
Output: 3
Explanation:
The binary representations of num1 and num2 are 0011 and 0101, respectively.
The integer 3 has the same number of set bits as num2, and the value 3 XOR 3 = 0 is minimal.
```
```
Input: num1 = 1, num2 = 12
Output: 3
Explanation:
The binary representations of num1 and num2 are 0001 and 1100, respectively.
The integer 3 has the same number of set bits as num2, and the value 3 XOR 1 = 2 is minimal.
```
### Constraints
* 1 \<= num1, num2 \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_xor/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimize_xor/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log(max(num1, num2)))
# Space: O(1)
def minimize_xor(self, num1: int, num2: int) -> int:
target_bits = bin(num2).count("1")
x = num1
cur_bits = bin(x).count("1")
# Drop the lowest set bits while we have too many.
while cur_bits > target_bits:
x &= x - 1
cur_bits -= 1
# Otherwise take the lowest clear bits.
bit = 1
while cur_bits < target_bits:
if not x & bit:
x |= bit
cur_bits += 1
bit <<= 1
return x
```
## Complexity
| Time | Space |
| ----------------------- | ----- |
| O(log(max(num1, num2))) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimized Maximum of Products Distributed to
Source: https://leetcode-py.wisl.dev/problems/minimized-maximum-of-products-distributed-to-any-store
Tested Python solution for LeetCode 2064 with 39 pytest cases. Generate a practice environment with lcpy.
LeetCode 2064, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/minimized-maximum-of-products-distributed-to-any-store/description/).
Generate this problem as a practice environment: tested reference solution, 39 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2064 # by problem number
lcpy gen -s minimized_maximum_of_products_distributed_to_any_store # by problem name
```
## Problem
You are given an integer `n` indicating there are `n` specialty retail stores. There are `m` product types of varying amounts, which are given as a **0-indexed** integer array `quantities`, where `quantities[i]` represents the number of products of the `ith` product type.
You need to distribute **all products** to the retail stores following these rules:
* A store can only be given **at most one product type** but can be given **any** amount of it.
* After distribution, each store will have been given some number of products (possibly `0`). Let `x` represent the maximum number of products given to any store. You want `x` to be as small as possible, i.e., you want to **minimize** the **maximum** number of products that are given to any store.
Return *the minimum possible* `x`.
### Examples
```
Input: n = 6, quantities = [11,6]
Output: 3
Explanation: One optimal way is:
- The 11 products of type 0 are distributed to the first four stores in these amounts: 2, 3, 3, 3
- The 6 products of type 1 are distributed to the other two stores in these amounts: 3, 3
The maximum number of products given to any store is max(2, 3, 3, 3, 3, 3) = 3.
```
```
Input: n = 7, quantities = [15,10,10]
Output: 5
Explanation: One optimal way is:
- The 15 products of type 0 are distributed to the first three stores in these amounts: 5, 5, 5
- The 10 products of type 1 are distributed to the next two stores in these amounts: 5, 5
- The 10 products of type 2 are distributed to the last two stores in these amounts: 5, 5
The maximum number of products given to any store is max(5, 5, 5, 5, 5, 5, 5) = 5.
```
```
Input: n = 1, quantities = [100000]
Output: 100000
Explanation: The only optimal way is:
- The 100000 products of type 0 are distributed to the only store.
The maximum number of products given to any store is max(100000) = 100000.
```
### Constraints
* m == quantities.length
* 1 \<= m \<= n \<= 10^5
* 1 \<= quantities\[i] \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimized_maximum_of_products_distributed_to_any_store/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimized_maximum_of_products_distributed_to_any_store/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * log(max(quantities)))
# Space: O(1)
def minimized_maximum(self, n: int, quantities: list[int]) -> int:
lo, hi = 1, max(quantities)
while lo < hi:
mid = (lo + hi) // 2
if sum(-(-q // mid) for q in quantities) <= n:
hi = mid
else:
lo = mid + 1
return lo
```
## Complexity
| Time | Space |
| ---------------------------- | ----- |
| O(m \* log(max(quantities))) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Absolute Difference in BST
Source: https://leetcode-py.wisl.dev/problems/minimum-absolute-difference-in-bst
Tested Python solution for LeetCode 530 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 530, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/minimum-absolute-difference-in-bst/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 530 # by problem number
lcpy gen -s minimum_absolute_difference_in_bst # by problem name
```
## Problem
Given the `root` of a Binary Search Tree (BST), return *the minimum absolute difference between the values of any two different nodes in the tree*.
### Examples

```
Input: root = [4,2,6,1,3]
Output: 1
```

```
Input: root = [1,0,48,null,null,12,49]
Output: 1
```
### Constraints
* The number of nodes in the tree is in the range \[2, 10^4].
* 0 \<= Node.val \<= 10^5
**Note:** This question is the same as 783: Minimum Distance Between BST Nodes.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_absolute_difference_in_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_absolute_difference_in_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def get_minimum_difference(self, root: TreeNode[int]) -> int:
prev: int | None = None
best = 10**5
node: TreeNode[int] | None = root
stack: list[TreeNode[int]] = []
while stack or node is not None:
while node is not None:
stack.append(node)
node = node.left
node = stack.pop()
if prev is not None:
best = min(best, node.val - prev)
prev = node.val
node = node.right
return best
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
# Minimum Add to Make Parentheses Valid
Source: https://leetcode-py.wisl.dev/problems/minimum-add-to-make-parentheses-valid
Tested Python solution for LeetCode 921 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 921, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 921 # by problem number
lcpy gen -s minimum_add_to_make_parentheses_valid # by problem name
```
## Problem
\A parentheses string is valid if and only if:\
\AB\ (\A\ concatenated with \B\), where \A\ and \B\ are valid strings, or\(A)\, where \A\ is a valid string.\You are given a parentheses string \s\. In one move, you can insert a parenthesis at any position of the string.\
s = "()))"\, you can insert an opening parenthesis to be \"(()))"\ or a closing parenthesis to be \"())))"\.\Return \the minimum number of moves required to make \\s\\ valid\.\
m x n\ grid. Each cell of the grid has a sign pointing to the next cell you should visit if you are currently in this cell. The sign of \grid\[i]\[j]\ can be:
\1\ which means go to the cell to the right. (i.e go from \grid\[i]\[j]\ to \grid\[i]\[j + 1]\)\2\ which means go to the cell to the left. (i.e go from \grid\[i]\[j]\ to \grid\[i]\[j - 1]\)\3\ which means go to the lower cell. (i.e go from \grid\[i]\[j]\ to \grid\[i + 1]\[j]\)\4\ which means go to the upper cell. (i.e go from \grid\[i]\[j]\ to \grid\[i - 1]\[j]\)\(0, 0)\. A valid path in the grid is a path that starts from the upper left cell \(0, 0)\ and ends at the bottom-right cell \(m - 1, n - 1)\ following the signs on the grid. The valid path does not have to be the shortest.
You can modify the sign on a cell with \cost = 1\. You can modify the sign on a cell \one time only\.
Return the \minimum cost to make the grid have at least one \valid path\\.
### Examples

```
Input: grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
Output: 3
Explanation: You will start at point (0, 0).
The path to (3, 3) is as follows. (0, 0) --> (0, 1) --> (0, 2) --> (0, 3) change the arrow to down with cost = 1 --> (1, 3) --> (1, 2) --> (1, 1) --> (1, 0) change the arrow to down with cost = 1 --> (2, 0) --> (2, 1) --> (2, 2) --> (2, 3) change the arrow to down with cost = 1 --> (3, 3)
The total cost = 3.
```

```
Input: grid = [[1,1,3],[3,2,2],[1,1,4]]
Output: 0
Explanation: You can follow the path from (0, 0) to (2, 2).
```

```
Input: grid = [[1,2],[4,3]]
Output: 1
```
### Constraints
* m == grid.length
* n == grid\[i].length
* 1 \<= m, n \<= 100
* 1 \<= grid\[i]\[j] \<= 4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_cost_to_make_at_least_one_valid_path_in_a_grid/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_cost_to_make_at_least_one_valid_path_in_a_grid/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def min_cost(self, grid: list[list[int]]) -> int:
# 0-1 BFS: follow the cell's own sign with cost 0, any other
# direction with cost 1.
dirs = {1: (0, 1), 2: (0, -1), 3: (1, 0), 4: (-1, 0)}
m, n = len(grid), len(grid[0])
inf_cost = 10**9
dist = [[inf_cost] * n for _ in range(m)]
dist[0][0] = 0
dq: deque[tuple[int, int, int]] = deque([(0, 0, 0)])
while dq:
d, i, j = dq.popleft()
if d > dist[i][j]:
continue
for s, (di, dj) in dirs.items():
ni, nj = i + di, j + dj
if 0 <= ni < m and 0 <= nj < n:
nd = d if grid[i][j] == s else d + 1
if nd < dist[ni][nj]:
dist[ni][nj] = nd
if nd == d:
dq.appendleft((nd, ni, nj))
else:
dq.append((nd, ni, nj))
return dist[m - 1][n - 1]
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Cost to Merge Stones Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimum-cost-to-merge-stones
Tested Python solution for LeetCode 1000 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1000, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/minimum-cost-to-merge-stones/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1000 # by problem number
lcpy gen -s minimum_cost_to_merge_stones # by problem name
```
## Problem
There are `n` piles of stones arranged in a row. The `i^th` pile has `stones[i]` stones.
A move consists of merging exactly `k` **consecutive** piles into one pile, and the cost of this move is equal to the total number of stones in these `k` piles.
Return the minimum cost to merge all piles of stones into one pile. If it is impossible, return `-1`.
### Examples
```
Input: stones = [3,2,4,1], k = 2
Output: 20
```
**Explanation:** We start with \[3, 2, 4, 1].
We merge \[3, 2] for a cost of 5, and we are left with \[5, 4, 1].
We merge \[4, 1] for a cost of 5, and we are left with \[5, 5].
We merge \[5, 5] for a cost of 10, and we are left with \[10].
The total cost was 20, and this is the minimum possible.
```
Input: stones = [3,2,4,1], k = 3
Output: -1
```
**Explanation:** After any merge operation, there are 2 piles left, and we can't merge anymore. So the task is impossible.
```
Input: stones = [3,5,1,2,6], k = 3
Output: 25
```
**Explanation:** We start with \[3, 5, 1, 2, 6].
We merge \[5, 1, 2] for a cost of 8, and we are left with \[3, 8, 6].
We merge \[3, 8, 6] for a cost of 17, and we are left with \[17].
The total cost was 25, and this is the minimum possible.
### Constraints
* `n == stones.length`
* `1 <= n <= 30`
* `1 <= stones[i] <= 100`
* `2 <= k <= 30`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_cost_to_merge_stones/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_cost_to_merge_stones/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^3 / k * k) = O(n^3) over intervals with k-step splits
# Space: O(n^2)
def merge_stones(self, stones: list[int], k: int) -> int:
n = len(stones)
if n == 1:
return 0
if (n - 1) % (k - 1) != 0:
return -1
prefix = [0] * (n + 1)
for i, stones_count in enumerate(stones):
prefix[i + 1] = prefix[i] + stones_count
# dp[i][j] = min cost to merge stones[i..j] down to the minimum possible pile count
dp = [[0] * n for _ in range(n)]
for length in range(k, n + 1):
for i in range(n - length + 1):
j = i + length - 1
dp[i][j] = min(dp[i][mid] + dp[mid + 1][j] for mid in range(i, j, k - 1))
if (j - i) % (k - 1) == 0:
dp[i][j] += prefix[j + 1] - prefix[i]
return dp[0][n - 1]
```
## Complexity
| Time | Space |
| ---------------------------------------------------------- | ------ |
| O(n^3 / k \* k) = O(n^3) over intervals with k-step splits | O(n^2) |
## Tags
# Minimum Cost Walk in Weighted Graph
Source: https://leetcode-py.wisl.dev/problems/minimum-cost-walk-in-weighted-graph
Tested Python solution for LeetCode 3108 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 3108, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), [Union Find](/catalog/topics/union-find), [Graph](/catalog/topics/graph). [View on LeetCode](https://leetcode.com/problems/minimum-cost-walk-in-weighted-graph/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3108 # by problem number
lcpy gen -s minimum_cost_walk_in_weighted_graph # by problem name
```
## Problem
There is an undirected weighted graph with `n` vertices labeled from `0` to `n - 1`.
You are given the integer `n` and an array `edges`, where `edges[i] = [ui, vi, wi]` indicates that there is an edge between vertices `ui` and `vi` with a weight of `wi`.
A walk on a graph is a sequence of vertices and edges. The walk starts and ends with a vertex, and each edge connects the vertex that comes before it and the vertex that comes after it. It's important to note that a walk may visit the same edge or vertex more than once.
The **cost** of a walk starting at node `u` and ending at node `v` is defined as the bitwise `AND` of the weights of the edges traversed during the walk. In other words, if the sequence of edge weights encountered during the walk is `w0, w1, w2, ..., wk`, then the cost is calculated as `w0 & w1 & w2 & ... & wk`, where `&` denotes the bitwise `AND` operator.
You are also given a 2D array `query`, where `query[i] = [si, ti]`. For each query, you need to find the minimum cost of the walk starting at vertex `si` and ending at vertex `ti`. If there exists no such walk, the answer is `-1`.
Return *the array* `answer`*, where* `answer[i]` *denotes the **minimum** cost of a walk for query* `i`.
### Examples

```
Input: n = 5, edges = [[0,1,7],[1,3,7],[1,2,1]], query = [[0,3],[3,4]]
Output: [1,-1]
Explanation:
To achieve the cost of 1 in the first query, we need to move on the following edges: 0->1 (weight 7), 1->2 (weight 1), 2->1 (weight 1), 1->3 (weight 7).
In the second query, there is no walk between nodes 3 and 4, so the answer is -1.
```

```
Input: n = 3, edges = [[0,2,7],[0,1,15],[1,2,6],[1,2,1]], query = [[1,2]]
Output: [0]
Explanation:
To achieve the cost of 0 in the first query, we need to move on the following edges: 1->2 (weight 1), 2->1 (weight 6), 1->2 (weight 1).
```
### Constraints
* 2 \<= n \<= 10^5
* 0 \<= edges.length \<= 10^5
* edges\[i].length == 3
* 0 \<= ui, vi \<= n - 1
* ui != vi
* 0 \<= wi \<= 10^5
* 1 \<= query.length \<= 10^5
* query\[i].length == 2
* 0 \<= si, ti \<= n - 1
* si != ti
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_cost_walk_in_weighted_graph/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_cost_walk_in_weighted_graph/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
FULL_MASK = (1 << 17) - 1
class Solution:
# Time: O((len(edges) + len(query)) * alpha(n))
# Space: O(n)
def minimum_cost(self, n: int, edges: list[list[int]], query: list[list[int]]) -> list[int]:
# A walk may repeat edges, so within a connected component every edge can be
# traversed, and extra edges only clear bits. The minimum cost for two nodes
# in the same component is therefore the AND of all weights in it.
parent = list(range(n))
and_by_root = [FULL_MASK] * n
def find(node: int) -> int:
while parent[node] != node:
parent[node] = parent[parent[node]]
node = parent[node]
return node
for u, v, weight in edges:
ru, rv = find(u), find(v)
if ru == rv:
and_by_root[ru] &= weight
else:
parent[ru] = rv
and_by_root[rv] &= and_by_root[ru] & weight
result: list[int] = []
for start, end in query:
if start == end:
result.append(0)
continue
root = find(start)
result.append(and_by_root[root] if root == find(end) else -1)
return result
```
## Complexity
| Time | Space |
| ---------------------------------------- | ----- |
| O((len(edges) + len(query)) \* alpha(n)) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Deletions to Make Character
Source: https://leetcode-py.wisl.dev/problems/minimum-deletions-to-make-character-frequencies-unique
Tested Python solution for LeetCode 1647 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1647, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/minimum-deletions-to-make-character-frequencies-unique/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1647 # by problem number
lcpy gen -s minimum_deletions_to_make_character_frequencies_unique # by problem name
```
## Problem
A string `s` is called **good** if there are no two different characters in `s` that have the same **frequency**.
Given a string `s`, return the minimum number of characters you need to delete to make `s` **good**.
The **frequency** of a character in a string is the number of times it appears in the string. For example, in the string `"aab"`, the **frequency** of `'a'` is `2`, while the **frequency** of `'b'` is `1`.
### Examples
```
Input: s = "aab"
Output: 0
Explanation: s is already good.
```
```
Input: s = "aaabbbcc"
Output: 2
Explanation: You can delete two 'b's resulting in the good string "aaabcc".
Another way it to delete one 'b' and one 'c' resulting in the good string "aaabbc".
```
```
Input: s = "ceabaacb"
Output: 2
Explanation: You can delete both 'c's resulting in the good string "eabaab".
Note that we only care about characters that are still in the string at the end (i.e. frequency of 0 is ignored).
```
### Constraints
* 1 \<= s.length \<= 10^5
* s contains only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_deletions_to_make_character_frequencies_unique/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_deletions_to_make_character_frequencies_unique/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n + k^2) where k = 26 distinct characters
# Space: O(k)
def min_deletions(self, s: str) -> int:
used: set[int] = set()
deletions = 0
for freq in sorted(Counter(s).values(), reverse=True):
while freq > 0 and freq in used:
freq -= 1
deletions += 1
if freq > 0:
used.add(freq)
return deletions
```
## Complexity
| Time | Space |
| ------------------------------------------- | ----- |
| O(n + k^2) where k = 26 distinct characters | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Deletions to Make String Balanced
Source: https://leetcode-py.wisl.dev/problems/minimum-deletions-to-make-string-balanced
Tested Python solution for LeetCode 1653 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 1653, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/minimum-deletions-to-make-string-balanced/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1653 # by problem number
lcpy gen -s minimum_deletions_to_make_string_balanced # by problem name
```
## Problem
You are given a string `s` consisting only of characters `'a'` and `'b'`.
You can delete any number of characters in `s` to make `s` **balanced**. `s` is **balanced** if there is no pair of indices `(i,j)` such that `i < j` and `s[i] = 'b'` and `s[j] = 'a'`.
Return the minimum number of deletions needed to make `s` balanced.
### Examples
```
Input: s = "aababbab"
Output: 2
Explanation: You can either:
Delete the characters at 0-indexed positions 2 and 6 ("aababbab" -> "aaabbb"), or
Delete the characters at 0-indexed positions 3 and 6 ("aababbab" -> "aabbbb").
```
```
Input: s = "bbaaaaabb"
Output: 2
Explanation: The only solution is to delete the first two characters.
```
### Constraints
* 1 \<= s.length \<= 10^5
* s\[i] is 'a' or 'b'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_deletions_to_make_string_balanced/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_deletions_to_make_string_balanced/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def minimum_deletions(self, s: str) -> int:
deletions = 0
b_count = 0
for char in s:
if char == "b":
b_count += 1
else:
deletions = min(deletions + 1, b_count)
return deletions
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Depth of Binary Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimum-depth-of-binary-tree
Tested Python solution for LeetCode 111 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 111, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/minimum-depth-of-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 111 # by problem number
lcpy gen -s minimum_depth_of_binary_tree # by problem name
```
## Problem
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
**Note:** A leaf is a node with no children.
### Examples

```
Input: root = [3,9,20,null,null,15,7]
Output: 2
```
```
Input: root = [2,null,3,null,4,null,5,null,6]
Output: 5
```
### Constraints
* The number of nodes in the tree is in the range `[0, 10^5]`.
* `-1000 <= Node.val <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_depth_of_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_depth_of_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(w) where w is the maximum width of the tree
def min_depth(self, root: TreeNode[int] | None) -> int:
if root is None:
return 0
queue: deque[TreeNode[int]] = deque([root])
depth = 1
while queue:
for _ in range(len(queue)):
node = queue.popleft()
if node.left is None and node.right is None:
return depth
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
depth += 1
return depth
```
## Complexity
| Time | Space |
| ---- | --------------------------------------------- |
| O(n) | O(w) where w is the maximum width of the tree |
## Tags
# Minimum Difference Between Highest and Lowest
Source: https://leetcode-py.wisl.dev/problems/minimum-difference-between-highest-and-lowest-of-k-scores
Tested Python solution for LeetCode 1984 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1984, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/minimum-difference-between-highest-and-lowest-of-k-scores/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1984 # by problem number
lcpy gen -s minimum_difference_between_highest_and_lowest_of_k_scores # by problem name
```
## Problem
\You are given a \0-indexed\ integer array \nums\, where \nums\[i]\ represents the score of the \i\th\\ student. You are also given an integer \k\.\
Pick the scores of any \k\ students from the array so that the \difference\ between the \highest\ and the \lowest\ of the \k\ scores is \minimized\.\
Return \the \minimum\ possible difference\.\
### Examples ``` Input: nums = [90], k = 1 Output: 0 Explanation: There is one way to pick score(s) of one student: - [90]. The difference between the highest and lowest score is 90 - 90 = 0. The minimum possible difference is 0. ``` ``` Input: nums = [9,4,1,7], k = 2 Output: 2 Explanation: There are six ways to pick score(s) of two students: - [9,4,1,7]. The difference between the highest and lowest score is 9 - 4 = 5. - [9,4,1,7]. The difference between the highest and lowest score is 9 - 1 = 8. - [9,4,1,7]. The difference between the highest and lowest score is 9 - 7 = 2. - [9,4,1,7]. The difference between the highest and lowest score is 4 - 1 = 3. - [9,4,1,7]. The difference between the highest and lowest score is 7 - 4 = 3. - [9,4,1,7]. The difference between the highest and lowest score is 7 - 1 = 6. The minimum possible difference is 2. ``` ### Constraints * 1 \<= k \<= nums.length \<= 1000 * 0 \<= nums\[i] \<= 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_difference_between_highest_and_lowest_of_k_scores/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_difference_between_highest_and_lowest_of_k_scores/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) for the sort def minimum_difference(self, nums: list[int], k: int) -> int: scores = sorted(nums) return min(scores[i + k - 1] - scores[i] for i in range(len(scores) - k + 1)) ``` ## Complexity | Time | Space | | ---------- | ----------------- | | O(n log n) | O(n) for the sort | ## Tags [NeetCode All](/catalog/neetcode). # Minimum Difference Between Largest and Source: https://leetcode-py.wisl.dev/problems/minimum-difference-between-largest-and-smallest-value-in-three-moves Tested Python solution for LeetCode 1509 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 1509, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/minimum-difference-between-largest-and-smallest-value-in-three-moves/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1509 # by problem number lcpy gen -s minimum_difference_between_largest_and_smallest_value_in_three_moves # by problem name ``` ## Problem \You are given an integer array \nums\.\
In one move, you can choose one element of \nums\ and change it to \any value\.\
Return \the minimum difference between the largest and smallest value of \\nums\\ \after performing at most three moves\\.\
Given an \n x n\ array of integers \matrix\, return \the minimum sum of any \falling path\ through\ \matrix\.\
A \falling path\ starts at any element in the first row and chooses the element in the next row that is either directly below or diagonally left/right. Specifically, the next element from position \(row, col)\ will be \(row + 1, col - 1)\, \(row + 1, col)\, or \(row + 1, col + 1)\.\
```
Input: n = 4, edges = [[1,0],[1,2],[1,3]]
Output: [1]
Explanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.
```
\
```
Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
Output: [3,4]
```
### Constraints
* `1 <= n <= 2 * 10^4`
* `edges.length == n - 1`
* `0 <= ai, bi < n`
* `ai != bi`
* All the pairs `(ai, bi)` are distinct.
* The given input is **guaranteed** to be a tree and there will be **no repeated** edges.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_height_trees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_height_trees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict, deque
class Solution:
# Time: O(V)
# Space: O(V)
def find_min_height_trees(self, n: int, edges: list[list[int]]) -> list[int]:
if n == 1:
return [0]
graph = defaultdict(set)
for u, v in edges:
graph[u].add(v)
graph[v].add(u)
leaves = deque([i for i in range(n) if len(graph[i]) == 1])
remaining = n
while remaining > 2:
size = len(leaves)
remaining -= size
for _ in range(size):
leaf = leaves.popleft()
neighbor = graph[leaf].pop()
graph[neighbor].remove(leaf)
if len(graph[neighbor]) == 1:
leaves.append(neighbor)
return list(leaves)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(V) | O(V) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Minimum Increment to Make Array Unique
Source: https://leetcode-py.wisl.dev/problems/minimum-increment-to-make-array-unique
Tested Python solution for LeetCode 945 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 945, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/minimum-increment-to-make-array-unique/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 945 # by problem number
lcpy gen -s minimum_increment_to_make_array_unique # by problem name
```
## Problem
\You are given an integer array \nums\. In one move, you can pick an index \i\ where \0 \<= i \< nums.length\ and increment \nums\[i]\ by \1\.\
Return \the minimum number of moves to make every value in \\nums\\ \unique\\.\
The test cases are generated so that the answer fits in a 32-bit integer.\
### Examples ``` Input: nums = [1,2,2] Output: 1 Explanation: After 1 move, the array could be [1, 2, 3]. ``` ``` Input: nums = [3,2,1,2,1,7] Output: 6 Explanation: After 6 moves, the array could be [3, 4, 1, 2, 5, 7]. It can be shown that it is impossible for the array to have all unique values with 5 or less moves. ``` ### Constraints * 1 \<= nums.length \<= 10^5 * 0 \<= nums\[i] \<= 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_increment_to_make_array_unique/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_increment_to_make_array_unique/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) for the sorted copy def min_increment_for_unique(self, nums: list[int]) -> int: moves = 0 previous = -1 for num in sorted(nums): if num <= previous: # Raise num to one above the last placed value moves += previous - num + 1 previous += 1 else: previous = num return moves ``` ## Complexity | Time | Space | | ---------- | ------------------------ | | O(n log n) | O(n) for the sorted copy | ## Tags [NeetCode All](/catalog/neetcode). # Minimum Index of a Valid Split Python Solution Source: https://leetcode-py.wisl.dev/problems/minimum-index-of-a-valid-split Tested Python solution for LeetCode 2780 with 27 pytest cases. Generate a practice environment with lcpy. LeetCode 2780, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/minimum-index-of-a-valid-split/description/). Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2780 # by problem number lcpy gen -s minimum_index_of_a_valid_split # by problem name ``` ## Problem An element \x\ of an integer array \arr\ of length \m\ is \dominant\ if \more than half\ the elements of \arr\ have a value of \x\.\
\You are given a \0-indexed\ integer array \nums\ of length \n\ with one \dominant\ element.\
You can split \nums\ at an index \i\ into two arrays \nums\[0, ..., i]\ and \nums\[i + 1, ..., n - 1]\, but the split is only \valid\ if:\
0 \<= i \< n - 1\\nums\[0, ..., i]\, and \nums\[i + 1, ..., n - 1]\ have the same dominant element.\Here, \nums\[i, ..., j]\ denotes the subarray of \nums\ starting at index \i\ and ending at index \j\, both ends being inclusive. Particularly, if \j \< i\ then \nums\[i, ..., j]\ denotes an empty subarray.\
Return \the \minimum\ index of a \valid split\\. If no valid split exists, return \-1\.\
Given a string \s\ consisting only of characters \'a'\, \'b'\, and \'c'\. You are asked to apply the following algorithm on the string any number of times:\
s\ where all the characters in the prefix are equal.\s\ where all the characters in this suffix are equal.\Return \the \minimum length\ of \\s\ \after performing the above operation any number of times (possibly zero times)\.\
You are given a \0-indexed\ binary string \s\ having an even length.\
A string is \beautiful\ if it's possible to partition it into one or more substrings such that:\
\1\'s or \only\ \0\'s.\You can change any character in \s\ to \0\ or \1\.\
Return \the \minimum\ number of changes required to make the string \\s\ \beautiful\.\
target\. You have an integer array \initial\ of the same size as \target\ with all elements initially zeros.
In one operation you can choose \any\ subarray from \initial\ and increment each value by one.
Return \the minimum number of operations to form a \\target\\ array from \\initial\.
The test cases are generated so that the answer fits in a 32-bit integer.
### Examples
```
Input: target = [1,2,3,2,1]
Output: 3
Explanation: We need at least 3 operations to form the target array from the initial array.
[0,0,0,0,0] increment 1 from index 0 to 4 (inclusive).
[1,1,1,1,1] increment 1 from index 1 to 3 (inclusive).
[1,2,2,2,1] increment 1 at index 2.
[1,2,3,2,1] target array is formed.
```
```
Input: target = [3,1,1,2]
Output: 4
Explanation: [0,0,0,0] -> [1,1,1,1] -> [1,1,1,2] -> [2,1,1,2] -> [3,1,1,2]
```
```
Input: target = [3,1,5,4,2]
Output: 7
Explanation: [0,0,0,0,0] -> [1,1,1,1,1] -> [2,1,1,1,1] -> [3,1,1,1,1] -> [3,1,2,2,2] -> [3,1,3,3,2] -> [3,1,4,4,2] -> [3,1,5,4,2]
```
### Constraints
* 1 \<= target.length \<= 10^5
* 1 \<= target\[i] \<= 10^5
* The input is generated such that the answer fits inside a 32 bit integer.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_increments_on_subarrays_to_form_a_target_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_increments_on_subarrays_to_form_a_target_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def min_number_operations(self, target: list[int]) -> int:
operations = 0
prev = 0
for value in target:
if value > prev:
operations += value - prev
prev = value
return operations
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Number of K Consecutive Bit Flips
Source: https://leetcode-py.wisl.dev/problems/minimum-number-of-k-consecutive-bit-flips
Tested Python solution for LeetCode 995 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 995, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), [Queue](/catalog/topics/queue), [Sliding Window](/catalog/topics/sliding-window), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/minimum-number-of-k-consecutive-bit-flips/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 995 # by problem number
lcpy gen -s minimum_number_of_k_consecutive_bit_flips # by problem name
```
## Problem
You are given a binary array `nums` and an integer `k`.
A **k-bit flip** is choosing a **subarray** of length `k` from `nums` and **simultaneously** changing every `0` in the subarray to `1`, and every `1` in the subarray to `0`.
Return *the minimum number of `k-bit` flips required so that there is no `0` in the array.* If it is not possible, return `-1`.
A subarray is a **contiguous** part of an array.
### Examples
```
Input: nums = [0,1,0], k = 1
Output: 2
Explanation: Flip nums[0], then flip nums[2].
```
```
Input: nums = [1,1,0], k = 2
Output: -1
Explanation: No matter how we flip subarrays of size 2, we cannot make the array become [1,1,1].
```
```
Input: nums = [0,0,0,1,0,1,1,0], k = 3
Output: 3
Explanation:
Flip nums[0],nums[1],nums[2]: nums becomes [1,1,1,1,0,1,1,0]
Flip nums[4],nums[5],nums[6]: nums becomes [1,1,1,1,1,0,0,0]
Flip nums[5],nums[6],nums[7]: nums becomes [1,1,1,1,1,1,1,1]
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= k <= nums.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_k_consecutive_bit_flips/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_k_consecutive_bit_flips/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def min_k_bit_flips(self, nums: list[int], k: int) -> int:
n = len(nums)
flip_ends: list[bool] = [False] * n
flipped = 0
flips = 0
for i, num in enumerate(nums):
if i >= k and flip_ends[i - k]:
flipped ^= 1
if (num ^ flipped) == 0:
if i + k > n:
return -1
flipped ^= 1
flip_ends[i] = True
flips += 1
return flips
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Number of Moves to Seat Everyone
Source: https://leetcode-py.wisl.dev/problems/minimum-number-of-moves-to-seat-everyone
Tested Python solution for LeetCode 2037 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2037, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), Counting Sort. [View on LeetCode](https://leetcode.com/problems/minimum-number-of-moves-to-seat-everyone/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2037 # by problem number
lcpy gen -s minimum_number_of_moves_to_seat_everyone # by problem name
```
## Problem
There are `n` availabe seats and `n` students standing in a room. You are given an array `seats` of length `n`, where `seats[i]` is the position of the `ith` seat. You are also given the array `students` of length `n`, where `students[j]` is the position of the `jth` student.
You may perform the following move any number of times:
* Increase or decrease the position of the `ith` student by `1` (i.e., moving the `ith` student from position `x` to `x + 1` or `x - 1`)
Return the minimum number of moves required to move each student to a seat such that no two students are in the same seat.
Note that there may be multiple seats or students in the same position at the beginning.
### Examples
```
Input: seats = [3,1,5], students = [2,7,4]
Output: 4
Explanation: The students are moved as follows:
- The first student is moved from position 2 to position 1 using 1 move.
- The second student is moved from position 7 to position 5 using 2 moves.
- The third student is moved from position 4 to position 3 using 1 move.
In total, 1 + 2 + 1 = 4 moves were used.
```
```
Input: seats = [4,1,5,9], students = [1,3,2,6]
Output: 7
Explanation: The students are moved as follows:
- The first student is not moved.
- The second student is moved from position 3 to position 4 using 1 move.
- The third student is moved from position 2 to position 5 using 3 moves.
- The fourth student is moved from position 6 to position 9 using 3 moves.
In total, 0 + 1 + 3 + 3 = 7 moves were used.
```
```
Input: seats = [2,2,6,6], students = [1,3,2,6]
Output: 4
Explanation: Note that there are two seats at position 2 and two seats at position 6.
The students are moved as follows:
- The first student is moved from position 1 to position 2 using 1 move.
- The second student is moved from position 3 to position 6 using 3 moves.
- The third student is not moved.
- The fourth student is not moved.
In total, 1 + 3 + 0 + 0 = 4 moves were used.
```
### Constraints
* n == seats.length == students.length
* 1 \<= n \<= 100
* 1 \<= seats\[i], students\[j] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_moves_to_seat_everyone/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_moves_to_seat_everyone/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n) for the sorted copies
def min_moves_to_seat(self, seats: list[int], students: list[int]) -> int:
return sum(
abs(seat - student)
for seat, student in zip(sorted(seats), sorted(students), strict=True)
)
```
## Complexity
| Time | Space |
| ---------- | -------------------------- |
| O(n log n) | O(n) for the sorted copies |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Number of Operations to Make (#2009)
Source: https://leetcode-py.wisl.dev/problems/minimum-number-of-operations-to-make-array-continuous
Tested Python solution for LeetCode 2009 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2009, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Binary Search](/catalog/topics/binary-search), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/minimum-number-of-operations-to-make-array-continuous/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2009 # by problem number
lcpy gen -s minimum_number_of_operations_to_make_array_continuous # by problem name
```
## Problem
You are given an integer array `nums`. In one operation, you can replace **any** element in `nums` with **any** integer.
`nums` is considered **continuous** if both of the following conditions are fulfilled:
* All elements in `nums` are **unique**.
* The difference between the **maximum** element and the **minimum** element in `nums` equals `nums.length - 1`.
For example, `nums = [4, 2, 5, 3]` is **continuous**, but `nums = [1, 2, 3, 5, 6]` is **not continuous**.
Return *the **minimum** number of operations to make* `nums` *continuous*.
### Examples
```
Input: nums = [4,2,5,3]
Output: 0
Explanation: nums is already continuous.
```
```
Input: nums = [1,2,3,5,6]
Output: 1
Explanation: One possible solution is to change the last element to 4.
The resulting array is [1,2,3,5,4], which is continuous.
```
```
Input: nums = [1,10,100,1000]
Output: 3
Explanation: One possible solution is to change the last three elements to 2, 3 and 4.
The resulting array is [1,2,3,4], which is continuous.
```
### Constraints
* 1 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_operations_to_make_array_continuous/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_number_of_operations_to_make_array_continuous/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def min_operations(self, nums: list[int]) -> int:
n = len(nums)
vals = sorted(set(nums))
best = 0
left = 0
for right in range(len(vals)):
while vals[right] - vals[left] > n - 1:
left += 1
best = max(best, right - left + 1)
return n - best
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Number of Operations to Make (#2870)
Source: https://leetcode-py.wisl.dev/problems/minimum-number-of-operations-to-make-array-empty
Tested Python solution for LeetCode 2870 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 2870, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Greedy](/catalog/topics/greedy), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/minimum-number-of-operations-to-make-array-empty/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2870 # by problem number
lcpy gen -s minimum_number_of_operations_to_make_array_empty # by problem name
```
## Problem
\You are given a \0-indexed\ array \nums\ consisting of positive integers.\
There are two types of operations that you can apply on the array \any\ number of times:\
\Return \the \minimum\ number of operations required to make the array empty, or \\-1\\ if it is not possible\.\
You have \n\ boxes. You are given a binary string \boxes\ of length \n\, where \boxes\[i]\ is \'0'\ if the \i\th\\ box is \empty\, and \'1'\ if it contains \one\ ball.\
In one operation, you can move \one\ ball from a box to an adjacent box. Box \i\ is adjacent to box \j\ if \abs(i - j) == 1\. Note that after doing so, there may be more than one ball in some boxes.\
Return an array \answer\ of size \n\, where \answer\[i]\ is the \minimum\ number of operations needed to move all the balls to the \i\th\\ box.\
Each \answer\[i]\ is calculated considering the \initial\ state of the boxes.\
ranks\ representing the \ranks\ of some mechanics. \ranks\[i]\ is the rank of the \i\th\\ mechanic. A mechanic with a rank \r\ can repair \n\ cars in \r \* n\2\\ minutes.
You are also given an integer \cars\ representing the total number of cars waiting in the garage to be repaired.
Return \the \minimum\ time taken to repair all the cars.\
\Note:\ All the mechanics can repair the cars simultaneously.
### Examples
```
Input: ranks = [4,2,3,1], cars = 10
Output: 16
Explanation:
- The first mechanic will repair two cars. The time required is 4 * 2 * 2 = 16 minutes.
- The second mechanic will repair two cars. The time required is 2 * 2 * 2 = 8 minutes.
- The third mechanic will repair two cars. The time required is 3 * 2 * 2 = 12 minutes.
- The fourth mechanic will repair four cars. The time required is 1 * 4 * 4 = 16 minutes.
It can be proved that the cars cannot be repaired in less than 16 minutes.
```
```
Input: ranks = [5,1,8], cars = 6
Output: 16
Explanation:
- The first mechanic will repair one car. The time required is 5 * 1 * 1 = 5 minutes.
- The second mechanic will repair four cars. The time required is 1 * 4 * 4 = 16 minutes.
- The third mechanic will repair one car. The time required is 8 * 1 * 1 = 8 minutes.
It can be proved that the cars cannot be repaired in less than 16 minutes.
```
### Constraints
* 1 \<= ranks.length \<= 10\5\
* 1 \<= ranks\[i] \<= 100
* 1 \<= cars \<= 10\6\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_time_to_repair_cars/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_time_to_repair_cars/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from math import isqrt
class Solution:
# Time: O(m * log(min(ranks) * cars^2)) where m = len(ranks)
# Space: O(1)
def repair_cars(self, ranks: list[int], cars: int) -> int:
lo, hi = 1, min(ranks) * cars * cars
while lo < hi:
mid = (lo + hi) // 2
if sum(isqrt(mid // r) for r in ranks) >= cars:
hi = mid
else:
lo = mid + 1
return lo
```
## Complexity
| Time | Space |
| ------------------------------------------------------ | ----- |
| O(m \* log(min(ranks) \* cars^2)) where m = len(ranks) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Time to Visit a Cell In a Grid
Source: https://leetcode-py.wisl.dev/problems/minimum-time-to-visit-a-cell-in-a-grid
Tested Python solution for LeetCode 2577 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 2577, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix), [Shortest Path](/catalog/topics/shortest-path). [View on LeetCode](https://leetcode.com/problems/minimum-time-to-visit-a-cell-in-a-grid/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2577 # by problem number
lcpy gen -s minimum_time_to_visit_a_cell_in_a_grid # by problem name
```
## Problem
You are given a `m x n` matrix `grid` consisting of non-negative integers where `grid[row][col]` represents the minimum time required to be able to visit the cell `(row, col)`, which means you can visit the cell `(row, col)` only when the time you visit it is greater than or equal to `grid[row][col]`.
You are standing in the top-left cell of the matrix in the `0th` second, and you must move to any adjacent cell in the four directions: **up**, **down**, **left**, and **right**. Each move you make takes `1` second.
Return the minimum time required in which you can visit the bottom-right cell of the matrix. If you cannot visit the bottom-right cell, then return `-1`.
### Examples

```
Input: grid = [[0,1,3,2],[5,1,2,5],[4,3,8,6]]
Output: 7
Explanation: One of the paths that we can take is the following:
- at t = 0, we are on the cell (0,0).
- at t = 1, we move to the cell (0,1). It is possible because grid[0][1] <= 1.
- at t = 2, we move to the cell (1,1). It is possible because grid[1][1] <= 2.
- at t = 3, we move to the cell (1,2). It is possible because grid[1][2] <= 3.
- at t = 4, we move to the cell (1,1). It is possible because grid[1][1] <= 4.
- at t = 5, we move to the cell (1,2). It is possible because grid[1][2] <= 5.
- at t = 6, we move to the cell (1,3). It is possible because grid[1][3] <= 6.
- at t = 7, we move to the cell (2,3). It is possible because grid[2][3] <= 7.
The final time is 7. It can be shown that it is the minimum time possible.
```

```
Input: grid = [[0,2,4],[3,2,1],[1,0,4]]
Output: -1
Explanation: There is no path from the top left to the bottom-right cell.
```
### Constraints
* m == grid.length
* n == grid\[i].length
* 2 \<= m, n \<= 1000
* 4 \<= m \* n \<= 10^5
* 0 \<= grid\[i]\[j] \<= 10^5
* grid\[0]\[0] == 0
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_time_to_visit_a_cell_in_a_grid/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_time_to_visit_a_cell_in_a_grid/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(m * n * log(m * n))
# Space: O(m * n)
def minimum_time(self, grid: list[list[int]]) -> int:
if grid[0][1] > 1 and grid[1][0] > 1:
return -1
rows, cols = len(grid), len(grid[0])
unvisited = 10**18
best = [[unvisited] * cols for _ in range(rows)]
best[0][0] = 0
heap: list[tuple[int, int, int]] = [(0, 0, 0)]
while heap:
time, row, col = heapq.heappop(heap)
if best[row][col] < time:
continue
if row == rows - 1 and col == cols - 1:
return time
for d_row, d_col in ((1, 0), (-1, 0), (0, 1), (0, -1)):
n_row, n_col = row + d_row, col + d_col
if not (0 <= n_row < rows and 0 <= n_col < cols):
continue
need = grid[n_row][n_col]
# Waiting means bouncing between two adjacent cells, which costs
# 2 seconds per bounce, so the arrival parity is preserved.
n_time = max(time + 1, need + ((need - time - 1) % 2))
if n_time < best[n_row][n_col]:
best[n_row][n_col] = n_time
heapq.heappush(heap, (n_time, n_row, n_col))
return -1
```
## Complexity
| Time | Space |
| ------------------------ | --------- |
| O(m \* n \* log(m \* n)) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Minimum Unique Word Abbreviation
Source: https://leetcode-py.wisl.dev/problems/minimum-unique-word-abbreviation
Tested Python solution for LeetCode 411 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 411, [Hard](/catalog/hard). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation), [Array](/catalog/topics/array), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/minimum-unique-word-abbreviation/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 411 # by problem number
lcpy gen -s minimum_unique_word_abbreviation # by problem name
```
## Problem
A string can be **abbreviated** by replacing any number of **non-adjacent** substrings with their lengths. For example, a string such as `"substitution"` could be abbreviated as (but not limited to):
* `"s10n"` (`"s ubstitutio n"`)
* `"sub4u4"` (`"sub stit u tion"`)
* `"12"` (`"substitution"`)
* `"su3i1u2on"` (`"su bst i t u ti on"`)
* `"substitution"` (no substrings replaced)
Note that `"s55n"` (`"s ubsti tutio n"`) is not a valid abbreviation of `"substitution"` because the replaced substrings are adjacent.
The **length** of an abbreviation is the number of letters that were not replaced plus the number of substrings that were replaced. For example, the abbreviation `"s10n"` has a length of `3` (`2` letters + `1` substring) and `"su3i1u2on"` has a length of `9` (`6` letters + `3` substrings).
Given a target string `target` and an array of strings `dictionary`, return *an **abbreviation** of* `target`\* with the **shortest possible length** such that it is **not an abbreviation** of **any** string in\* `dictionary`*. If there are multiple shortest abbreviations, return any of them*.
### Examples
```
Input: target = "apple", dictionary = ["blade"]
Output: "a4"
Explanation: The shortest abbreviation of "apple" is "5", but this is also an abbreviation of "blade".
The next shortest abbreviations are "a4" and "4e". "4e" is an abbreviation of blade while "a4" is not.
Hence, return "a4".
```
```
Input: target = "apple", dictionary = ["blade","plain","amber"]
Output: "1p3"
Explanation: "5" is an abbreviation of both "apple" but also every word in the dictionary.
"a4" is an abbreviation of "apple" but also "amber".
"4e" is an abbreviation of "apple" but also "blade".
"1p3", "2p2", and "3l1" are the next shortest abbreviations of "apple".
Since none of them are abbreviations of words in the dictionary, returning any of them is correct.
```
### Constraints
* `m == target.length`
* `n == dictionary.length`
* `1 <= m <= 21`
* `0 <= n <= 1000`
* `1 <= dictionary[i].length <= 100`
* `log_2(n) + m <= 21` if `n > 0`
* `target` and `dictionary[i]` consist of lowercase English letters.
* `dictionary` does not contain `target`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_unique_word_abbreviation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_unique_word_abbreviation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^m * n * m) — enumerate letter subsets, check against dictionary
# Space: O(m) for the abbreviation buffer
def min_abbreviation(self, target: str, dictionary: list[str]) -> str:
m = len(target)
words = [w for w in dictionary if len(w) == m]
def abbr_from_mask(mask: int) -> str:
parts: list[str] = []
run = 0
for i, ch in enumerate(target):
if mask >> i & 1:
if run:
parts.append(str(run))
run = 0
parts.append(ch)
else:
run += 1
if run:
parts.append(str(run))
return "".join(parts)
def matches(abbr: str, w: str) -> bool:
i = j = 0
while i < len(abbr) and j < len(w):
if abbr[i].isdigit():
if abbr[i] == "0":
return False
k = 0
while i < len(abbr) and abbr[i].isdigit():
k = k * 10 + int(abbr[i])
i += 1
j += k
else:
if w[j] != abbr[i]:
return False
i += 1
j += 1
return i == len(abbr) and j == len(w)
def conflicts(abbr: str) -> bool:
return any(matches(abbr, w) for w in words)
best_abbr = ""
best_len = m + 1
for mask in range(1 << m):
candidate = abbr_from_mask(mask)
candidate_len = sum(1 for c in candidate if c.isalpha()) + sum(
1 for c in candidate if c.isdigit()
)
if candidate_len >= best_len:
continue
if not conflicts(candidate):
best_abbr, best_len = candidate, candidate_len
return best_abbr
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------- | -------------------------------- |
| O(2^m \* n \* m) — enumerate letter subsets, check against dictionary | O(m) for the abbreviation buffer |
## Tags
# Minimum Window Subsequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimum-window-subsequence
Tested Python solution for LeetCode 727 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 727, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/minimum-window-subsequence/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 727 # by problem number
lcpy gen -s minimum_window_subsequence # by problem name
```
## Problem
Given strings `s1` and `s2`, return the minimum contiguous substring part of `s1`, so that `s2` is a subsequence of the part.
If there is no such window in `s1` that covers all characters in `s2`, return the empty string `""`. If there are multiple such minimum-length windows, return the one with the **left-most starting index**.
A subsequence of a string is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.
### Examples
```
Input: s1 = "abcdebdde", s2 = "bde"
Output: "bcde"
Explanation: "bcde" is the answer because it occurs before "bdde" which has the same length.
"deb" is not a smaller window because the elements of s2 in the window must occur in order.
```
```
Input: s1 = "jmeqksfrsdcmsiwvaovztaqenprpvnbstl", s2 = "u"
Output: ""
```
### Constraints
* 1 \<= s1.length \<= 2 \* 10^4
* 1 \<= s2.length \<= 100
* s1 and s2 consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_window_subsequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_window_subsequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(n)
def min_window(self, s1: str, s2: str) -> str:
m, n = len(s1), len(s2)
start, best = 0, m + 1
# dp[j] = smallest index i such that s1[:i] contains s2[:j] as a suffix subsequence
prev = [0] * (n + 1)
for i in range(1, m + 1):
cur = [0] * (n + 1)
for j in range(1, n + 1):
if s1[i - 1] == s2[j - 1]:
cur[j] = i if j == 1 else prev[j - 1]
else:
cur[j] = prev[j]
if cur[n] and i - cur[n] + 1 < best:
best = i - cur[n] + 1
start = cur[n] - 1
prev = cur
return "" if best > m else s1[start : start + best]
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(m \* n) | O(n) |
## Tags
# Minimum Window Substring Python Solution
Source: https://leetcode-py.wisl.dev/problems/minimum-window-substring
Tested Python solution for LeetCode 76 with 11 pytest cases. Generate a practice environment with lcpy.
LeetCode 76, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/minimum-window-substring/description/).
Generate this problem as a practice environment: tested reference solution, 11 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 76 # by problem number
lcpy gen -s minimum_window_substring # by problem name
```
## Problem
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 `""`.
The testcases will be generated such that the answer is unique.
### Examples
```
Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"
```
**Explanation:** The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
```
Input: s = "a", t = "a"
Output: "a"
```
**Explanation:** The entire string s is the minimum window.
```
Input: s = "a", t = "aa"
Output: ""
```
**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.
### Constraints
* `m == s.length`
* `n == t.length`
* `1 <= m, n <= 10^5`
* `s` and `t` consist of uppercase and lowercase English letters.
**Follow up:** Could you find an algorithm that runs in `O(m + n)` time?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_window_substring/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/minimum_window_substring/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Sliding Window
# Time: O(m + n) where m = len(s), n = len(t)
# Space: O(k) where k is unique chars in t
def min_window(self, s: str, t: str) -> str:
if not t or len(t) > len(s):
return ""
need = Counter(t)
left = 0
formed = 0
required = len(need)
window_counts: dict[str, int] = {}
# Result: (window length, left, right)
ans: tuple[float, int | None, int | None] = (float("inf"), None, None)
for right in range(len(s)):
char = s[right]
window_counts[char] = window_counts.get(char, 0) + 1
# Check if current char frequency matches desired frequency in t
if char in need and window_counts[char] == need[char]:
formed += 1
# Contract window until it's no longer valid
while left <= right and formed == required:
char = s[left]
# Update result if this window is smaller
if right - left + 1 < ans[0]:
ans = (right - left + 1, left, right)
# Remove from left
window_counts[char] -= 1
if char in need and window_counts[char] < need[char]:
formed -= 1
left += 1
if ans[0] == float("inf"):
return ""
assert ans[1] is not None and ans[2] is not None
return s[ans[1] : ans[2] + 1]
```
## Complexity
| Time | Space |
| ------------------------------------- | --------------------------------- |
| O(m + n) where m = len(s), n = len(t) | O(k) where k is unique chars in t |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Mirror Reflection Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/mirror-reflection
Tested Python solution for LeetCode 858 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 858, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry), [Number Theory](/catalog/topics/number-theory). [View on LeetCode](https://leetcode.com/problems/mirror-reflection/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 858 # by problem number
lcpy gen -s mirror_reflection # by problem name
```
## Problem
There is a special square room with mirrors on each of the four walls. Except for the southwest corner, there are receptors on each of the remaining corners, numbered `0`, `1`, and `2`.
The square room has walls of length `p` and a laser ray from the southwest corner first meets the east wall at a distance `q` from the 0^th receptor.
Given the two integers `p` and `q`, return the number of the receptor that the ray meets first.
The test cases are guaranteed so that the ray will meet a receptor eventually.
### Examples

```
Input: p = 2, q = 1
Output: 2
Explanation: The ray meets receptor 2 the first time it gets reflected back to the left wall.
```
```
Input: p = 3, q = 1
Output: 1
```
### Constraints
* `1 <= q <= p <= 1000`
**Follow up:** Could you solve it without simulating the reflections?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/mirror_reflection/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/mirror_reflection/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from math import gcd
class Solution:
# Time: O(log(min(p, q)))
# Space: O(1)
def mirror_reflection(self, p: int, q: int) -> int:
g = gcd(p, q)
heights, crossings = q // g, p // g
if heights % 2 == 0:
return 0
return 2 if crossings % 2 == 0 else 1
```
## Complexity
| Time | Space |
| ----------------- | ----- |
| O(log(min(p, q))) | O(1) |
## Tags
# Missing Element in Sorted Array
Source: https://leetcode-py.wisl.dev/problems/missing-element-in-sorted-array
Tested Python solution for LeetCode 1060 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1060, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/missing-element-in-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1060 # by problem number
lcpy gen -s missing_element_in_sorted_array # by problem name
```
## Problem
Given an integer array `nums` which is sorted in **ascending order** and all of its elements are **unique** and given also an integer `k`, return the `kth` missing number starting from the leftmost number of the array.
### Examples
```
Input: nums = [4,7,9,10], k = 1
Output: 5
Explanation: The first missing number is 5.
```
```
Input: nums = [4,7,9,10], k = 3
Output: 8
Explanation: The missing numbers are [5,6,8,...], hence the third missing number is 8.
```
```
Input: nums = [1,2,4], k = 3
Output: 6
Explanation: The missing numbers are [3,5,6,7,...], hence the third missing number is 6.
```
### Constraints
* 1 \<= nums.length \<= 5 \* 10^4
* 1 \<= nums\[i] \<= 10^7
* nums is sorted in ascending order, and all the elements are unique.
* 1 \<= k \<= 10^8
**Follow up:** Can you find a logarithmic time complexity (i.e., `O(log(n))`) solution?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_element_in_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_element_in_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def missing_element(self, nums: list[int], k: int) -> int:
def missing(i: int) -> int:
return nums[i] - nums[0] - i
n = len(nums)
if k > missing(n - 1):
return nums[n - 1] + k - missing(n - 1)
left, right = 0, n - 1
while left < right:
mid = (left + right) >> 1
if missing(mid) >= k:
right = mid
else:
left = mid + 1
return nums[left - 1] + k - missing(left - 1)
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Missing Number Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/missing-number
Tested Python solution for LeetCode 268 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 268, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/missing-number/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 268 # by problem number
lcpy gen -s missing_number # by problem name
```
## Problem
Given an array `nums` containing `n` distinct numbers in the range `[0, n]`, return *the only number in the range that is missing from the array.*
### Examples
```
Input: nums = [3,0,1]
Output: 2
```
**Explanation:**
`n = 3` since there are 3 numbers, so all numbers are in the range `[0,3]`. 2 is the missing number in the range since it does not appear in `nums`.
```
Input: nums = [0,1]
Output: 2
```
**Explanation:**
`n = 2` since there are 2 numbers, so all numbers are in the range `[0,2]`. 2 is the missing number in the range since it does not appear in `nums`.
```
Input: nums = [9,6,4,2,3,5,7,0,1]
Output: 8
```
**Explanation:**
`n = 9` since there are 9 numbers, so all numbers are in the range `[0,9]`. 8 is the missing number in the range since it does not appear in `nums`.
### Constraints
* n == nums.length
* 1 \<= n \<= 10^4
* 0 \<= nums\[i] \<= n
* All the numbers of nums are **unique**.
**Follow up:** Could you implement a solution using only `O(1)` extra space complexity and `O(n)` runtime complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def missing_number(self, nums: list[int]) -> int:
"""
Find the missing number in an array containing n distinct numbers
in the range [0, n].
Approach: Use the mathematical formula for sum of consecutive integers.
The sum of numbers from 0 to n is n*(n+1)/2.
The missing number = expected_sum - actual_sum.
"""
n = len(nums)
expected_sum = n * (n + 1) // 2
actual_sum = sum(nums)
return expected_sum - actual_sum
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Missing Number In Arithmetic Progression
Source: https://leetcode-py.wisl.dev/problems/missing-number-in-arithmetic-progression
Tested Python solution for LeetCode 1228 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1228, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/missing-number-in-arithmetic-progression/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1228 # by problem number
lcpy gen -s missing_number_in_arithmetic_progression # by problem name
```
## Problem
In some array `arr`, the values were in arithmetic progression: the values `arr[i + 1] - arr[i]` are all equal for every `0 <= i < arr.length - 1`.
A value from `arr` was removed that **was not the first or last value in the array**.
Given `arr`, return *the removed value*.
### Examples
```
Input: arr = [5,7,11,13]
Output: 9
Explanation: The previous array was [5,7,9,11,13].
```
```
Input: arr = [15,13,12]
Output: 14
Explanation: The previous array was [15,14,13,12].
```
### Constraints
* 3 \<= arr.length \<= 1000
* 0 \<= arr\[i] \<= 10^5
* The given array is **guaranteed** to be a valid array.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_number_in_arithmetic_progression/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_number_in_arithmetic_progression/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def missing_number(self, arr: list[int]) -> int:
return (arr[0] + arr[-1]) * (len(arr) + 1) // 2 - sum(arr)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Missing Ranges Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/missing-ranges
Tested Python solution for LeetCode 163 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 163, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/missing-ranges/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 163 # by problem number
lcpy gen -s missing_ranges # by problem name
```
## Problem
You are given an inclusive range `[lower, upper]` and a **sorted unique** integer array `nums`, where all elements are within the inclusive range.
A number `x` is considered **missing** if `x` is in the range `[lower, upper]` and `x` is not in `nums`.
Return the **shortest sorted** list of ranges that **exactly covers all the missing numbers**. That is, no element of `nums` is included in any of the ranges, and each missing number is covered by one of the ranges.
### Examples
```
Input: nums = [0,1,3,50,75], lower = 0, upper = 99
Output: [[2,2],[4,49],[51,74],[76,99]]
Explanation: The ranges are:
[2,2]
[4,49]
[51,74]
[76,99]
```
```
Input: nums = [-1], lower = -1, upper = -1
Output: []
Explanation: There are no missing ranges since there are no missing numbers.
```
### Constraints
* -10^9 \<= lower \<= upper \<= 10^9
* 0 \<= nums.length \<= 100
* lower \<= nums\[i] \<= upper
* All values of nums are unique
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_ranges/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/missing_ranges/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_missing_ranges(self, nums: list[int], lower: int, upper: int) -> list[list[int]]:
ranges: list[list[int]] = []
prev = lower - 1
for i in range(len(nums) + 1):
curr = nums[i] if i < len(nums) else upper + 1
if curr - prev >= 2:
ranges.append([prev + 1, curr - 1])
prev = curr
return ranges
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Monotone Increasing Digits Python Solution
Source: https://leetcode-py.wisl.dev/problems/monotone-increasing-digits
Tested Python solution for LeetCode 738 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 738, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/monotone-increasing-digits/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 738 # by problem number
lcpy gen -s monotone_increasing_digits # by problem name
```
## Problem
An integer has **monotone increasing digits** if and only if each pair of adjacent digits `x` and `y` satisfy `x <= y`.
Given an integer `n`, return the largest number that is less than or equal to `n` with monotone increasing digits.
### Examples
```
Input: n = 10
Output: 9
```
```
Input: n = 1234
Output: 1234
```
```
Input: n = 332
Output: 299
```
### Constraints
* `0 <= n <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/monotone_increasing_digits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/monotone_increasing_digits/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(d) where d is the number of digits in n
# Space: O(d)
def monotone_increasing_digits(self, n: int) -> int:
digits = list(str(n))
for i in range(len(digits) - 1):
if digits[i] > digits[i + 1]:
while i > 0 and digits[i - 1] == digits[i]:
i -= 1
digits[i] = str(int(digits[i]) - 1)
for j in range(i + 1, len(digits)):
digits[j] = "9"
break
return int("".join(digits))
```
## Complexity
| Time | Space |
| ----------------------------------------- | ----- |
| O(d) where d is the number of digits in n | O(d) |
## Tags
# Monotonic Array Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/monotonic-array
Tested Python solution for LeetCode 896 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 896, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/monotonic-array/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 896 # by problem number
lcpy gen -s monotonic_array # by problem name
```
## Problem
An array is \monotonic\ if it is either monotone increasing or monotone decreasing.\
\An array \nums\ is monotone increasing if for all \i \<= j\, \nums\[i] \<= nums\[j]\. An array \nums\ is monotone decreasing if for all \i \<= j\, \nums\[i] >= nums\[j]\.\
Given an integer array \nums\, return \true\ \if the given array is monotonic, or\ \false\ \otherwise\.\
0\'s to \1\'s and all the \1\'s to \0\'s in its binary representation.
\5\ is \"101"\ in binary and its \complement\ is \"010"\ which is the integer \2\.\Given an integer \num\, return \its complement\.\
n\ different songs. You want to listen to \goal\ songs (not necessarily different) during your trip. To avoid boredom, you will create a playlist so that:
\k\ other songs have been played.\Given \n\, \goal\, and \k\, return \the number of possible playlists that you can create\. Since the answer can be very large, return it \modulo\ \10\9\ + 7\.\
You are given a \0-indexed\ array of strings \details\. Each element of \details\ provides information about a given passenger compressed into a string of length \15\. The system is such that:\
Return \the number of passengers who are \strictly more than 60 years old\\.\
### Examples ``` Input: details = ["7868190130M7522","5303914400F9211","9273338290F4010"] Output: 2 Explanation: The passengers at indices 0, 1, and 2 have ages 75, 92, and 40. Thus, there are 2 people who are over 60 years old. ``` ``` Input: details = ["1313579440F2036","2921522980M5644"] Output: 0 Explanation: None of the passengers are older than 60. ``` ### Constraints * `1 <= details.length <= 100` * `details[i].length == 15` * `details[i]` consists of digits from `'0'` to `'9'`. * `details[i][10]` is either `'M'`, `'F'`, or `'O'`. * The phone numbers and seat numbers of the passengers are distinct. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_senior_citizens/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_senior_citizens/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def count_seniors(self, details: list[str]) -> int: return sum(int(detail[11:13]) > 60 for detail in details) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Number of Ships in a Rectangle Python Solution Source: https://leetcode-py.wisl.dev/problems/number-of-ships-in-a-rectangle Tested Python solution for LeetCode 1274 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 1274, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/number-of-ships-in-a-rectangle/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1274 # by problem number lcpy gen -s number_of_ships_in_a_rectangle # by problem name ``` ## Problem (This problem is an **interactive problem**.) Each ship is located at an integer point on the sea represented by a cartesian plane, and each integer point may contain at most 1 ship. You have a function `Sea.has_ships(top_right, bottom_left)` which takes two points as arguments and returns `true` if there is at least one ship in the rectangle represented by the two points, including on the boundary. Given two points: the top right and bottom left corners of a rectangle, return the number of ships present in that rectangle. It is guaranteed that there are **at most 10 ships** in that rectangle. Submissions making **more than 400 calls** to `has_ships` will be judged **Wrong Answer**. Also, any solutions that attempt to circumvent the judge will be disqualified. The API is: ``` class Sea: def has_ships(self, top_right: 'Point', bottom_left: 'Point') -> bool: ... class Point: def __init__(self, x: int, y: int) -> None: self.x = x self.y = y ``` ### Examples  ``` Input: ships = [[1,1],[2,2],[3,3],[5,5]], topRight = [4,4], bottomLeft = [0,0] Output: 3 Explanation: From [0,0] to [4,4] we can count 3 ships within the range. ``` ``` Input: ships = [[1,1],[2,2],[3,3]], topRight = [1000,1000], bottomLeft = [0,0] Output: 3 ``` ### Constraints * On the input `ships` is only given to initialize the map internally. You must solve this problem "blindfolded". In other words, you must find the answer using the given `has_ships` API, without knowing the `ships` position. * `0 <= bottomLeft[0] <= topRight[0] <= 1000` * `0 <= bottomLeft[1] <= topRight[1] <= 1000` * `topRight != bottomLeft` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ships_in_a_rectangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ships_in_a_rectangle/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Point: # Test-harness value type for a cartesian point on the sea def __init__(self, x: int, y: int) -> None: self.x = x self.y = y class Sea: # Test-harness API: backs the interactive has_ships query with the ships def __init__(self, ships: list[list[int]]) -> None: self.ships = {(x, y) for x, y in ships} self.calls = 0 def has_ships(self, top_right: Point, bottom_left: Point) -> bool: self.calls += 1 if self.calls > 400: msg = "has_ships exceeded the 400-call judge limit" raise RuntimeError(msg) return any( bottom_left.x <= x <= top_right.x and bottom_left.y <= y <= top_right.y for x, y in self.ships ) class Solution: # Time: O(C * log(max(m, n))) API calls, C = ships inside the rectangle # Space: O(log(max(m, n))) recursion def count_ships(self, sea: Sea, top_right: Point, bottom_left: Point) -> int: def dfs(tr: Point, bl: Point) -> int: x1, y1 = bl.x, bl.y x2, y2 = tr.x, tr.y if x1 > x2 or y1 > y2: return 0 if not sea.has_ships(tr, bl): return 0 if x1 == x2 and y1 == y2: return 1 midx = (x1 + x2) // 2 midy = (y1 + y2) // 2 return ( dfs(tr, Point(midx + 1, midy + 1)) + dfs(Point(midx, y2), Point(x1, midy + 1)) + dfs(Point(midx, midy), bl) + dfs(Point(x2, midy), Point(midx + 1, y1)) ) return dfs(top_right, bottom_left) ``` ## Complexity | Time | Space | | ---------------------------------------------------------------- | --------------------------- | | O(C \* log(max(m, n))) API calls, C = ships inside the rectangle | O(log(max(m, n))) recursion | ## Tags [NeetCode All](/catalog/neetcode). # Number of Squareful Arrays Python Solution Source: https://leetcode-py.wisl.dev/problems/number-of-squareful-arrays Tested Python solution for LeetCode 996 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 996, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/number-of-squareful-arrays/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 996 # by problem number lcpy gen -s number_of_squareful_arrays # by problem name ``` ## Problem An array is **squareful** if the sum of every pair of adjacent elements is a **perfect square**. Given an integer array `nums`, return *the number of permutations of* `nums` *that are* ***squareful***. Two permutations `perm1` and `perm2` are different if there is some index `i` such that `perm1[i] != perm2[i]`. ### Examples ``` Input: nums = [1,17,8] Output: 2 Explanation: [1,8,17] and [17,8,1] are the valid permutations. ``` ``` Input: nums = [2,2,2] Output: 1 ``` ### Constraints * 1 \<= nums.length \<= 12 * 0 \<= nums\[i] \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_squareful_arrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_squareful_arrays/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter from functools import cache from math import isqrt class Solution: # Time: O(k^2 * 2^n) where k is the number of distinct values (k <= n <= 12) # Space: O(k * 2^n) for the memo table over (last value, used-element mask) def num_squareful_perms(self, nums: list[int]) -> int: n = len(nums) counts = Counter(nums) values = sorted(counts) positions = { value: sum(1 << i for i, x in enumerate(nums) if x == value) for value in values } def is_square(x: int) -> bool: root = isqrt(x) return root * root == x neighbors = {value: [b for b in values if is_square(value + b)] for value in values} @cache def dfs(last: int, mask: int) -> int: if mask == (1 << n) - 1: return 1 total = 0 for neighbor in neighbors[last]: if (mask & positions[neighbor]).bit_count() == counts[neighbor]: continue free = positions[neighbor] & ~mask pick = (free & -free).bit_length() - 1 total += dfs(neighbor, mask | (1 << pick)) return total return sum(dfs(value, positions[value] & -positions[value]) for value in values) ``` ## Complexity | Time | Space | | ----------------------------------------------------------------------- | ------------------------------------------------------------------- | | O(k^2 \* 2^n) where k is the number of distinct values (k \<= n \<= 12) | O(k \* 2^n) for the memo table over (last value, used-element mask) | ## Tags # Number of Students Unable to Eat Lunch Source: https://leetcode-py.wisl.dev/problems/number-of-students-unable-to-eat-lunch Tested Python solution for LeetCode 1700 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 1700, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Queue](/catalog/topics/queue), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/number-of-students-unable-to-eat-lunch/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1700 # by problem number lcpy gen -s number_of_students_unable_to_eat_lunch # by problem name ``` ## Problem The school cafeteria offers circular and square sandwiches at lunch break, referred to by numbers `0` and `1` respectively. All students stand in a queue. Each student either prefers square or circular sandwiches. The number of sandwiches in the cafeteria is equal to the number of students. The sandwiches are placed in a **stack**. At each step: * If the student at the front of the queue **prefers** the sandwich on the top of the stack, they will **take it** and leave the queue. * Otherwise, they will **leave it** and go to the queue's end. This continues until none of the queue students want to take the top sandwich and are thus unable to eat. You are given two integer arrays `students` and `sandwiches` where `sandwiches[i]` is the type of the `i`th sandwich in the stack (`i = 0` is the top of the stack) and `students[j]` is the preference of the `j`th student in the initial queue (`j = 0` is the front of the queue). Return the number of students that are unable to eat. ### Examples ``` Input: students = [1,1,0,0], sandwiches = [0,1,0,1] Output: 0 ``` **Explanation:** Front students who want sandwich `1` move to the end of the queue until the stack exposes `1`, and every student eventually takes a sandwich. ``` Input: students = [1,1,1,0,0,1], sandwiches = [1,0,0,0,1,1] Output: 3 ``` ### Constraints * 1 \<= students.length, sandwiches.length \<= 100 * students.length == sandwiches.length * sandwiches\[i] is 0 or 1. * students\[i] is 0 or 1. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_students_unable_to_eat_lunch/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_students_unable_to_eat_lunch/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n + m) where n = len(students), m = len(sandwiches) # Space: O(1) - only two counters def count_students(self, students: list[int], sandwiches: list[int]) -> int: counts = [0, 0] for pref in students: counts[pref] += 1 for sandwich in sandwiches: if counts[sandwich] == 0: break counts[sandwich] -= 1 return counts[0] + counts[1] ``` ## Complexity | Time | Space | | ----------------------------------------------------- | ------------------------ | | O(n + m) where n = len(students), m = len(sandwiches) | O(1) - only two counters | ## Tags [NeetCode All](/catalog/neetcode). # Number of Sub-arrays of Size K and Average Source: https://leetcode-py.wisl.dev/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold Tested Python solution for LeetCode 1343 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 1343, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1343 # by problem number lcpy gen -s number_of_sub_arrays_of_size_k_and_average_greater_than_or_equal_to_threshold # by problem name ``` ## Problem Given an array of integers arr and two integers k and threshold, return the number of sub-arrays of size k and average greater than or equal to threshold. ### Examples ``` Input: arr = [2,2,2,2,5,5,5,8], k = 3, threshold = 4 Output: 3 Explanation: Sub-arrays [2,5,5],[5,5,5] and [5,5,8] have averages 4, 5 and 6 respectively. All other sub-arrays of size 3 have averages less than 4 (the threshold). ``` ``` Input: arr = [11,13,17,23,29,31,7,5,2,3], k = 3, threshold = 5 Output: 6 Explanation: The first 6 sub-arrays of size 3 have averages greater than 5. Note that averages are not integers. ``` ### Constraints * 1 \<= arr.length \<= 10^5 * 1 \<= arr\[i] \<= 10^4 * 1 \<= k \<= arr.length * 0 \<= threshold \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_sub_arrays_of_size_k_and_average_greater_than_or_equal_to_threshold/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_sub_arrays_of_size_k_and_average_greater_than_or_equal_to_threshold/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: def num_of_subarrays(self, arr: list[int], k: int, threshold: int) -> int: window = sum(arr[:k]) target = k * threshold count = 1 if window >= target else 0 for i in range(k, len(arr)): window += arr[i] - arr[i - k] if window >= target: count += 1 return count ``` ## Complexity | Time | Space | | ---- | ----- | | - | - | ## Tags [NeetCode All](/catalog/neetcode). # Number of Subarrays with Bounded Maximum Source: https://leetcode-py.wisl.dev/problems/number-of-subarrays-with-bounded-maximum Tested Python solution for LeetCode 795 with 23 pytest cases. Generate a practice environment with lcpy. LeetCode 795, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/number-of-subarrays-with-bounded-maximum/description/). Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 795 # by problem number lcpy gen -s number_of_subarrays_with_bounded_maximum # by problem name ``` ## Problem Given an integer array \nums\ and two integers \left\ and \right\, return \the number of contiguous non-empty \subarrays\ such that the value of the maximum array element in that subarray is in the range\ \\[left, right]\.
The test cases are generated so that the answer will fit in a \32-bit\ integer.
### Examples
```
Input: nums = [2,1,4,3], left = 2, right = 3
Output: 3
Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3].
```
```
Input: nums = [2,9,2,5,6], left = 2, right = 8
Output: 7
```
### Constraints
* `1 <= nums.length <= 10^5`
* `0 <= nums[i] <= 10^9`
* `0 <= left <= right <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_subarrays_with_bounded_maximum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_subarrays_with_bounded_maximum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def num_subarray_bounded_max(self, nums: list[int], left: int, right: int) -> int:
def at_most(bound: int) -> int:
total = 0
run = 0
for value in nums:
run = run + 1 if value <= bound else 0
total += run
return total
return at_most(right) - at_most(left - 1)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Number of Sub-arrays With Odd Sum
Source: https://leetcode-py.wisl.dev/problems/number-of-subarrays-with-odd-sum
Tested Python solution for LeetCode 1524 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 1524, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/number-of-subarrays-with-odd-sum/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1524 # by problem number
lcpy gen -s number_of_subarrays_with_odd_sum # by problem name
```
## Problem
\Given an array of integers \arr\, return \the number of subarrays with an \odd\ sum\.\
Since the answer can be very large, return it modulo \10\9\ + 7\.\
matrix\ and a \target\, return the number of non-empty submatrices that sum to \target\.
A submatrix \x1, y1, x2, y2\ is the set of all cells \matrix\[x]\[y]\ with \x1 \<= x \<= x2\ and \y1 \<= y \<= y2\.
Two submatrices \(x1, y1, x2, y2)\ and \(x1', y1', x2', y2')\ are different if they have some coordinate that is different: for example, if \x1 != x1'\.
### Examples

```
Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
Output: 4
Explanation: The four 1x1 submatrices that only contain 0.
```
```
Input: matrix = [[1,-1],[-1,1]], target = 0
Output: 5
Explanation: The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.
```
```
Input: matrix = [[904]], target = 0
Output: 0
```
### Constraints
* \1 \<= matrix.length \<= 100\
* \1 \<= matrix\[0].length \<= 100\
* \-1000 \<= matrix\[i]\[j] \<= 1000\
* \-10\8\ \<= target \<= 10\8\\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_submatrices_that_sum_to_target/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_submatrices_that_sum_to_target/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(rows^2 * cols)
# Space: O(cols)
def num_submatrix_sum_target(self, matrix: list[list[int]], target: int) -> int:
rows, cols = len(matrix), len(matrix[0])
count = 0
for top in range(rows):
col_sums = [0] * cols
for bottom in range(top, rows):
for c in range(cols):
col_sums[c] += matrix[bottom][c]
prefix: dict[int, int] = {0: 1}
running = 0
for s in col_sums:
running += s
count += prefix.get(running - target, 0)
prefix[running] = prefix.get(running, 0) + 1
return count
```
## Complexity
| Time | Space |
| ----------------- | ------- |
| O(rows^2 \* cols) | O(cols) |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Subsequences That Satisfy the Given
Source: https://leetcode-py.wisl.dev/problems/number-of-subsequences-that-satisfy-the-given-sum-condition
Tested Python solution for LeetCode 1498 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1498, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1498 # by problem number
lcpy gen -s number_of_subsequences_that_satisfy_the_given_sum_condition # by problem name
```
## Problem
You are given an array of integers `nums` and an integer `target`.
Return *the number of **non-empty** subsequences of* `nums` *such that the sum of the minimum and maximum element on it is less or equal to* `target`. Since the answer may be too large, return it **modulo** `10^9 + 7`.
### Examples
```
Input: nums = [3,5,6,7], target = 9
Output: 4
Explanation: There are 4 subsequences that satisfy the condition.
[3] -> Min value + max value <= target (3 + 3 <= 9)
[3,5] -> (3 + 5 <= 9)
[3,5,6] -> (3 + 6 <= 9)
[3,6] -> (3 + 6 <= 9)
```
```
Input: nums = [3,3,6,8], target = 10
Output: 6
Explanation: There are 6 subsequences that satisfy the condition. (nums can have repeated numbers).
[3] , [3] , [3,3], [3,6] , [3,6] , [3,3,6]
```
```
Input: nums = [2,3,3,4,6,7], target = 12
Output: 61
Explanation: There are 63 non-empty subsequences, two of them do not satisfy the condition ([6,7], [7]).
Number of valid subsequences (63 - 2 = 61).
```
### Constraints
* 1 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= 10^6
* 1 \<= target \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_subsequences_that_satisfy_the_given_sum_condition/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_subsequences_that_satisfy_the_given_sum_condition/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(1) auxiliary (sorting aside)
def num_subseq(self, nums: list[int], target: int) -> int:
nums = sorted(nums)
mod = 1_000_000_007
n = len(nums)
pows = [1] * n
for i in range(1, n):
pows[i] = pows[i - 1] * 2 % mod
result = 0
left, right = 0, n - 1
while left <= right:
if nums[left] + nums[right] <= target:
result = (result + pows[right - left]) % mod
left += 1
else:
right -= 1
return result
```
## Complexity
| Time | Space |
| ---------- | ------------------------------ |
| O(n log n) | O(1) auxiliary (sorting aside) |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Substrings Containing All Three
Source: https://leetcode-py.wisl.dev/problems/number-of-substrings-containing-all-three-characters
Tested Python solution for LeetCode 1358 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1358, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/number-of-substrings-containing-all-three-characters/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1358 # by problem number
lcpy gen -s number_of_substrings_containing_all_three_characters # by problem name
```
## Problem
Given a string s consisting only of characters a, b and c.
Return the number of substrings containing at least one occurrence of all these characters a, b and c.
### Examples
```
Input: s = "abcabc"
Output: 10
Explanation: The substrings containing at least one occurrence of the characters a, b and c are "abc", "abca", "abcab", "abcabc", "bca", "bcab", "bcabc", "cab", "cabc" and "abc" (again).
```
```
Input: s = "aaacb"
Output: 3
Explanation: The substrings containing at least one occurrence of the characters a, b and c are "aaacb", "aacb" and "acb".
```
```
Input: s = "abc"
Output: 1
```
### Constraints
* 3 \<= s.length \<= 5 \* 10^4
* s only consists of 'a', 'b' or 'c' characters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_substrings_containing_all_three_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_substrings_containing_all_three_characters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def number_of_substrings(self, s: str) -> int:
count = 0
last = [-1, -1, -1]
for i, ch in enumerate(s):
last[ord(ch) - 97] = i
count += min(last) + 1
return count
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Visible People in a Queue
Source: https://leetcode-py.wisl.dev/problems/number-of-visible-people-in-a-queue
Tested Python solution for LeetCode 1944 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1944, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/number-of-visible-people-in-a-queue/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1944 # by problem number
lcpy gen -s number_of_visible_people_in_a_queue # by problem name
```
## Problem
There are `n` people standing in a queue, and they numbered from `0` to `n - 1` in **left to right** order. You are given an array `heights` of **distinct** integers where `heights[i]` represents the height of the `ith` person.
A person can **see** another person to their right in the queue if everybody in between is **shorter** than both of them. More formally, the `ith` person can see the `jth` person if `i < j` and `min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1])`.
Return *an array* `answer` *of length* `n` *where* `answer[i]` *is the **number of people** the `ith` person can **see** to their right in the queue*.
### Examples

```
Input: heights = [10,6,8,5,11,9]
Output: [3,1,2,1,1,0]
```
**Explanation:**
* Person 0 can see person 1, 2, and 4.
* Person 1 can see person 2.
* Person 2 can see person 3 and 4.
* Person 3 can see person 4.
* Person 4 can see person 5.
* Person 5 can see no one since nobody is to the right of them.
```
Input: heights = [5,1,2,3,10]
Output: [4,1,1,1,0]
```
### Constraints
* `n == heights.length`
* `1 <= n <= 10^5`
* `1 <= heights[i] <= 10^5`
* All the values of `heights` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_visible_people_in_a_queue/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_visible_people_in_a_queue/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def can_see_persons_count(self, heights: list[int]) -> list[int]:
n = len(heights)
answer = [0] * n
stack: list[int] = []
for i in range(n - 1, -1, -1):
height = heights[i]
while stack and stack[-1] < height:
stack.pop()
answer[i] += 1
if stack:
answer[i] += 1
stack.append(height)
return answer
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Ways to Arrive at Destination
Source: https://leetcode-py.wisl.dev/problems/number-of-ways-to-arrive-at-destination
Tested Python solution for LeetCode 1976 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 1976, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), [Shortest Path](/catalog/topics/shortest-path), Dijkstra's Algorithm. [View on LeetCode](https://leetcode.com/problems/number-of-ways-to-arrive-at-destination/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1976 # by problem number
lcpy gen -s number_of_ways_to_arrive_at_destination # by problem name
```
## Problem
You are in a city that consists of `n` intersections numbered from `0` to `n - 1` with **bi-directional** roads between some intersections. The inputs are generated such that you can reach any intersection from any other intersection and that there is at most one road between any two intersections.
You are given an integer `n` and a 2D integer array `roads` where `roads[i] = [ui, vi, timei]` means that there is a road between intersections `ui` and `vi` that takes `timei` minutes to travel. You want to know in how many ways you can travel from intersection `0` to intersection `n - 1` in the **shortest amount of time**.
Return *the **number of ways** you can arrive at your destination in the **shortest amount of time***. Since the answer may be large, return it **modulo** `109 + 7`.
### Examples

```
Input: n = 7, roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
Output: 4
Explanation: The shortest amount of time it takes to go from intersection 0 to intersection 6 is 7 minutes.
The four ways to get there in 7 minutes are:
- 0 ➝ 6
- 0 ➝ 4 ➝ 6
- 0 ➝ 1 ➝ 2 ➝ 5 ➝ 6
- 0 ➝ 1 ➝ 3 ➝ 5 ➝ 6
```
```
Input: n = 2, roads = [[1,0,10]]
Output: 1
Explanation: There is only one way to go from intersection 0 to intersection 1, and it takes 10 minutes.
```
### Constraints
* 1 \<= n \<= 200
* n - 1 \<= roads.length \<= n \* (n - 1) / 2
* roads\[i].length == 3
* 0 \<= u\i\, v\i\ \<= n - 1
* 1 \<= time\i\ \<= 10\9\
* u\i\ != v\i\
* There is at most one road connecting any two intersections.
* You can reach any intersection from any other intersection.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ways_to_arrive_at_destination/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ways_to_arrive_at_destination/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O((n + m) log n) where m = len(roads)
# Space: O(n + m)
def count_paths(self, n: int, roads: list[list[int]]) -> int:
mod = 1_000_000_007
adj: list[list[tuple[int, int]]] = [[] for _ in range(n)]
for u, v, t in roads:
adj[u].append((v, t))
adj[v].append((u, t))
# max path cost is n * max(time) <= 200 * 10^9, far below the sentinel
inf = 1 << 62
dist = [inf] * n
ways = [0] * n
dist[0] = 0
ways[0] = 1
heap: list[tuple[int, int]] = [(0, 0)]
while heap:
d, node = heapq.heappop(heap)
if d > dist[node]:
continue
for nxt, t in adj[node]:
nd = d + t
if nd < dist[nxt]:
dist[nxt] = nd
ways[nxt] = ways[node]
heapq.heappush(heap, (nd, nxt))
elif nd == dist[nxt]:
ways[nxt] = (ways[nxt] + ways[node]) % mod
return ways[n - 1]
```
## Complexity
| Time | Space |
| ------------------------------------- | -------- |
| O((n + m) log n) where m = len(roads) | O(n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Ways to Divide a Long Corridor
Source: https://leetcode-py.wisl.dev/problems/number-of-ways-to-divide-a-long-corridor
Tested Python solution for LeetCode 2147 with 25 pytest cases. Generate a practice environment with lcpy.
LeetCode 2147, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/number-of-ways-to-divide-a-long-corridor/description/).
Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2147 # by problem number
lcpy gen -s number_of_ways_to_divide_a_long_corridor # by problem name
```
## Problem
Along a long library corridor, there is a line of seats and decorative plants. You are given a 0-indexed string corridor of length n consisting of letters 'S' and 'P' where each 'S' represents a seat and each 'P' represents a plant.
One room divider has already been installed to the left of index 0, and another to the right of index n - 1. Additional room dividers can be installed. For each position between indices i - 1 and i (1 \<= i \<= n - 1), at most one divider can be installed.
Divide the corridor into non-overlapping sections, where each section has exactly two seats with any number of plants. There may be multiple ways to perform the division. Two ways are different if there is a position with a room divider installed in the first way but not in the second way.
Return the number of ways to divide the corridor. Since the answer may be very large, return it modulo 10^9 + 7. If there is no way, return 0.
### Examples

```
Input: corridor = "SSPPSPS"
Output: 3
Explanation: There are 3 different ways to divide the corridor.
The black bars in the above image indicate the two room dividers already installed.
Note that in each of the ways, each section has exactly two seats.
```

```
Input: corridor = "PPSPSP"
Output: 1
Explanation: There is only 1 way to divide the corridor, by not installing any additional dividers.
Installing any would create some section that does not have exactly two seats.
```

```
Input: corridor = "S"
Output: 0
Explanation: There is no way to divide the corridor because there will always be a section that does not have exactly two seats.
```
### Constraints
* n == corridor.length
* 1 \<= n \<= 10^5
* corridor\[i] is either 'S' or 'P'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ways_to_divide_a_long_corridor/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ways_to_divide_a_long_corridor/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def number_of_ways(self, corridor: str) -> int:
mod = 1_000_000_007
seats = 0
last_pair_end = -1
ways = 1
for i, ch in enumerate(corridor):
if ch != "S":
continue
seats += 1
if seats % 2 == 0:
last_pair_end = i
elif seats > 1:
# divider positions between the previous pair and this new pair
ways = ways * (i - last_pair_end) % mod
if seats == 0 or seats % 2:
return 0
return ways
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Ways to Form a Target String Given
Source: https://leetcode-py.wisl.dev/problems/number-of-ways-to-form-a-target-string-given-a-dictionary
Tested Python solution for LeetCode 1639 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 1639, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/number-of-ways-to-form-a-target-string-given-a-dictionary/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1639 # by problem number
lcpy gen -s number_of_ways_to_form_a_target_string_given_a_dictionary # by problem name
```
## Problem
You are given a list of strings of the same length `words` and a string `target`.
Your task is to form `target` using the given `words` under the following rules:
* `target` should be formed from left to right.
* To form the `i`th character (0-indexed) of `target`, you can choose the `k`th character of the `j`th string in `words` if `target[i] = words[j][k]`.
* Once you use the `k`th character of the `j`th string of `words`, you can no longer use the `x`th character of any string in `words` where `x <= k`. In other words, all characters to the left of or at index `k` become unusuable for every string.
* Repeat the process until you form the string `target`.
Notice that you can use multiple characters from the same string in `words` provided the conditions above are met.
Return the number of ways to form `target` from `words`. Since the answer may be too large, return it modulo `10^9 + 7`.
### Examples
```
Input: words = ["acca","bbbb","caca"], target = "aba"
Output: 6
Explanation: There are 6 ways to form target.
- index 0 (acca), index 1 (bbbb), index 3 (caca)
- index 0 (acca), index 2 (bbbb), index 3 (caca)
- index 0 (acca), index 1 (bbbb), index 3 (acca)
- index 0 (acca), index 2 (bbbb), index 3 (acca)
- index 1 (caca), index 2 (bbbb), index 3 (acca)
- index 1 (caca), index 2 (bbbb), index 3 (caca)
```
```
Input: words = ["abba","baab"], target = "bab"
Output: 4
Explanation: There are 4 ways to form target.
- index 0 (baab), index 1 (baab), index 2 (abba)
- index 0 (baab), index 1 (baab), index 3 (baab)
- index 0 (baab), index 2 (baab), index 3 (baab)
- index 1 (abba), index 2 (baab), index 3 (baab)
```
### Constraints
* 1 \<= words.length \<= 1000
* 1 \<= words\[i].length \<= 1000
* All strings in `words` have the same length.
* 1 \<= target.length \<= 1000
* `words[i]` and `target` consist of only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ways_to_form_a_target_string_given_a_dictionary/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_ways_to_form_a_target_string_given_a_dictionary/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(S + n * m) where S = total chars in words, n = len(words[0]), m = len(target)
# Space: O(26 * n + m)
def num_ways(self, words: list[str], target: str) -> int:
mod = 1_000_000_007
n = len(words[0])
m = len(target)
counts: list[list[int]] = [[0] * 26 for _ in range(n)]
for word in words:
for k, char in enumerate(word):
counts[k][ord(char) - 97] += 1
dp = [0] * (m + 1)
dp[0] = 1
for k in range(n):
column = counts[k]
for i in range(m, 0, -1):
freq = column[ord(target[i - 1]) - 97]
if freq:
dp[i] = (dp[i] + dp[i - 1] * freq) % mod
return dp[m]
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------------------- | -------------- |
| O(S + n \* m) where S = total chars in words, n = len(words\[0]), m = len(target) | O(26 \* n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Number of Ways to Split Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/number-of-ways-to-split-array
Tested Python solution for LeetCode 2270 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2270, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/number-of-ways-to-split-array/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2270 # by problem number
lcpy gen -s number_of_ways_to_split_array # by problem name
```
## Problem
You are given a \0-indexed\ integer array \nums\ of length \n\.
\\nums\ contains a \valid split\ at index \i\ if the following are true:\
i + 1\ elements is \greater than or equal to\ the sum of the last \n - i - 1\ elements.\i\. That is, \0 \<= i \< n - 1\.\Return \the number of \valid splits\ in\ \nums\.\
Given an integer array \nums\, return \the number of \subarrays\ filled with \\0\.\
A \subarray\ is a contiguous non-empty sequence of elements within an array.\
### Examples ``` Input: nums = [1,3,0,0,2,0,0,4] Output: 6 Explanation: There are 4 occurrences of [0] as a subarray. There are 2 occurrences of [0,0] as a subarray. There is no occurrence of a subarray with a size more than 2 filled with 0. Therefore, we return 6. ``` ``` Input: nums = [0,0,0,2,0,0] Output: 9 Explanation: There are 5 occurrences of [0] as a subarray. There are 3 occurrences of [0,0] as a subarray. There is 1 occurrence of [0,0,0] as a subarray. There is no occurrence of a subarray with a size more than 3 filled with 0. Therefore, we return 9. ``` ``` Input: nums = [2,10,2019] Output: 0 Explanation: There is no subarray filled with 0. Therefore, we return 0. ``` ### Constraints * 1 \<= nums.length \<= 10^5 * -10^9 \<= nums\[i] \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_zero_filled_subarrays/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/number_of_zero_filled_subarrays/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def zero_filled_subarray(self, nums: list[int]) -> int: total = 0 streak = 0 for num in nums: streak = streak + 1 if num == 0 else 0 total += streak return total ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Numbers At Most N Given Digit Set Source: https://leetcode-py.wisl.dev/problems/numbers-at-most-n-given-digit-set Tested Python solution for LeetCode 902 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 902, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [String](/catalog/topics/string), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/numbers-at-most-n-given-digit-set/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 902 # by problem number lcpy gen -s numbers_at_most_n_given_digit_set # by problem name ``` ## Problem Given an array of `digits` which is sorted in **non-decreasing** order. You can write numbers using each `digits[i]` as many times as we want. For example, if `digits = ['1','3','5']`, we may write numbers such as `'13'`, `'551'`, and `'1351315'`. Return the number of positive integers that can be generated that are less than or equal to a given integer `n`. ### Examples ``` Input: digits = ["1","3","5","7"], n = 100 Output: 20 ``` **Explanation:** The 20 numbers that can be written are: 1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77. ``` Input: digits = ["1","4","9"], n = 1000000000 Output: 29523 ``` **Explanation:** We can write 3 one digit numbers, 9 two digit numbers, 27 three digit numbers, 81 four digit numbers, 243 five digit numbers, 729 six digit numbers, 2187 seven digit numbers, 6561 eight digit numbers, and 19683 nine digit numbers. In total, this is 29523 integers that can be written using the digits array. ``` Input: digits = ["7"], n = 8 Output: 1 ``` ### Constraints * 1 \<= digits.length \<= 9 * digits\[i].length == 1 * digits\[i] is a digit from '1' to '9'. * All the values in digits are unique. * digits is sorted in non-decreasing order. * 1 \<= n \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/numbers_at_most_n_given_digit_set/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/numbers_at_most_n_given_digit_set/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log n * len(digits)) # Space: O(log n) def at_most_n_given_digit_set(self, digits: list[str], n: int) -> int: ds = sorted(int(d) for d in digits) s = str(n) k = len(s) allowed = set(ds) total = sum(len(ds) ** length for length in range(1, k)) for i, ch in enumerate(s): total += sum(d < int(ch) for d in ds) * len(ds) ** (k - 1 - i) if int(ch) not in allowed: break else: total += 1 return total ``` ## Complexity | Time | Space | | ----------------------- | -------- | | O(log n \* len(digits)) | O(log n) | ## Tags # Numbers With Same Consecutive Differences Source: https://leetcode-py.wisl.dev/problems/numbers-with-same-consecutive-differences Tested Python solution for LeetCode 967 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 967, [Medium](/catalog/medium). Topics: [Backtracking](/catalog/topics/backtracking), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/numbers-with-same-consecutive-differences/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 967 # by problem number lcpy gen -s numbers_with_same_consecutive_differences # by problem name ``` ## Problem Given two integers `n` and `k`, return an array of all the integers of length `n` where the difference between every two consecutive digits is `k`. You may return the answer in any order. Note that the integers should not have leading zeros. Integers as `02` and `043` are not allowed. ### Examples ``` Input: n = 3, k = 7 Output: [181,292,707,818,929] Explanation: Note that 070 is not a valid number, because it has leading zeroes. ``` ``` Input: n = 2, k = 1 Output: [10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98] ``` ### Constraints * `2 <= n <= 9` * `0 <= k <= 9` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/numbers_with_same_consecutive_differences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/numbers_with_same_consecutive_differences/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(2^n * n) over digit sequences of length n # Space: O(2^n) for the answer def nums_same_consec_diff(self, n: int, k: int) -> list[int]: digits = list(range(1, 10)) for _ in range(n - 1): nxt: list[int] = [] for num in digits: last = num % 10 if last + k <= 9: nxt.append(num * 10 + last + k) if k and last - k >= 0: nxt.append(num * 10 + last - k) digits = nxt return digits ``` ## Complexity | Time | Space | | -------------------------------------------- | --------------------- | | O(2^n \* n) over digit sequences of length n | O(2^n) for the answer | ## Tags # Odd Even Jump Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/odd-even-jumps Tested Python solution for LeetCode 975 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 975, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Stack](/catalog/topics/stack), [Sorting](/catalog/topics/sorting), [Monotonic Stack](/catalog/topics/monotonic-stack), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/odd-even-jumps/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 975 # by problem number lcpy gen -s odd_even_jumps # by problem name ``` ## Problem You are given an integer array `arr`. From some starting index, you can make a series of jumps. The (1st, 3rd, 5th, ...) jumps in the series are called odd-numbered jumps, and the (2nd, 4th, 6th, ...) jumps in the series are called even-numbered jumps. Note that the jumps are numbered, not the indices. You may jump forward from index `i` to index `j` (with `i < j`) in the following way: * During odd-numbered jumps (i.e., jumps 1, 3, 5, ...), you jump to the index `j` such that `arr[i] <= arr[j]` and `arr[j]` is the smallest possible value. If there are multiple such indices `j`, you can only jump to the smallest such index `j`. * During even-numbered jumps (i.e., jumps 2, 4, 6, ...), you jump to the index `j` such that `arr[i] >= arr[j]` and `arr[j]` is the largest possible value. If there are multiple such indices `j`, you can only jump to the smallest such index `j`. * It may be the case that for some index `i`, there are no legal jumps. A starting index is good if, starting from that index, you can reach the end of the array (index `arr.length - 1`) by jumping some number of times (possibly 0 or more than once). Return the number of good starting indices. ### Examples ``` Input: arr = [10,13,12,14,15] Output: 2 Explanation: From starting index i = 0, we can make our 1st jump to i = 2 (since arr[2] is the smallest among arr[1], arr[2], arr[3], arr[4] that is greater or equal to arr[0]), then we cannot jump any more. From starting index i = 1 and i = 2, we can make our 1st jump to i = 3, then we cannot jump any more. From starting index i = 3, we can make our 1st jump to i = 4, so we have reached the end. From starting index i = 4, we have reached the end already. In total, there are 2 different starting indices i = 3 and i = 4, where we can reach the end with some number of jumps. ``` ``` Input: arr = [2,3,1,1,4] Output: 3 Explanation: From starting index i = 0, we make jumps to i = 1, i = 2, i = 3: During our 1st jump (odd-numbered), we first jump to i = 1 because arr[1] is the smallest value in [arr[1], arr[2], arr[3], arr[4]] that is greater than or equal to arr[0]. During our 2nd jump (even-numbered), we jump from i = 1 to i = 2 because arr[2] is the largest value in [arr[2], arr[3], arr[4]] that is less than or equal to arr[1]. arr[3] is also the largest value, but 2 is a smaller index, so we can only jump to i = 2 and not i = 3. During our 3rd jump (odd-numbered), we jump from i = 2 to i = 3 because arr[3] is the smallest value in [arr[3], arr[4]] that is greater than or equal to arr[2]. We can't jump from i = 3 to i = 4, so the starting index i = 0 is not good. In a similar manner, we can deduce that: From starting index i = 1, we jump to i = 4, so we reach the end. From starting index i = 2, we jump to i = 3, and then we can't jump anymore. From starting index i = 3, we jump to i = 4, so we reach the end. From starting index i = 4, we are already at the end. In total, there are 3 different starting indices i = 1, i = 3, and i = 4, where we can reach the end with some number of jumps. ``` ``` Input: arr = [5,1,3,4,2] Output: 3 Explanation: We can reach the end from starting indices 1, 2, and 4. ``` ### Constraints * 1 \<= arr.length \<= 2 \* 10^4 * 0 \<= arr\[i] \< 10^5 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/odd_even_jumps/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/odd_even_jumps/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) sorting plus linear DP # Space: O(n) for the two jump maps def odd_even_jumps(self, arr: list[int]) -> int: n = len(arr) def make_next(indices: list[int]) -> list[int | None]: # For each index j, the next index (in sorted order) greater than j: # its first jump target, honoring the smallest-index tie-break. nxt: list[int | None] = [None] * n stack: list[int] = [] for i in indices: while stack and i > stack[-1]: nxt[stack.pop()] = i stack.append(i) return nxt odd_next = make_next(sorted(range(n), key=lambda i: arr[i])) even_next = make_next(sorted(range(n), key=lambda i: -arr[i])) # higher[i]: a good end is reachable from i when the next jump is odd-numbered higher = [False] * n lower = [False] * n higher[n - 1] = lower[n - 1] = True for i in range(n - 2, -1, -1): odd_target = odd_next[i] if odd_target is not None: higher[i] = lower[odd_target] even_target = even_next[i] if even_target is not None: lower[i] = higher[even_target] return sum(higher) ``` ## Complexity | Time | Space | | --------------------------------- | -------------------------- | | O(n log n) sorting plus linear DP | O(n) for the two jump maps | ## Tags # Odd Even Linked List Python Solution Source: https://leetcode-py.wisl.dev/problems/odd-even-linked-list Tested Python solution for LeetCode 328 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 328, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/odd-even-linked-list/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 328 # by problem number lcpy gen -s odd_even_linked_list # by problem name ``` ## Problem Given the `head` of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return *the reordered list*. The **first** node is considered **odd**, and the **second** node is **even**, and so on. Note that the relative order inside both the even and odd groups should remain as it was in the input. You must solve the problem in `O(1)` extra space complexity and `O(n)` time complexity. ### Examples  ``` Input: head = [1,2,3,4,5] Output: [1,3,5,2,4] ```  ``` Input: head = [2,1,3,5,6,4,7] Output: [2,3,6,7,1,5,4] ``` ### Constraints * The number of nodes in the linked list is in the range \[0, 10^4] * -10^6 \<= Node.val \<= 10^6 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/odd_even_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/odd_even_linked_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) - single pass through list # Space: O(1) - only pointer manipulation def odd_even_list(self, head: ListNode[int] | None) -> ListNode[int] | None: """ Group odd-indexed nodes followed by even-indexed nodes. Example: [1,2,3,4,5] → [1,3,5,2,4] Step 1: Separate odd and even chains odd: 1 → 3 → 5 → None even: 2 → 4 → None Step 2: Connect odd tail to even head 1 → 3 → 5 → 2 → 4 → None """ if not head or not head.next: return head odd = head even: ListNode[int] | None = head.next even_head = even while even and even.next: odd.next = even.next odd = odd.next even.next = odd.next even = even.next odd.next = even_head return head ``` ## Complexity | Time | Space | | ------------------------------- | -------------------------------- | | O(n) - single pass through list | O(1) - only pointer manipulation | ## Tags [Grind](/catalog/grind). # 1-bit and 2-bit Characters Python Solution Source: https://leetcode-py.wisl.dev/problems/one-bit-and-two-bit-characters Tested Python solution for LeetCode 717 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 717, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/one-bit-and-two-bit-characters/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 717 # by problem number lcpy gen -s one_bit_and_two_bit_characters # by problem name ``` ## Problem We have two special characters: * The first character can be represented by one bit `0`. * The second character can be represented by two bits (`10` or `11`). Given a binary array `bits` that ends with `0`, return `true` if the last character must be a one-bit character. ### Examples ``` Input: bits = [1,0,0] Output: true Explanation: The only way to decode it is two-bit character and one-bit character. So the last character is one-bit character. ``` ``` Input: bits = [1,1,1,0] Output: false Explanation: The only way to decode it is two-bit character and two-bit character. So the last character is not one-bit character. ``` ### Constraints * 1 \<= bits.length \<= 1000 * bits\[i] is either 0 or 1. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/one_bit_and_two_bit_characters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/one_bit_and_two_bit_characters/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def is_one_bit_character(self, bits: list[int]) -> bool: ones = 0 for bit in reversed(bits[:-1]): if bit == 0: break ones += 1 return ones % 2 == 0 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # One Edit Distance Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/one-edit-distance Tested Python solution for LeetCode 161 with 25 pytest cases. Generate a practice environment with lcpy. LeetCode 161, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/one-edit-distance/description/). Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 161 # by problem number lcpy gen -s one_edit_distance # by problem name ``` ## Problem Given two strings `s` and `t`, return `true` if they are both one edit distance apart, otherwise return `false`. A string `s` is said to be one distance apart from a string `t` if you can: * Insert exactly one character into `s` to get `t`. * Delete exactly one character from `s` to get `t`. * Replace exactly one character of `s` to get `t`. ### Examples ``` Input: s = "ab", t = "acb" Output: true Explanation: We can insert 'c' into s to get t. ``` ``` Input: s = "cab", t = "ad" Output: false Explanation: We cannot get t from s by only one step. ``` ``` Input: s = "1203", t = "1213" Output: true Explanation: We can replace '0' with '1' to get t. ``` ### Constraints * 0 \<= s.length, t.length \<= 10^4 * s and t consist of lowercase letters, uppercase letters, and digits ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/one_edit_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/one_edit_distance/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def is_one_edit_distance(self, s: str, t: str) -> bool: if len(s) > len(t): return self.is_one_edit_distance(t, s) if len(t) - len(s) > 1: return False for i in range(len(s)): if s[i] != t[i]: if len(s) == len(t): return s[i + 1 :] == t[i + 1 :] return s[i:] == t[i + 1 :] return len(s) + 1 == len(t) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Ones and Zeroes Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/ones-and-zeroes Tested Python solution for LeetCode 474 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 474, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/ones-and-zeroes/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 474 # by problem number lcpy gen -s ones_and_zeroes # by problem name ``` ## Problem You are given an array of binary strings `strs` and two integers `m` and `n`. Return *the size of the largest subset of `strs` such that there are **at most** `m` `0`'s and `n` `1`'s in the subset*. A set `x` is a **subset** of a set `y` if all elements of `x` are also elements of `y`. ### Examples ``` Input: strs = ["10","0001","111001","1","0"], m = 5, n = 3 Output: 4 Explanation: The largest subset with at most 5 0's and 3 1's is {"10", "0001", "1", "0"}, so the answer is 4. Other valid but smaller subsets include {"0001", "1"} and {"10", "1", "0"}. {"111001"} is an invalid subset because it contains 4 1's, greater than the maximum of 3. ``` ``` Input: strs = ["10","0","1"], m = 1, n = 1 Output: 2 Explanation: The largest subset is {"0", "1"}, so the answer is 2. ``` ### Constraints * `1 <= strs.length <= 600` * `1 <= strs[i].length <= 100` * `strs[i]` consists only of digits `'0'` and `'1'`. * `1 <= m, n <= 100` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/ones_and_zeroes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/ones_and_zeroes/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(l * m * n + total chars) # Space: O(m * n) def find_max_form(self, strs: list[str], m: int, n: int) -> int: dp = [[0] * (n + 1) for _ in range(m + 1)] for s in strs: zeros = s.count("0") ones = len(s) - zeros for i in range(m, zeros - 1, -1): for j in range(n, ones - 1, -1): dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1) return dp[m][n] ``` ## Complexity | Time | Space | | ---------------------------- | --------- | | O(l \* m \* n + total chars) | O(m \* n) | ## Tags [NeetCode All](/catalog/neetcode). # Online Election Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/online-election Tested Python solution for LeetCode 911 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 911, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Binary Search](/catalog/topics/binary-search), [Design](/catalog/topics/design). [View on LeetCode](https://leetcode.com/problems/online-election/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 911 # by problem number lcpy gen -s online_election # by problem name ``` ## Problem You are given two integer arrays `persons` and `times`. In an election, the `i-th` vote was cast for `persons[i]` at time `times[i]`. For each query at a time `t`, find the person that was leading the election at time `t`. Votes cast at time `t` will count towards our query. In the case of a tie, the most recent vote (among tied candidates) wins. Implement the `TopVotedCandidate` class: * `TopVotedCandidate(int[] persons, int[] times)` Initializes the object with the `persons` and `times` arrays. * `int q(int t)` Returns the number of the person that was leading the election at time `t` according to the mentioned rules. ### Examples ``` Input ["TopVotedCandidate", "q", "q", "q", "q", "q", "q"] [[[0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]], [3], [12], [25], [15], [24], [8]] Output [null, 0, 1, 1, 0, 0, 1] Explanation TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]); topVotedCandidate.q(3); // return 0, At time 3, the votes are [0], and 0 is leading. topVotedCandidate.q(12); // return 1, At time 12, the votes are [0,1,1], and 1 is leading. topVotedCandidate.q(25); // return 1, At time 25, the votes are [0,1,1,0,0,1], and 1 is leading (as ties go to the most recent vote.) topVotedCandidate.q(15); // return 0 topVotedCandidate.q(24); // return 0 topVotedCandidate.q(8); // return 1 ``` ### Constraints * `1 <= persons.length <= 5000` * `times.length == persons.length` * `0 <= persons[i] < persons.length` * `0 <= times[i] <= 10^9` * `times` is sorted in a strictly increasing order. * `times[0] <= t <= 10^9` * At most `10^4` calls will be made to `q`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/online_election/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/online_election/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from bisect import bisect_right class TopVotedCandidate: # Time: O(n) to build the leader timeline # Space: O(n) for the leader timeline def __init__(self, persons: list[int], times: list[int]) -> None: self.times = times self.leaders: list[int] = [] counts: dict[int, int] = {} leader = -1 for person in persons: counts[person] = counts.get(person, 0) + 1 if counts[person] >= counts.get(leader, 0): leader = person self.leaders.append(leader) # Time: O(log n) # Space: O(1) def q(self, t: int) -> int: return self.leaders[bisect_right(self.times, t) - 1] ``` ## Complexity | Time | Space | | --------------------------------- | ---------------------------- | | O(n) to build the leader timeline | O(n) for the leader timeline | ## Tags # Online Stock Span Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/online-stock-span Tested Python solution for LeetCode 901 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 901, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Design](/catalog/topics/design), [Monotonic Stack](/catalog/topics/monotonic-stack), [Data Stream](/catalog/topics/data-stream). [View on LeetCode](https://leetcode.com/problems/online-stock-span/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 901 # by problem number lcpy gen -s online_stock_span # by problem name ``` ## Problem Design an algorithm that collects daily price quotes for some stock and returns **the span** of that stock's price for the current day. The **span** of the stock's price in one day is the maximum number of consecutive days (starting from that day and going backward) for which the stock price was less than or equal to the price of that day. * For example, if the prices of the stock in the last four days is `[7,2,1,2]` and the price of the stock today is `2`, then the span of today is `4` because starting from today, the price of the stock was less than or equal `2` for `4` consecutive days. * Also, if the prices of the stock in the last four days is `[7,34,1,2]` and the price of the stock today is `8`, then the span of today is `3` because starting from today, the price of the stock was less than or equal `8` for `3` consecutive days. Implement the `StockSpanner` class: * `StockSpanner()` Initializes the object of the class. * `int next(int price)` Returns the **span** of the stock's price given that today's price is `price`. ### Examples ``` 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 ``` ### Constraints * 1 \<= price \<= 10^5 * At most 10^4 calls will be made to `next`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/online_stock_span/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/online_stock_span/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class StockSpanner: # Time: O(1) amortized per next call # Space: O(n) def __init__(self) -> None: # Monotonic decreasing stack of (price, span) pairs. self.stack: list[tuple[int, int]] = [] def next(self, price: int) -> int: span = 1 while self.stack and self.stack[-1][0] <= price: span += self.stack.pop()[1] self.stack.append((price, span)) return span ``` ## Complexity | Time | Space | | ---------------------------- | ----- | | O(1) amortized per next call | O(n) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Open the Lock Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/open-the-lock Tested Python solution for LeetCode 752 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 752, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/open-the-lock/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 752 # by problem number lcpy gen -s open_the_lock # by problem name ``` ## Problem You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: `'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'`. The wheels can rotate freely and wrap around: for example we can turn `'9'` to be `'0'`, or `'0'` to be `'9'`. Each move consists of turning one wheel one slot. The lock initially starts at `'0000'`, a string representing the state of the 4 wheels. You are given a list of `deadends` dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it. Given a `target` representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or `-1` if it is impossible. ### Examples ``` Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202" Output: 6 Explanation: A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202". Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid, because the wheels of the lock become stuck after the display becomes the dead end "0102". ``` ``` Input: deadends = ["8888"], target = "0009" Output: 1 Explanation: We can turn the last wheel in reverse to move from "0000" -> "0009". ``` ``` Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888" Output: -1 Explanation: We cannot reach the target without getting stuck. ``` ### Constraints * 1 \<= deadends.length \<= 500 * deadends\[i].length == 4 * target.length == 4 * target will not be in the list `deadends`. * `target` and `deadends[i]` consist of digits only. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/open_the_lock/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/open_the_lock/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(10^4) # Space: O(10^4) def open_lock(self, deadends: list[str], target: str) -> int: dead = set(deadends) if "0000" in dead: return -1 if target == "0000": return 0 queue: deque[tuple[str, int]] = deque([("0000", 0)]) visited: set[str] = {"0000"} while queue: state, turns = queue.popleft() for i in range(4): digit = int(state[i]) for delta in (1, -1): new_digit = (digit + delta) % 10 neighbor = state[:i] + str(new_digit) + state[i + 1 :] if neighbor == target: return turns + 1 if neighbor in dead or neighbor in visited: continue visited.add(neighbor) queue.append((neighbor, turns + 1)) return -1 ``` ## Complexity | Time | Space | | ------- | ------- | | O(10^4) | O(10^4) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Operations on Tree Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/operations-on-tree Tested Python solution for LeetCode 1993 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 1993, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Design](/catalog/topics/design). [View on LeetCode](https://leetcode.com/problems/operations-on-tree/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1993 # by problem number lcpy gen -s operations_on_tree # by problem name ``` ## Problem You are given a tree with `n` nodes numbered from `0` to `n - 1` in the form of a parent array `parent` where `parent[i]` is the parent of the `ith` node. The root of the tree is node `0`, so `parent[0] = -1` since it has no parent. You want to design a data structure that allows users to lock, unlock, and upgrade nodes in the tree. The data structure should support the following functions: * **Lock:** Locks the given node for the given user and prevents other users from locking the same node. You may only lock a node using this function if the node is unlocked. * **Unlock:** Unlocks the given node for the given user. You may only unlock a node using this function if it is currently locked by the same user. * **Upgrade:** Locks the given node for the given user and unlocks all of its descendants regardless of who locked it. You may only upgrade a node if all 3 conditions are true: * The node is unlocked, * It has at least one locked descendant (by any user), and * It does not have any locked ancestors. Implement the `LockingTree` class: * `LockingTree(int[] parent)` initializes the data structure with the parent array. * `lock(int num, int user)` returns `true` if it is possible for the user with id `user` to lock the node `num`, or `false` otherwise. If it is possible, the node `num` will become locked by the user with id `user`. * `unlock(int num, int user)` returns `true` if it is possible for the user with id `user` to unlock the node `num`, or `false` otherwise. If it is possible, the node `num` will become unlocked. * `upgrade(int num, int user)` returns `true` if it is possible for the user with id `user` to upgrade the node `num`, or `false` otherwise. If it is possible, the node `num` will be upgraded. ### Examples  ``` Input ["LockingTree", "lock", "unlock", "unlock", "lock", "upgrade", "lock"] [[[-1, 0, 0, 1, 1, 2, 2]], [2, 2], [2, 3], [2, 2], [4, 5], [0, 1], [0, 1]] Output [null, true, false, true, true, true, false] Explanation LockingTree lockingTree = new LockingTree([-1, 0, 0, 1, 1, 2, 2]); lockingTree.lock(2, 2); // return true because node 2 is unlocked. // Node 2 will now be locked by user 2. lockingTree.unlock(2, 3); // return false because user 3 cannot unlock a node // locked by user 2. lockingTree.unlock(2, 2); // return true because node 2 was previously locked by // user 2. Node 2 will now be unlocked. lockingTree.lock(4, 5); // return true because node 4 is unlocked. // Node 4 will now be locked by user 5. lockingTree.upgrade(0, 1); // return true because node 0 is unlocked and has at // least one locked descendant (node 4). Node 0 will // now be locked by user 1 and node 4 will now be // unlocked. lockingTree.lock(0, 1); // return false because node 0 is already locked. ``` ### Constraints * `n == parent.length` * `2 <= n <= 2000` * `0 <= parent[i] <= n - 1` for `i != 0` * `parent[0] == -1` * `0 <= num <= n - 1` * `1 <= user <= 10^4` * `parent` represents a valid tree. * At most `2000` calls in total will be made to `lock`, `unlock`, and `upgrade`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/operations_on_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/operations_on_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class LockingTree: # Time: __init__ O(n), lock O(1), unlock O(1), upgrade O(n) per call # Space: O(n) def __init__(self, parent: list[int]) -> None: self.parent = parent self.children: list[list[int]] = [[] for _ in parent] for node, par in enumerate(parent): if par != -1: self.children[par].append(node) self.locked_by: dict[int, int] = {} def lock(self, num: int, user: int) -> bool: if num in self.locked_by: return False self.locked_by[num] = user return True def unlock(self, num: int, user: int) -> bool: if self.locked_by.get(num) != user: return False del self.locked_by[num] return True def upgrade(self, num: int, user: int) -> bool: if num in self.locked_by or self._locked_ancestor(num) or not self._locked_descendant(num): return False self._release_descendants(num) self.locked_by[num] = user return True def _locked_ancestor(self, num: int) -> bool: node = self.parent[num] while node != -1: if node in self.locked_by: return True node = self.parent[node] return False def _locked_descendant(self, num: int) -> bool: stack = [num] while stack: node = stack.pop() for child in self.children[node]: if child in self.locked_by: return True stack.append(child) return False def _release_descendants(self, num: int) -> None: stack = [num] while stack: node = stack.pop() for child in self.children[node]: self.locked_by.pop(child, None) stack.append(child) ``` ## Complexity | Time | Space | | ------------------------------------------------------------ | ----- | | **init** O(n), lock O(1), unlock O(1), upgrade O(n) per call | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Optimal Account Balancing Python Solution Source: https://leetcode-py.wisl.dev/problems/optimal-account-balancing Tested Python solution for LeetCode 465 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 465, [Hard](/catalog/hard). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation), [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/optimal-account-balancing/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 465 # by problem number lcpy gen -s optimal_account_balancing # by problem name ``` ## Problem You are given an array of transactions `transactions` where `transactions[i] = [from_i, to_i, amount_i]` indicates that the person with `ID = from_i` gave `amount_i $` to the person with `ID = to_i`. Return the minimum number of transactions required to settle the debt. ### Examples ``` Input: transactions = [[0,1,10],[2,0,5]] Output: 2 Explanation: Person #0 gave person #1 $10. Person #2 gave person #0 $5. Two transactions are needed. One way to settle the debt is person #1 pays person #0 and #2 $5 each. ``` ``` Input: transactions = [[0,1,10],[1,0,1],[1,2,5],[2,0,5]] Output: 1 Explanation: Person #0 gave person #1 $10. Person #1 gave person #0 $1. Person #1 gave person #2 $5. Person #2 gave person #0 $5. Therefore, person #1 only need to give person #0 $4, and all debt is settled. ``` ### Constraints * `1 <= transactions.length <= 8` * `transactions[i].length == 3` * `0 <= from_i, to_i < 12` * `from_i != to_i` * `1 <= amount_i <= 100` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimal_account_balancing/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimal_account_balancing/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(k! ) worst case over k non-zero balances # Space: O(k) def min_transfers(self, transactions: list[list[int]]) -> int: balances: dict[int, int] = {} for sender, receiver, amount in transactions: balances[sender] = balances.get(sender, 0) - amount balances[receiver] = balances.get(receiver, 0) + amount debts = [v for v in balances.values() if v != 0] def settle(start: int) -> int: while start < len(debts) and debts[start] == 0: start += 1 if start == len(debts): return 0 best = len(debts) seen: set[int] = set() for i in range(start + 1, len(debts)): if debts[i] * debts[start] < 0 and debts[i] not in seen: seen.add(debts[i]) debts[i] += debts[start] best = min(best, 1 + settle(start + 1)) debts[i] -= debts[start] return best return settle(0) ``` ## Complexity | Time | Space | | ------------------------------------------ | ----- | | O(k! ) worst case over k non-zero balances | O(k) | ## Tags [NeetCode All](/catalog/neetcode). # Optimal Division Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/optimal-division Tested Python solution for LeetCode 553 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 553, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/optimal-division/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 553 # by problem number lcpy gen -s optimal_division # by problem name ``` ## Problem You are given an integer array `nums`. The adjacent integers in `nums` will perform the float division. * For example, for `nums = [2,3,4]`, we will evaluate the expression `"2/3/4"`. However, you can add any number of parenthesis at any position to change the priority of operations. You want to add these parentheses such the value of the expression after the evaluation is maximum. Return *the corresponding expression that has the maximum value in string format*. **Note:** your expression should not contain redundant parenthesis. ### Examples ``` Input: nums = [1000,100,10,2] Output: "1000/(100/10/2)" Explanation: 1000/(100/10/2) = 1000/((100/10)/2) = 200 However, the bold parenthesis in "1000/((100/10)/2)" are redundant since they do not influence the operation priority. So you should return "1000/(100/10/2)". Other cases: 1000/(100/10)/2 = 50 1000/(100/(10/2)) = 50 1000/100/10/2 = 0.5 1000/100/(10/2) = 2 ``` ``` Input: nums = [2,3,4] Output: "2/(3/4)" Explanation: (2/(3/4)) = 8/3 = 2.667 It can be shown that after trying all possibilities, we cannot get an expression with evaluation greater than 2.667 ``` ### Constraints * 1 \<= nums.length \<= 10 * 2 \<= nums\[i] \<= 1000 * There is only one optimal division for the given input. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimal_division/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimal_division/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def optimal_division(self, nums: list[int]) -> str: if len(nums) == 1: return str(nums[0]) if len(nums) == 2: return f"{nums[0]}/{nums[1]}" return f"{nums[0]}/(" + "/".join(str(x) for x in nums[1:]) + ")" ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Optimal Partition of String Python Solution Source: https://leetcode-py.wisl.dev/problems/optimal-partition-of-string Tested Python solution for LeetCode 2405 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 2405, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/optimal-partition-of-string/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2405 # by problem number lcpy gen -s optimal_partition_of_string # by problem name ``` ## Problem Given a string `s`, partition the string into one or more substrings such that the characters in each substring are unique. That is, no letter appears in a single substring more than once. Return the minimum number of substrings in such a partition. Note that each character should belong to exactly one substring in a partition. ### Examples ``` Input: s = "abacaba" Output: 4 Explanation: Two possible partitions are ("a","ba","cab","a") and ("ab","a","ca","ba"). It can be shown that 4 is the minimum number of substrings needed. ``` ``` Input: s = "ssssss" Output: 6 Explanation: The only valid partition is ("s","s","s","s","s","s"). ``` ### Constraints * 1 \<= s.length \<= 10^5 * s consists of only English lowercase letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimal_partition_of_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimal_partition_of_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def partition_string(self, s: str) -> int: seen = 0 count = 1 for ch in s: bit = 1 << (ord(ch) - 97) if seen & bit: count += 1 seen = bit else: seen |= bit return count ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Optimize Water Distribution in a Village Source: https://leetcode-py.wisl.dev/problems/optimize-water-distribution-in-a-village Tested Python solution for LeetCode 1168 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 1168, [Hard](/catalog/hard). Topics: [Union Find](/catalog/topics/union-find), [Graph](/catalog/topics/graph), Minimum Spanning Tree, [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/optimize-water-distribution-in-a-village/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1168 # by problem number lcpy gen -s optimize_water_distribution_in_a_village # by problem name ``` ## Problem There are `n` houses in a village. We want to supply water for all the houses by building wells and laying pipes. For each house `i`, we can either build a well inside it directly with cost `wells[i - 1]` (note the `-1` due to **0-indexing**), or pipe in water from another well to it. The costs to lay pipes between houses are given by the array `pipes` where each `pipes[j] = [house1_j, house2_j, cost_j]` represents the cost to connect `house1_j` and `house2_j` together using a pipe. Connections are bidirectional, and there could be multiple valid connections between the same two houses with different costs. Return *the minimum total cost to supply water to all houses*. ### Examples  ``` Input: n = 3, wells = [1,2,2], pipes = [[1,2,1],[2,3,1]] Output: 3 Explanation: The image shows the costs of connecting houses using pipes. The best strategy is to build a well in the first house with cost 1 and connect the other houses to it with cost 2 so the total cost is 3. ``` ``` Input: n = 2, wells = [1,1], pipes = [[1,2,1],[1,2,2]] Output: 2 Explanation: We can supply water with cost two using one of the three options: Option 1: - Build a well inside house 1 with cost 1. - Build a well inside house 2 with cost 1. The total cost will be 2. Option 2: - Build a well inside house 1 with cost 1. - Connect house 2 with house 1 with cost 1. The total cost will be 2. Option 3: - Build a well inside house 2 with cost 1. - Connect house 1 with house 2 with cost 1. The total cost will be 2. Note that we can connect houses 1 and 2 with cost 1 or with cost 2 but we will always choose **the cheapest option**. ``` ### Constraints * 2 \<= n \<= 10^4 * wells.length == n * 0 \<= wells\[i] \<= 10^5 * 1 \<= pipes.length \<= 10^4 * pipes\[j].length == 3 * 1 \<= house1\_j, house2\_j \<= n * 0 \<= cost\_j \<= 10^5 * house1\_j != house2\_j ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimize_water_distribution_in_a_village/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/optimize_water_distribution_in_a_village/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O((m + n) log(m + n)) where m = len(pipes), n = len(wells) # Space: O(n + m) def min_cost_to_supply_water(self, n: int, wells: list[int], pipes: list[list[int]]) -> int: # Virtual well node 0: connecting house i to it costs wells[i - 1]. edges = [(w, 0, i + 1) for i, w in enumerate(wells)] edges += [(c, a, b) for a, b, c in pipes] edges.sort() parent = list(range(n + 1)) def find(x: int) -> int: while parent[x] != x: parent[x] = parent[parent[x]] x = parent[x] return x total = 0 components = n + 1 for cost, a, b in edges: ra, rb = find(a), find(b) if ra == rb: continue parent[ra] = rb total += cost components -= 1 if components == 1: break return total ``` ## Complexity | Time | Space | | ---------------------------------------------------------- | -------- | | O((m + n) log(m + n)) where m = len(pipes), n = len(wells) | O(n + m) | ## Tags # Orderly Queue Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/orderly-queue Tested Python solution for LeetCode 899 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 899, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting), Lexicographically Minimal String Rotation. [View on LeetCode](https://leetcode.com/problems/orderly-queue/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 899 # by problem number lcpy gen -s orderly_queue # by problem name ``` ## Problem You are given a string `s` and an integer `k`. You can choose one of the first `k` letters of `s` and append it at the end of the string. Return *the lexicographically smallest string you could have after applying the mentioned step any number of moves*. ### Examples ``` Input: s = "cba", k = 1 Output: "acb" Explanation: In the first move, we move the 1st character 'c' to the end, obtaining the string "bac". In the second move, we move the 1st character 'b' to the end, obtaining the final result "acb". ``` ``` Input: s = "baaca", k = 3 Output: "aaabc" Explanation: In the first move, we move the 1st character 'b' to the end, obtaining the string "aacab". In the second move, we move the 3rd character 'c' to the end, obtaining the final result "aaabc". ``` ### Constraints * `1 <= k <= s.length <= 1000` * `s` consist of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/orderly_queue/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/orderly_queue/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) for k == 1 (n rotations of length n), O(n log n) for k >= 2 # Space: O(n) for the rotation candidates def orderly_queue(self, s: str, k: int) -> str: if k == 1: return min(s[i:] + s[:i] for i in range(len(s))) return "".join(sorted(s)) ``` ## Complexity | Time | Space | | ------------------------------------------------------------------ | -------------------------------- | | O(n^2) for k == 1 (n rotations of length n), O(n log n) for k >= 2 | O(n) for the rotation candidates | ## Tags # Out of Boundary Paths Python Solution Source: https://leetcode-py.wisl.dev/problems/out-of-boundary-paths Tested Python solution for LeetCode 576 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 576, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/out-of-boundary-paths/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 576 # by problem number lcpy gen -s out_of_boundary_paths # by problem name ``` ## Problem There is an `m x n` grid with a ball. The ball is initially at the position `[startRow, startColumn]`. You are allowed to move the ball to one of the four adjacent cells in the grid (possibly out of the grid crossing the grid boundary). You can apply **at most** `maxMove` moves to the ball. Given the five integers `m`, `n`, `maxMove`, `startRow`, `startColumn`, return the number of paths to move the ball out of the grid boundary. Since the answer can be very large, return it **modulo** `10^9 + 7`. ### Examples  ``` Input: m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0 Output: 6 ```  ``` Input: m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1 Output: 12 ``` ### Constraints * 1 \<= m, n \<= 50 * 0 \<= maxMove \<= 50 * 0 \<= startRow \< m * 0 \<= startColumn \< n ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/out_of_boundary_paths/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/out_of_boundary_paths/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(max_move * m * n) # Space: O(m * n) def find_paths( self, m: int, n: int, max_move: int, start_row: int, start_column: int, ) -> int: mod = 1_000_000_007 # dp[r][c]: number of paths currently at cell (r, c) inside the grid. dp = [[0] * n for _ in range(m)] dp[start_row][start_column] = 1 paths = 0 for _ in range(max_move): nxt = [[0] * n for _ in range(m)] for row in range(m): for col in range(n): count = dp[row][col] if not count: continue for n_row, n_col in ( (row + 1, col), (row - 1, col), (row, col + 1), (row, col - 1), ): if 0 <= n_row < m and 0 <= n_col < n: nxt[n_row][n_col] = (nxt[n_row][n_col] + count) % mod else: paths = (paths + count) % mod dp = nxt return paths ``` ## Complexity | Time | Space | | ---------------------- | --------- | | O(max\_move \* m \* n) | O(m \* n) | ## Tags [NeetCode All](/catalog/neetcode). # Output Contest Matches Python Solution Source: https://leetcode-py.wisl.dev/problems/output-contest-matches Tested Python solution for LeetCode 544 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 544, [Medium](/catalog/medium). Topics: [Recursion](/catalog/topics/recursion), [String](/catalog/topics/string), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/output-contest-matches/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 544 # by problem number lcpy gen -s output_contest_matches # by problem name ``` ## Problem During the NBA playoffs, we always set the rather strong team to play with the rather weak team, like making the rank `1` team play with the rank `n`th team, which is a good strategy to make the contest more interesting. Given `n` teams, return their final contest matches in the form of a string. The `n` teams are labeled from `1` to `n`, which represents their initial rank (i.e., Rank `1` is the strongest team and Rank `n` is the weakest team). We will use parentheses `'('`, and `')'` and commas `','` to represent the contest team pairing. We use the parentheses for pairing and the commas for partition. During the pairing process in each round, you always need to follow the strategy of making the rather strong one pair with the rather weak one. ### Examples ``` Input: n = 4 Output: "((1,4),(2,3))" Explanation: In the first round, we pair the team 1 and 4, the teams 2 and 3 together, as we need to make the strong team and weak team together. And we got (1, 4),(2, 3). In the second round, the winners of (1, 4) and (2, 3) need to play again to generate the final winner, so you need to add the parentheses outside them. And we got the final answer ((1,4),(2,3)). ``` ``` Input: n = 8 Output: "(((1,8),(4,5)),((2,7),(3,6)))" Explanation: First round: (1, 8),(2, 7),(3, 6),(4, 5) Second round: ((1, 8),(4, 5)),((2, 7),(3, 6)) Third round: (((1, 8),(4, 5)),((2, 7),(3, 6))) Since the third round will generate the final winner, you need to output the answer (((1,8),(4,5)),((2,7),(3,6))). ``` ### Constraints * `n == 2^x` where `x` is in the range `[1, 12]`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/output_contest_matches/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/output_contest_matches/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) def find_contest_match(self, n: int) -> str: teams = [str(i + 1) for i in range(n)] while n > 1: for i in range(n >> 1): teams[i] = f"({teams[i]},{teams[n - i - 1]})" n >>= 1 return teams[0] ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags # Pacific Atlantic Water Flow Python Solution Source: https://leetcode-py.wisl.dev/problems/pacific-atlantic-water-flow Tested Python solution for LeetCode 417 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 417, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/pacific-atlantic-water-flow/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 417 # by problem number lcpy gen -s pacific_atlantic_water_flow # by problem name ``` ## Problem 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. The island is partitioned into a grid of square cells. You are given an `m x n` integer matrix `heights` where `heights[r][c]` represents the **height above sea level** of the cell at coordinate `(r, c)`. The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell's height is **less than or equal to** the current cell's height. Water can flow from any cell adjacent to an ocean into the ocean. Return *a **2D list** of grid coordinates* `result` *where* `result[i] = [ri, ci]` *denotes that rain water can flow from cell* `(ri, ci)` *to **both** the Pacific and Atlantic oceans*. ### Examples  ``` 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]] Output: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]] 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. ``` ``` Input: heights = [[1]] Output: [[0,0]] Explanation: The water can flow from the only cell to the Pacific and Atlantic oceans. ``` ### Constraints * `m == heights.length` * `n == heights[r].length` * `1 <= m, n <= 200` * `0 <= heights[r][c] <= 10^5` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pacific_atlantic_water_flow/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pacific_atlantic_water_flow/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(m * n) def pacific_atlantic(self, heights: list[list[int]]) -> list[list[int]]: if not heights or not heights[0]: return [] m, n = len(heights), len(heights[0]) pacific: set[tuple[int, int]] = set() atlantic: set[tuple[int, int]] = set() def dfs(r: int, c: int, visited: set) -> None: visited.add((r, c)) for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]: nr, nc = r + dr, c + dc if ( 0 <= nr < m and 0 <= nc < n and (nr, nc) not in visited and heights[nr][nc] >= heights[r][c] ): dfs(nr, nc, visited) # DFS from Pacific borders (top and left) for i in range(m): dfs(i, 0, pacific) for j in range(n): dfs(0, j, pacific) # DFS from Atlantic borders (bottom and right) for i in range(m): dfs(i, n - 1, atlantic) for j in range(n): dfs(m - 1, j, atlantic) return [[r, c] for r, c in pacific & atlantic] ``` ## Complexity | Time | Space | | --------- | --------- | | O(m \* n) | O(m \* n) | ## Tags [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Paint Fence Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/paint-fence Tested Python solution for LeetCode 276 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 276, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/paint-fence/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 276 # by problem number lcpy gen -s paint_fence # by problem name ``` ## Problem You are painting a fence of `n` posts with `k` different colors. You must paint the posts following these rules: * Every post must be painted **exactly one** color. * There **cannot** be three or more **consecutive** posts with the same color. Given the two integers `n` and `k`, return *the **number of ways** you can paint the fence*. ### Examples  ``` Input: n = 3, k = 2 Output: 6 Explanation: All the possibilities are shown. Note that painting all the posts red or all the posts green is invalid because there cannot be three posts in a row with the same color. ``` ``` Input: n = 1, k = 1 Output: 1 ``` ``` Input: n = 7, k = 2 Output: 42 ``` ### Constraints * `1 <= n <= 50` * `1 <= k <= 10^5` * The testcases are generated such that the answer is in the range `[0, 2^31 - 1]` for the given `n` and `k`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/paint_fence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/paint_fence/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def num_ways(self, n: int, k: int) -> int: if n == 1: return k same, diff = k, k * (k - 1) for _ in range(n - 2): same, diff = diff, (same + diff) * (k - 1) return same + diff ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Paint House Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/paint-house Tested Python solution for LeetCode 256 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 256, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/paint-house/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 256 # by problem number lcpy gen -s paint_house # by problem name ``` ## Problem There is a row of `n` houses, where each house can be painted one of three colors: red, blue, or green. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color. The cost of painting each house with a certain color is represented by an `n x 3` cost matrix `costs`. * For example, `costs[0][0]` is the cost of painting house `0` with the color red; `costs[1][2]` is the cost of painting house 1 with color green, and so on... Return *the minimum cost to paint all houses*. ### Examples ``` Input: costs = [[17,2,17],[16,16,5],[14,3,19]] Output: 10 Explanation: Paint house 0 into blue, paint house 1 into green, paint house 2 into blue. Minimum cost: 2 + 5 + 3 = 10. ``` ``` Input: costs = [[7,6,2]] Output: 2 ``` ### Constraints * `costs.length == n` * `costs[i].length == 3` * `1 <= n <= 100` * `1 <= costs[i][j] <= 20` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/paint_house/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/paint_house/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def min_cost(self, costs: list[list[int]]) -> int: red = blue = green = 0 for r, b, g in costs: red, blue, green = ( min(blue, green) + r, min(red, green) + b, min(red, blue) + g, ) return min(red, blue, green) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Paint House II Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/paint-house-ii Tested Python solution for LeetCode 265 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 265, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/paint-house-ii/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 265 # by problem number lcpy gen -s paint_house_ii # by problem name ``` ## Problem There are a row of `n` houses, each house can be painted with one of the `k` colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color. The cost of painting each house with a certain color is represented by an `n x k` cost matrix `costs`. * For example, `costs[0][0]` is the cost of painting house `0` with color `0`; `costs[1][2]` is the cost of painting house `1` with color `2`, and so on... Return *the minimum cost to paint all houses*. ### Examples ``` Input: costs = [[1,5,3],[2,9,4]] Output: 5 Explanation: Paint house 0 into color 0, paint house 1 into color 2. Minimum cost: 1 + 4 = 5; Or paint house 0 into color 2, paint house 1 into color 0. Minimum cost: 3 + 2 = 5. ``` ``` Input: costs = [[1,3],[2,4]] Output: 5 ``` ### Constraints * `costs.length == n` * `costs[i].length == k` * `1 <= n <= 100` * `2 <= k <= 20` * `1 <= costs[i][j] <= 20` **Follow up:** Could you solve it in `O(nk)` runtime? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/paint_house_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/paint_house_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(nk) # Space: O(k) def min_cost_ii(self, costs: list[list[int]]) -> int: best = costs[0][:] for house in costs[1:]: min1 = min(best) min1_idx = best.index(min1) min2 = min(value for idx, value in enumerate(best) if idx != min1_idx) best = [cost + (min2 if idx == min1_idx else min1) for idx, cost in enumerate(house)] return min(best) ``` ## Complexity | Time | Space | | ----- | ----- | | O(nk) | O(k) | ## Tags [NeetCode All](/catalog/neetcode). # Painting the Walls Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/painting-the-walls Tested Python solution for LeetCode 2742 with 19 pytest cases. Generate a practice environment with lcpy. LeetCode 2742, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/painting-the-walls/description/). Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2742 # by problem number lcpy gen -s painting_the_walls # by problem name ``` ## Problem You are given two **0-indexed** integer arrays, `cost` and `time`, of size `n` representing the costs and the time taken to paint `n` different walls respectively. There are two painters available: * A **paid painter** that paints the `ith` wall in `time[i]` units of time and takes `cost[i]` units of money. * A **free painter** that paints **any** wall in `1` unit of time at a cost of `0`. But the free painter can only be used if the paid painter is already **occupied**. Return *the minimum amount of money required to paint the `n` walls*. ### Examples ``` Input: cost = [1,2,3,2], time = [1,2,3,2] Output: 3 Explanation: The walls at index 0 and 1 will be painted by the paid painter, and it will take 3 units of time; meanwhile, the free painter will paint the walls at index 2 and 3, free of cost in 2 units of time. Thus, the total cost is 1 + 2 = 3. ``` ``` Input: cost = [2,3,4,2], time = [1,1,1,1] Output: 4 Explanation: The walls at index 0 and 3 will be painted by the paid painter, and it will take 2 units of time; meanwhile, the free painter will paint the walls at index 1 and 2, free of cost in 2 units of time. Thus, the total cost is 2 + 2 = 4. ``` ### Constraints * `1 <= cost.length <= 500` * `cost.length == time.length` * `1 <= cost[i] <= 10^6` * `1 <= time[i] <= 500` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/painting_the_walls/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/painting_the_walls/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n) def paint_walls(self, cost: list[int], time: list[int]) -> int: n = len(cost) # dp[j] = min cost of paid walls so the free painter can cover j walls; # a paid wall with time t covers itself plus t free walls. inf = 10**18 dp = [0] + [inf] * n for c, t in zip(cost, time, strict=True): for j in range(n, 0, -1): candidate = dp[max(0, j - t - 1)] + c if candidate < dp[j]: dp[j] = candidate return dp[n] ``` ## Complexity | Time | Space | | ------ | ----- | | O(n^2) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Palindrome Linked List Python Solution Source: https://leetcode-py.wisl.dev/problems/palindrome-linked-list Tested Python solution for LeetCode 234 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 234, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/palindrome-linked-list/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 234 # by problem number lcpy gen -s palindrome_linked_list # by problem name ``` ## Problem Given the `head` of a singly linked list, return `true` if it is a palindrome or `false` otherwise. ### Examples  ``` Input: head = [1,2,2,1] Output: true ```  ``` Input: head = [1,2] Output: false ``` ### Constraints * The number of nodes in the list is in the range \[1, 10^5]. * 0 \<= Node.val \<= 9 **Follow up:** Could you do it in `O(n)` time and `O(1)` space? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_linked_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) — find middle, reverse half, compare # Space: O(1) — in-place pointers def is_palindrome(self, head: ListNode[int] | None) -> bool: if not head or not head.next: return True # Slow/fast to reach the middle (slow lands on start of second half) slow: ListNode[int] | None = head fast: ListNode[int] | None = head while fast and fast.next: assert slow is not None slow = slow.next fast = fast.next.next # Reverse the second half second_head = self._reverse(slow) # Compare both halves first: ListNode[int] | None = head second: ListNode[int] | None = second_head result = True while second: assert first is not None if first.val != second.val: result = False break first = first.next second = second.next return result @staticmethod def _reverse(head: ListNode[int] | None) -> ListNode[int] | None: prev: ListNode[int] | None = None current = head while current: nxt = current.next current.next = prev prev = current current = nxt return prev ``` ## Complexity | Time | Space | | ----------------------------------------- | ------------------------ | | O(n) — find middle, reverse half, compare | O(1) — in-place pointers | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Palindrome Number Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/palindrome-number Tested Python solution for LeetCode 9 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 9, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/palindrome-number/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 9 # by problem number lcpy gen -s palindrome_number # by problem name ``` ## Problem Given an integer `x`, return `true` if `x` is a **palindrome**, and `false` otherwise. ### Examples ``` Input: x = 121 Output: true Explanation: 121 reads as 121 from left to right and from right to left. ``` ``` Input: x = -121 Output: false Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome. ``` ``` Input: x = 10 Output: false Explanation: Reads 01 from right to left. Therefore it is not a palindrome. ``` ### Constraints * -2^31 \<= x \<= 2^31 - 1 **Follow up:** Could you solve it without converting the integer to a string? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_number/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log10(n)) - process half the digits # Space: O(1) def is_palindrome(self, x: int) -> bool: # Negative numbers and numbers ending in 0 (except 0 itself) are not palindromes if x < 0 or (x % 10 == 0 and x != 0): return False reversed_half = 0 while x > reversed_half: reversed_half = reversed_half * 10 + x % 10 x //= 10 # Even length: x == reversed_half # Odd length: x == reversed_half // 10 (drop middle digit) return x == reversed_half or x == reversed_half // 10 ``` ## Complexity | Time | Space | | ------------------------------------- | ----- | | O(log10(n)) - process half the digits | O(1) | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Palindrome Pairs Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/palindrome-pairs Tested Python solution for LeetCode 336 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 336, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/palindrome-pairs/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 336 # by problem number lcpy gen -s palindrome_pairs # by problem name ``` ## Problem You are given a **0-indexed** array of **unique** strings `words`. A **palindrome pair** is a pair of integers `(i, j)` such that: * `0 <= i, j < words.length`, * `i != j`, and * `words[i] + words[j]` (the concatenation of the two strings) is a palindrome. Return an array of all the palindrome pairs of `words`. You must write an algorithm with `O(sum of words[i].length)` runtime complexity. ### Examples ``` Input: words = ["abcd","dcba","lls","s","sssll"] Output: [[0,1],[1,0],[3,2],[2,4]] Explanation: The palindromes are ["abcddcba","dcbaabcd","slls","llssssll"] ``` ``` Input: words = ["bat","tab","cat"] Output: [[0,1],[1,0]] Explanation: The palindromes are ["battab","tabbat"] ``` ``` Input: words = ["a",""] Output: [[0,1],[1,0]] Explanation: The palindromes are ["a","a"] ``` ### Constraints * 1 \<= words.length \<= 5000 * 0 \<= words\[i].length \<= 300 * `words[i]` consists of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_pairs/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Hash map of reversed word -> index. For each word, split into prefix/suffix # at every cut. If prefix palindrome, reversed suffix in map -> pair (j, i). # If suffix palindrome, reversed prefix in map -> pair (i, j). Handle empty string. # Time: O(sum of words[i].length) # Space: O(sum of words[i].length) def palindrome_pairs(self, words: list[str]) -> list[list[int]]: word_to_index = {word: i for i, word in enumerate(words)} result: list[list[int]] = [] for i, word in enumerate(words): for j in range(len(word) + 1): prefix = word[:j] suffix = word[j:] # Reverse of prefix matches another word and current suffix is palindrome # -> that word + word forms palindrome: pair (other, i) if prefix == prefix[::-1]: back = suffix[::-1] if back != word and back in word_to_index: result.append([word_to_index[back], i]) # Reverse of suffix matches another word (not the full word itself) and # current prefix is palindrome -> word + that word: pair (i, other) if j != len(word) and suffix == suffix[::-1]: front = prefix[::-1] if front != word and front in word_to_index: result.append([i, word_to_index[front]]) return result ``` ## Complexity | Time | Space | | -------------------------- | -------------------------- | | O(sum of words\[i].length) | O(sum of words\[i].length) | ## Tags [Grind](/catalog/grind). # Palindrome Partitioning Python Solution Source: https://leetcode-py.wisl.dev/problems/palindrome-partitioning Tested Python solution for LeetCode 131 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 131, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/palindrome-partitioning/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 131 # by problem number lcpy gen -s palindrome_partitioning # by problem name ``` ## Problem Given a string `s`, partition `s` such that every substring of the partition is a **palindrome**. Return *all possible palindrome partitioning of `s`*. ### Examples ``` Input: s = "aab" Output: [["a","a","b"],["aa","b"]] ``` ``` Input: s = "a" Output: [["a"]] ``` ### Constraints * `1 <= s.length <= 16` * `s` contains only lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_partitioning/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_partitioning/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(N * 2^N) # Space: O(N) def partition(self, s: str) -> list[list[str]]: result: list[list[str]] = [] self._backtrack(s, 0, [], result) return result def _backtrack(self, s: str, start: int, path: list[str], result: list[list[str]]) -> None: if start == len(s): result.append(path[:]) return for end in range(start + 1, len(s) + 1): substring = s[start:end] if self._is_palindrome(substring): path.append(substring) self._backtrack(s, end, path, result) path.pop() def _is_palindrome(self, s: str) -> bool: return s == s[::-1] ``` ## Complexity | Time | Space | | ----------- | ----- | | O(N \* 2^N) | O(N) | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Palindrome Partitioning II Python Solution Source: https://leetcode-py.wisl.dev/problems/palindrome-partitioning-ii Tested Python solution for LeetCode 132 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 132, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/palindrome-partitioning-ii/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 132 # by problem number lcpy gen -s palindrome_partitioning_ii # by problem name ``` ## Problem Given a string `s`, partition `s` such that every substring of the partition is a **palindrome**. Return *the minimum cuts needed for a palindrome partitioning of `s`*. ### Examples ``` Input: s = "aab" Output: 1 Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut. ``` ``` Input: s = "a" Output: 0 ``` ``` Input: s = "ab" Output: 1 ``` ### Constraints * `1 <= s.length <= 2000` * `s` consists of lowercase English letters only. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_partitioning_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_partitioning_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n^2) def min_cut(self, s: str) -> int: n = len(s) is_pal = [[False] * n for _ in range(n)] cut = [0] * n for i in range(n): best = n for j in range(i + 1): if s[j] == s[i] and (i - j < 2 or is_pal[j + 1][i - 1]): is_pal[j][i] = True best = 0 if j == 0 else min(best, cut[j - 1] + 1) cut[i] = best return cut[n - 1] ``` ## Complexity | Time | Space | | ------ | ------ | | O(n^2) | O(n^2) | ## Tags # Palindrome Permutation Python Solution Source: https://leetcode-py.wisl.dev/problems/palindrome-permutation Tested Python solution for LeetCode 266 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 266, [Easy](/catalog/easy). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/palindrome-permutation/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 266 # by problem number lcpy gen -s palindrome_permutation # by problem name ``` ## Problem Given a string `s`, return `true` *if a permutation of the string could form a **palindrome** and* `false` *otherwise*. ### Examples ``` Input: s = "code" Output: false ``` ``` Input: s = "aab" Output: true ``` ``` Input: s = "carerac" Output: true ``` ### Constraints * `1 <= s.length <= 5000` * `s` consists of only lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_permutation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_permutation/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n) # Space: O(1) for the 26-letter alphabet def can_permute_palindrome(self, s: str) -> bool: counts = Counter(s) return sum(count % 2 for count in counts.values()) < 2 ``` ## Complexity | Time | Space | | ---- | ------------------------------- | | O(n) | O(1) for the 26-letter alphabet | ## Tags [NeetCode All](/catalog/neetcode). # Palindrome Permutation II Python Solution Source: https://leetcode-py.wisl.dev/problems/palindrome-permutation-ii Tested Python solution for LeetCode 267 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 267, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/palindrome-permutation-ii/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 267 # by problem number lcpy gen -s palindrome_permutation_ii # by problem name ``` ## Problem Given a string `s`, return *all the palindromic permutations (without duplicates) of it*. You may return the answer in **any order**. If `s` has no palindromic permutation, return an empty list. ### Examples ``` Input: s = "aabb" Output: ["abba","baab"] ``` ``` Input: s = "abc" Output: [] ``` ### Constraints * `1 <= s.length <= 16` * `s` consists of only lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_permutation_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_permutation_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n * (n/2)!) for generating each half permutation # Space: O(n) def generate_palindromes(self, s: str) -> list[str]: counts = Counter(s) mid = "" for char, count in counts.items(): if count % 2: if mid: return [] mid = char counts[char] -= 1 results: list[str] = [] def build(current: str) -> None: if all(value == 0 for value in counts.values()): results.append(current) return for char in counts: if counts[char] > 0: counts[char] -= 2 build(char + current + char) counts[char] += 2 build(mid) return results ``` ## Complexity | Time | Space | | --------------------------------------------------- | ----- | | O(n \* (n/2)!) for generating each half permutation | O(n) | ## Tags # Palindrome Removal Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/palindrome-removal Tested Python solution for LeetCode 1246 with 32 pytest cases. Generate a practice environment with lcpy. LeetCode 1246, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/palindrome-removal/description/). Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1246 # by problem number lcpy gen -s palindrome_removal # by problem name ``` ## Problem You are given an integer array `arr`. In one move, you can select a **palindromic** subarray `arr[i], arr[i + 1], ..., arr[j]` where `i <= j`, and remove that subarray from the given array. Note that after removing a subarray, the elements on the left and on the right of that subarray move to fill the gap left by the removal. Return the minimum number of moves needed to remove all numbers from the array. ### Examples ``` Input: arr = [1,2] Output: 2 ``` ``` Input: arr = [1,3,4,1,5] Output: 3 ``` **Explanation:** Remove `[4]` then remove `[1,3,1]` then remove `[5]`. ### Constraints * `1 <= arr.length <= 100` * `1 <= arr[i] <= 20` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_removal/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindrome_removal/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^3) # Space: O(n^2) def minimum_moves(self, arr: list[int]) -> int: n = len(arr) # dp[i][j] = minimum moves to clear arr[i..j] dp = [[0] * n for _ in range(n)] for i in range(n): dp[i][i] = 1 for i in range(n - 2, -1, -1): for j in range(i + 1, n): if i + 1 == j: dp[i][j] = 1 if arr[i] == arr[j] else 2 continue best = n if arr[i] == arr[j]: best = dp[i + 1][j - 1] for k in range(i, j): best = min(best, dp[i][k] + dp[k + 1][j]) dp[i][j] = best return dp[0][n - 1] ``` ## Complexity | Time | Space | | ------ | ------ | | O(n^3) | O(n^2) | ## Tags # Palindromic Substrings Python Solution Source: https://leetcode-py.wisl.dev/problems/palindromic-substrings Tested Python solution for LeetCode 647 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 647, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/palindromic-substrings/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 647 # by problem number lcpy gen -s palindromic_substrings # by problem name ``` ## Problem Given a string s, return the number of palindromic substrings in it. A string is a palindrome when it reads the same backward as forward. A substring is a contiguous sequence of characters within the string. ### Examples ``` Input: s = "abc" Output: 3 Explanation: Three palindromic strings: "a", "b", "c". ``` ``` Input: s = "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". ``` ### Constraints 1 \<= s.length \<= 1000 s consists of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindromic_substrings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/palindromic_substrings/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) - expand around centers approach # Space: O(1) - no extra space used def count_substrings(self, s: str) -> int: """ Count palindromic substrings using expand around centers approach. For each possible center (single char or between two chars), expand outward and count palindromes. """ if not s: return 0 count = 0 n = len(s) for i in range(n): # Odd length palindromes (center at i) count += self._expand_around_center(s, i, i) # Even length palindromes (center between i and i+1) count += self._expand_around_center(s, i, i + 1) return count def _expand_around_center(self, s: str, left: int, right: int) -> int: """Expand around center and count palindromes.""" count = 0 while left >= 0 and right < len(s) and s[left] == s[right]: count += 1 left -= 1 right += 1 return count ``` ## Complexity | Time | Space | | --------------------------------------- | -------------------------- | | O(n^2) - expand around centers approach | O(1) - no extra space used | ## Tags [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Pancake Sorting Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/pancake-sorting Tested Python solution for LeetCode 969 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 969, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/pancake-sorting/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 969 # by problem number lcpy gen -s pancake_sorting # by problem name ``` ## Problem Given an array of integers `arr`, sort the array by performing a series of **pancake flips**. In one pancake flip we do the following steps: * Choose an integer `k` where `1 <= k <= arr.length`. * Reverse the sub-array `arr[0...k-1]` (0-indexed). For example, if `arr = [3,2,1,4]` and we performed a pancake flip choosing `k = 3`, we reverse the sub-array `[3,2,1]`, so `arr = [1,2,3,4]` after the pancake flip at `k = 3`. Return an array of the `k`-values corresponding to a sequence of pancake flips that sort `arr`. Any valid answer that sorts the array within `10 * arr.length` flips will be judged as correct. ### Examples ``` Input: arr = [3,2,4,1] Output: [4,2,4,3] Explanation: We perform 4 pancake flips, with k values 4, 2, 4, and 3. Starting state: arr = [3, 2, 4, 1] After 1st flip (k = 4): arr = [1, 4, 2, 3] After 2nd flip (k = 2): arr = [4, 1, 2, 3] After 3rd flip (k = 4): arr = [3, 2, 1, 4] After 4th flip (k = 3): arr = [1, 2, 3, 4], which is sorted. ``` ``` Input: arr = [1,2,3] Output: [] Explanation: The input is already sorted, so there is no need to flip anything. Note that other answers, such as [3, 3], would also be accepted. ``` ### Constraints * `1 <= arr.length <= 100` * `1 <= arr[i] <= arr.length` * All integers in `arr` are **unique** (i.e. `arr` is a permutation of the integers from `1` to `arr.length`). ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pancake_sorting/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pancake_sorting/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n) for the working copy def pancake_sort(self, arr: list[int]) -> list[int]: result: list[int] = [] work = list(arr) for target in range(len(work), 1, -1): idx = work.index(target) if idx == target - 1: continue if idx != 0: result.append(idx + 1) work[: idx + 1] = work[idx::-1] result.append(target) work[:target] = work[target - 1 :: -1] return result ``` ## Complexity | Time | Space | | ------ | ------------------------- | | O(n^2) | O(n) for the working copy | ## Tags # Parallel Courses Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/parallel-courses Tested Python solution for LeetCode 1136 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 1136, [Medium](/catalog/medium). Topics: [Graph](/catalog/topics/graph), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/parallel-courses/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1136 # by problem number lcpy gen -s parallel_courses # by problem name ``` ## Problem You are given an integer `n`, which indicates that there are `n` courses labeled from `1` to `n`. You are also given an array `relations` where `relations[i] = [prevCourse_i, nextCourse_i]`, representing a prerequisite relationship between course `prevCourse_i` and course `nextCourse_i`: course `prevCourse_i` has to be taken before course `nextCourse_i`. In one semester, you can take **any number** of courses as long as you have taken all the prerequisites in the **previous** semester for the courses you are taking. Return *the **minimum** number of semesters needed to take all courses*. If there is no way to take all the courses, return `-1`. ### Examples  ``` Input: n = 3, relations = [[1,3],[2,3]] Output: 2 ``` **Explanation:** In the first semester, you can take courses 1 and 2. In the second semester, you can take course 3.  ``` Input: n = 3, relations = [[1,2],[2,3],[3,1]] Output: -1 ``` **Explanation:** No course can be studied because they are prerequisites of each other. ### Constraints * `1 <= n <= 5000` * `1 <= relations.length <= 5000` * `relations[i].length == 2` * `1 <= prevCourse_i, nextCourse_i <= n` * `prevCourse_i != nextCourse_i` * All the pairs `[prevCourse_i, nextCourse_i]` are **unique**. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parallel_courses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parallel_courses/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(n + m) # Space: O(n + m) def minimum_semesters(self, n: int, relations: list[list[int]]) -> int: graph: list[list[int]] = [[] for _ in range(n)] indegree = [0] * n for prev_course, next_course in relations: graph[prev_course - 1].append(next_course - 1) indegree[next_course - 1] += 1 queue: deque[int] = deque(i for i in range(n) if indegree[i] == 0) semesters = 0 taken = 0 while queue: semesters += 1 for _ in range(len(queue)): course = queue.popleft() taken += 1 for nxt in graph[course]: indegree[nxt] -= 1 if indegree[nxt] == 0: queue.append(nxt) return semesters if taken == n else -1 ``` ## Complexity | Time | Space | | -------- | -------- | | O(n + m) | O(n + m) | ## Tags [NeetCode All](/catalog/neetcode). # Parallel Courses III Python Solution Source: https://leetcode-py.wisl.dev/problems/parallel-courses-iii Tested Python solution for LeetCode 2050 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 2050, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Graph Theory](/catalog/topics/graph-theory), [Topological Sort](/catalog/topics/topological-sort), Directed Acyclic Graph. [View on LeetCode](https://leetcode.com/problems/parallel-courses-iii/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2050 # by problem number lcpy gen -s parallel_courses_iii # by problem name ``` ## Problem You are given an integer `n`, which indicates that there are `n` courses labeled from `1` to `n`. You are also given a 2D integer array `relations` where `relations[j] = [prevCourse_j, nextCourse_j]` denotes that course `prevCourse_j` has to be completed **before** course `nextCourse_j` (prerequisite relationship). Furthermore, you are given a **0-indexed** integer array `time` where `time[i]` denotes how many **months** it takes to complete the `(i+1)th` course. You must find the **minimum** number of months needed to complete all the courses following these rules: * You may start taking a course at **any time** if the prerequisites are met. * **Any number of courses** can be taken at the **same time**. Return *the **minimum** number of months needed to complete all the courses*. **Note:** The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph). ### Examples  ``` Input: n = 3, relations = [[1,3],[2,3]], time = [3,2,5] Output: 8 ``` **Explanation:** We start course 1 and course 2 simultaneously at month 0. Course 1 takes 3 months and course 2 takes 2 months to complete respectively. Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.  ``` Input: n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5] Output: 12 ``` **Explanation:** Courses 1, 2 and 3 run in parallel and finish after 1, 2 and 3 months. Course 4 starts after course 3 and finishes at month 7. Course 5 starts at month 7 and finishes at month 12. ### Constraints * `1 <= n <= 5 * 10^4` * `0 <= relations.length <= min(n * (n - 1) / 2, 5 * 10^4)` * `relations[j].length == 2` * `1 <= prevCourse_j, nextCourse_j <= n` * `prevCourse_j != nextCourse_j` * All the pairs `[prevCourse_j, nextCourse_j]` are **unique**. * `time.length == n` * `1 <= time[i] <= 10^4` * The given graph is a directed acyclic graph. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parallel_courses_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parallel_courses_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(n + e) # Space: O(n + e) def minimum_time(self, n: int, relations: list[list[int]], time: list[int]) -> int: adj: list[list[int]] = [[] for _ in range(n + 1)] indegree = [0] * (n + 1) for prev_course, next_course in relations: adj[prev_course].append(next_course) indegree[next_course] += 1 finish = [0] * (n + 1) queue: deque[int] = deque() for course in range(1, n + 1): if indegree[course] == 0: finish[course] = time[course - 1] queue.append(course) while queue: course = queue.popleft() for nxt in adj[course]: finish[nxt] = max(finish[nxt], finish[course] + time[nxt - 1]) indegree[nxt] -= 1 if indegree[nxt] == 0: queue.append(nxt) return max(finish) ``` ## Complexity | Time | Space | | -------- | -------- | | O(n + e) | O(n + e) | ## Tags [NeetCode All](/catalog/neetcode). # Parse Lisp Expression Python Solution Source: https://leetcode-py.wisl.dev/problems/parse-lisp-expression Tested Python solution for LeetCode 736 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 736, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/parse-lisp-expression/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 736 # by problem number lcpy gen -s parse_lisp_expression # by problem name ``` ## Problem You are given a string expression representing a Lisp-like expression to return the integer value of. The syntax for these expressions is given as follows. * An expression is either an integer, let expression, add expression, mult expression, or an assigned variable. Expressions always evaluate to a single integer. (An integer could be positive or negative.) * A let expression takes the form `(let v1 e1 v2 e2 ... vn en expr)`, where let is always the string `"let"`, then there are one or more pairs of alternating variables and expressions, meaning that the first variable v1 is assigned the value of the expression e1, the second variable v2 is assigned the value of the expression e2, and so on sequentially; and then the value of this let expression is the value of the expression expr. * An add expression takes the form `(add e1 e2)` where add is always the string `"add"`, there are always two expressions e1, e2 and the result is the addition of the evaluation of e1 and the evaluation of e2. * A mult expression takes the form `(mult e1 e2)` where mult is always the string `"mult"`, there are always two expressions e1, e2 and the result is the multiplication of the evaluation of e1 and the evaluation of e2. * For this question, we will use a smaller subset of variable names. A variable starts with a lowercase letter, then zero or more lowercase letters or digits. Additionally, for your convenience, the names `"add"`, `"let"`, and `"mult"` are protected and will never be used as variable names. * Finally, there is the concept of scope. When an expression of a variable name is evaluated, within the context of that evaluation, the innermost scope (in terms of parentheses) is checked first for the value of that variable, and then outer scopes are checked sequentially. It is guaranteed that every expression is legal. Please see the examples for more details on the scope. ### Examples ``` Input: expression = "(let x 2 (mult x (let x 3 y 4 (add x y))))" Output: 14 ``` **Explanation:** In the expression (add x y), when checking for the value of the variable x, we check from the innermost scope to the outermost in the context of the variable we are trying to evaluate. Since x = 3 is found first, the value of x is 3. ``` Input: expression = "(let x 3 x 2 x)" Output: 2 ``` **Explanation:** Assignment in let statements is processed sequentially. ``` Input: expression = "(let x 1 y 2 x (add x y) (add x y))" Output: 5 ``` **Explanation:** The first (add x y) evaluates as 3, and is assigned to x. The second (add x y) evaluates as 3+2 = 5. ### Constraints * 1 \<= expression.length \<= 2000 * There are no leading or trailing spaces in expression. * All tokens are separated by a single space in expression. * The answer and all intermediate calculations of that answer are guaranteed to fit in a 32-bit integer. * The expression is guaranteed to be legal and evaluate to an integer. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parse_lisp_expression/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parse_lisp_expression/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n), each token is consumed exactly once # Space: O(n), recursion depth plus scope frames def evaluate(self, expression: str) -> int: tokens = expression.replace("(", " ( ").replace(")", " ) ").split() def group_end(p: int) -> int: if tokens[p] != "(": return p + 1 depth = 0 while p < len(tokens): if tokens[p] == "(": depth += 1 elif tokens[p] == ")": depth -= 1 if depth == 0: return p + 1 p += 1 raise ValueError("unbalanced parentheses") def lookup(name: str, scope: list[dict[str, int]]) -> int: for frame in reversed(scope): if name in frame: return frame[name] raise ValueError(f"unbound variable: {name}") def parse(p: int, scope: list[dict[str, int]]) -> tuple[int, int]: tok = tokens[p] if tok == "(": close = group_end(p) - 1 keyword = tokens[p + 1] if keyword == "let": scope.append({}) q = p + 2 while group_end(q) != close: name = tokens[q] value, q = parse(q + 1, scope) scope[-1][name] = value value, q = parse(q, scope) scope.pop() return value, close + 1 a, q = parse(p + 2, scope) b, q = parse(q, scope) return (a + b if keyword == "add" else a * b), close + 1 if tok == ")": raise ValueError("unexpected )") if tok[0].isdigit() or tok[0] == "-": return int(tok), p + 1 return lookup(tok, scope), p + 1 value, _ = parse(0, []) return value ``` ## Complexity | Time | Space | | ----------------------------------------- | --------------------------------------- | | O(n), each token is consumed exactly once | O(n), recursion depth plus scope frames | ## Tags # Parsing A Boolean Expression Python Solution Source: https://leetcode-py.wisl.dev/problems/parsing-a-boolean-expression Tested Python solution for LeetCode 1106 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 1106, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/parsing-a-boolean-expression/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1106 # by problem number lcpy gen -s parsing_a_boolean_expression # by problem name ``` ## Problem A \boolean expression\ is an expression that evaluates to either \true\ or \false\. It can be in one of the following shapes:
* \'t'\ that evaluates to \true\.
* \'f'\ that evaluates to \false\.
* \'!(subExpr)'\ that evaluates to \the logical NOT\ of the inner expression \subExpr\.
* \'&(subExpr\1\, subExpr\2\, ..., subExpr\n\)'\ that evaluates to \the logical AND\ of the inner expressions \subExpr\1\, subExpr\2\, ..., subExpr\n\\ where \n >= 1\.
* \'|(subExpr\1\, subExpr\2\, ..., subExpr\n\)'\ that evaluates to \the logical OR\ of the inner expressions \subExpr\1\, subExpr\2\, ..., subExpr\n\\ where \n >= 1\.
Given a string \expression\ that represents a \boolean expression\, return \the evaluation of that expression\.
It is \guaranteed\ that the given expression is valid and follows the given rules.
### Examples
```
Input: expression = "&(|(f))"
Output: false
Explanation: First, evaluate |(f) --> f. The expression is now "&(f)". Then, evaluate &(f) --> f. The expression is now "f". Finally, return false.
```
```
Input: expression = "|(f,f,f,t)"
Output: true
Explanation: The evaluation of (false OR false OR false OR true) is true.
```
```
Input: expression = "!(&(f,t))"
Output: true
Explanation: First, evaluate &(f,t) --> (false AND true) --> false --> f. The expression is now "!(f)". Then, evaluate !(f) --> NOT false --> true. We return true.
```
### Constraints
* \1 \<= expression.length \<= 2 \* 10\4\\
* \expression\[i]\ is one following characters: \'('\, \')'\, \'&'\, \'|'\, \'!'\, \'t'\, \'f'\, and \','\.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parsing_a_boolean_expression/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/parsing_a_boolean_expression/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def parse_bool_expr(self, expression: str) -> bool:
stack: list[str] = []
for ch in expression:
if ch == ",":
continue
if ch != ")":
stack.append(ch)
continue
seen: list[bool] = []
while stack[-1] in ("t", "f"):
seen.append(stack.pop() == "t")
stack.pop()
op = stack.pop()
if op == "!":
stack.append("t" if not seen[0] else "f")
elif op == "&":
stack.append("t" if all(seen) else "f")
else:
stack.append("t" if any(seen) else "f")
return stack[-1] == "t"
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Partition Array According to Given Pivot
Source: https://leetcode-py.wisl.dev/problems/partition-array-according-to-given-pivot
Tested Python solution for LeetCode 2161 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2161, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/partition-array-according-to-given-pivot/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2161 # by problem number
lcpy gen -s partition_array_according_to_given_pivot # by problem name
```
## Problem
You are given a **0-indexed** integer array `nums` and an integer `pivot`. Rearrange `nums` such that the following conditions are satisfied:
* Every element less than `pivot` appears **before** every element greater than `pivot`.
* Every element equal to `pivot` appears **in between** the elements less than and greater than `pivot`.
* The **relative order** of the elements less than `pivot` and the elements greater than `pivot` is maintained. More formally, consider every `p_i`, `p_j` where `p_i` is the new position of the `i`th element and `p_j` is the new position of the `j`th element. If `i < j` and **both** elements are smaller (or larger) than `pivot`, then `p_i < p_j`.
Return `nums`\* after the rearrangement.\*
### Examples
```
Input: nums = [9,12,5,10,14,3,10], pivot = 10
Output: [9,5,3,10,10,12,14]
Explanation: The elements 9, 5, and 3 are less than the pivot so they are on the left side of the array. The elements 12 and 14 are greater than the pivot so they are on the right side of the array. The relative ordering of the elements less than and greater than pivot is also maintained. [9, 5, 3] and [12, 14] are the respective orderings.
```
```
Input: nums = [-3,4,3,2], pivot = 2
Output: [-3,2,4,3]
Explanation: The element -3 is less than the pivot so it is on the left side of the array. The elements 4 and 3 are greater than the pivot so they are on the right side of the array. The relative ordering of the elements less than and greater than pivot is also maintained. [-3] and [4, 3] are the respective orderings.
```
### Constraints
* `1 <= nums.length <= 10^5`
* `-10^6 <= nums[i] <= 10^6`
* `pivot` equals to an element of `nums`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_array_according_to_given_pivot/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_array_according_to_given_pivot/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def pivot_array(self, nums: list[int], pivot: int) -> list[int]:
less: list[int] = []
equal: list[int] = []
greater: list[int] = []
for num in nums:
if num < pivot:
less.append(num)
elif num > pivot:
greater.append(num)
else:
equal.append(num)
return [*less, *equal, *greater]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Partition Array for Maximum Sum
Source: https://leetcode-py.wisl.dev/problems/partition-array-for-maximum-sum
Tested Python solution for LeetCode 1043 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1043, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/partition-array-for-maximum-sum/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1043 # by problem number
lcpy gen -s partition_array_for_maximum_sum # by problem name
```
## Problem
Given an integer array `arr`, partition the array into (contiguous) subarrays of length **at most** `k`. After partitioning, each subarray has their values changed to become the maximum value of that subarray.
Return *the largest sum of the given array after partitioning*. Test cases are generated so that the answer fits in a **32-bit** integer.
### Examples
```
Input: arr = [1,15,7,9,2,5,10], k = 3
Output: 84
Explanation: arr becomes [15,15,15,9,10,10,10]
```
```
Input: arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
Output: 83
```
```
Input: arr = [1], k = 1
Output: 1
```
### Constraints
* `1 <= arr.length <= 500`
* `0 <= arr[i] <= 10^9`
* `1 <= k <= arr.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_array_for_maximum_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_array_for_maximum_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * k)
# Space: O(n)
def max_sum_after_partitioning(self, arr: list[int], k: int) -> int:
n = len(arr)
dp = [0] * (n + 1)
for i in range(1, n + 1):
best = 0
mx = 0
for length in range(1, min(k, i) + 1):
mx = max(mx, arr[i - length])
best = max(best, dp[i - length] + mx * length)
dp[i] = best
return dp[n]
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(n \* k) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Partition Array into Disjoint Intervals
Source: https://leetcode-py.wisl.dev/problems/partition-array-into-disjoint-intervals
Tested Python solution for LeetCode 915 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 915, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/partition-array-into-disjoint-intervals/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 915 # by problem number
lcpy gen -s partition_array_into_disjoint_intervals # by problem name
```
## Problem
\Given an integer array \nums\, partition it into two (contiguous) subarrays \left\ and \right\ so that:\
left\ is less than or equal to every element in \right\.\left\ and \right\ are non-empty.\left\ has the smallest possible size.\Return \the length of \\left\\ after such a partitioning\.\
Test cases are generated such that partitioning exists.\
### Examples ``` Input: nums = [5,0,3,8,6] Output: 3 Explanation: left = [5,0,3], right = [8,6] ``` ``` Input: nums = [1,1,1,0,6,12] Output: 4 Explanation: left = [1,1,1,0], right = [6,12] ``` ### Constraints * 2 \<= nums.length \<= 10^5 * 0 \<= nums\[i] \<= 10^6 * There is at least one valid answer for the given input. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_array_into_disjoint_intervals/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_array_into_disjoint_intervals/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def partition_disjoint(self, nums: list[int]) -> int: length = 1 left_max = nums[0] cur_max = nums[0] for i in range(1, len(nums)): cur_max = max(cur_max, nums[i]) if nums[i] < left_max: left_max = cur_max length = i + 1 return length ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Partition Equal Subset Sum Python Solution Source: https://leetcode-py.wisl.dev/problems/partition-equal-subset-sum Tested Python solution for LeetCode 416 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 416, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/partition-equal-subset-sum/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 416 # by problem number lcpy gen -s partition_equal_subset_sum # by problem name ``` ## Problem Given an integer array `nums`, return `true` if you can partition the array into two subsets such that the sum of the elements in both subsets is equal or `false` otherwise. ### Examples ``` Input: nums = [1,5,11,5] Output: true ``` **Explanation:** The array can be partitioned as \[1, 5, 5] and \[11]. ``` Input: nums = [1,2,3,5] Output: false ``` **Explanation:** The array cannot be partitioned into equal sum subsets. ### Constraints * 1 \<= nums.length \<= 200 * 1 \<= nums\[i] \<= 100 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_equal_subset_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_equal_subset_sum/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n * sum) # Space: O(sum) def can_partition(self, nums: list[int]) -> bool: """ Example: nums = [1, 5, 11, 5], target = 11 Initial: dp = [T, F, F, F, F, F, F, F, F, F, F, F] 0 1 2 3 4 5 6 7 8 9 10 11 After num=1: [T, T, F, F, F, F, F, F, F, F, F, F] └─┘ (can make sum 1) After num=5: [T, T, F, F, F, T, T, F, F, F, F, F] └─┘ └─┘ └─┘ (can make sums 5,6) After num=11:[T, T, F, F, F, T, T, F, F, F, F, T] └─┘ (target!) Backward iteration prevents using same number twice """ total = sum(nums) if total % 2: return False target = total // 2 dp = [False] * (target + 1) dp[0] = True for num in nums: for j in range(target, num - 1, -1): dp[j] = dp[j] or dp[j - num] # Early termination: found target sum! if dp[target]: return True return False class SolutionBitset: # Time: O(n * sum) # Space: O(1) def can_partition(self, nums: list[int]) -> bool: """ Example: nums = [1, 5, 11, 5], target = 11 Bitset representation (bit position = achievable sum): Initial: dp = 1 (binary: 1) Bits: ...0001 Sums: {0} After num=1: dp |= dp << 1 a = dp = 1 (bin: 0001) b = dp << 1 = 2 (bin: 0010) c = a | b = 3 (bin: 0011) Sums: {0, 1} After num=5: dp |= dp << 5 a = dp = 3 (bin: 0000011) b = dp << 5 = 96 (bin: 1100000) c = a | b = 99 (bin: 1100011) Sums: {0, 1, 5, 6} After num=11: dp |= dp << 11 a = dp = 99 (bin: 00000001100011) b = dp << 11 = 202752 (bin: 110001100000000) c = a | b = 202851 (bin: 110001101100011) Sums: {0, 1, 5, 6, 11, 12, 16, 17} Check: (dp & (1 << 11)) != 0 a = dp = 202851 (bin: 110001101100011) b = 1 << 11 = 2048 (bin: 100000000000) c = a & b = 2048 (bin: 100000000000) c != 0 → bit 11 is set → True! """ total = sum(nums) if total % 2 != 0: return False target = total // 2 dp = 1 for num in nums: dp |= dp << num # Early termination: found target sum! if (dp & (1 << target)) != 0: return True return False ``` ## Complexity | Time | Space | | ----------- | ------ | | O(n \* sum) | O(sum) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Partition Labels Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/partition-labels Tested Python solution for LeetCode 763 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 763, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/partition-labels/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 763 # by problem number lcpy gen -s partition_labels # by problem name ``` ## Problem You are given a string `s`. We want to partition the string into as many parts as possible so that each letter appears in at most one part. For example, the string `"ababcc"` can be partitioned into `["abab", "cc"]`, but partitions such as `["aba", "bcc"]` or `["ab", "ab", "cc"]` are invalid. Note that the partition is done so that after concatenating all the parts in order, the resultant string should be `s`. Return *a list of integers representing the size of these parts*. ### Examples ``` Input: s = "ababcbacadefegdehijhklij" Output: [9,7,8] Explanation: The partition is "ababcbaca", "defegde", "hijhklij". This is a partition so that each letter appears in at most one part. A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits s into less parts. ``` ``` Input: s = "eccbbbbdec" Output: [10] ``` ### Constraints * 1 \<= s.length \<= 500 * s consists of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_labels/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_labels/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) — alphabet bounded to 26 def partition_labels(self, s: str) -> list[int]: last_occurrence: dict[str, int] = {char: idx for idx, char in enumerate(s)} partitions: list[int] = [] start, end = 0, 0 for idx, char in enumerate(s): end = max(end, last_occurrence[char]) if idx == end: partitions.append(idx - start + 1) start = idx + 1 return partitions ``` ## Complexity | Time | Space | | ---- | ----------------------------- | | O(n) | O(1) — alphabet bounded to 26 | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Partition List Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/partition-list Tested Python solution for LeetCode 86 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 86, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/partition-list/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 86 # by problem number lcpy gen -s partition_list # by problem name ``` ## Problem Given the `head` of a linked list and a value `x`, partition it such that all nodes **less than** `x` come before nodes **greater than or equal** to `x`. You should **preserve** the original relative order of the nodes in each of the two partitions. ### Examples  ``` Input: head = [1,4,3,2,5,2], x = 3 Output: [1,2,2,4,3,5] ``` ``` Input: head = [2,1], x = 2 Output: [1,2] ``` ### Constraints * The number of nodes in the list is in the range `[0, 200]`. * `-100 <= Node.val <= 100` * `-200 <= x <= 200` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) # Space: O(1) def partition(self, head: ListNode[int] | None, x: int) -> ListNode[int] | None: before_head = before = ListNode[int](0) after_head = after = ListNode[int](0) current = head while current: if current.val < x: before.next = current before = before.next else: after.next = current after = after.next current = current.next after.next = None before.next = after_head.next return before_head.next ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Partition to K Equal Sum Subsets Source: https://leetcode-py.wisl.dev/problems/partition-to-k-equal-sum-subsets Tested Python solution for LeetCode 698 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 698, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Memoization](/catalog/topics/memoization), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 698 # by problem number lcpy gen -s partition_to_k_equal_sum_subsets # by problem name ``` ## Problem Given an integer array `nums` and an integer `k`, return `true` if it is possible to divide this array into `k` non-empty subsets whose sums are all equal. ### Examples ``` Input: nums = [4,3,2,3,5,2,1], k = 4 Output: true Explanation: It is possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums. ``` ``` Input: nums = [1,2,3,4], k = 3 Output: false ``` ### Constraints * 1 \<= k \<= nums.length \<= 16 * 1 \<= nums\[i] \<= 10^4 * The frequency of each element is in the range \[1, 4]. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_to_k_equal_sum_subsets/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/partition_to_k_equal_sum_subsets/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(k * 2^n) # Space: O(n) def can_partition_k_subsets(self, nums: list[int], k: int) -> bool: total = sum(nums) if total % k != 0: return False target = total // k nums.sort(reverse=True) if nums[0] > target: return False buckets = [0] * k def backtrack(index: int) -> bool: if index == len(nums): return True for bucket_index in range(k): if buckets[bucket_index] + nums[index] <= target: buckets[bucket_index] += nums[index] if backtrack(index + 1): return True buckets[bucket_index] -= nums[index] # Prune: empty bucket means placement here is symmetric to any # other empty bucket; also a just-filled bucket that failed. if buckets[bucket_index] == 0: break return False return backtrack(0) ``` ## Complexity | Time | Space | | ----------- | ----- | | O(k \* 2^n) | O(n) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Pascal's Triangle Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/pascals-triangle Tested Python solution for LeetCode 118 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 118, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/pascals-triangle/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 118 # by problem number lcpy gen -s pascals_triangle # by problem name ``` ## Problem Given an integer `numRows`, return the first numRows of **Pascal's triangle**. In **Pascal's triangle**, each number is the sum of the two numbers directly above it as shown:  ### Examples ``` Input: numRows = 5 Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ``` ``` Input: numRows = 1 Output: [[1]] ``` ### Constraints * 1 \<= numRows \<= 30 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pascals_triangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pascals_triangle/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(1) excluding output def generate(self, num_rows: int) -> list[list[int]]: triangle: list[list[int]] = [[1]] for _ in range(1, num_rows): previous = triangle[-1] row = [1] + [previous[i] + previous[i + 1] for i in range(len(previous) - 1)] + [1] triangle.append(row) return triangle ``` ## Complexity | Time | Space | | ------ | --------------------- | | O(n^2) | O(1) excluding output | ## Tags [NeetCode All](/catalog/neetcode). # Pascal's Triangle II Python Solution Source: https://leetcode-py.wisl.dev/problems/pascals-triangle-ii Tested Python solution for LeetCode 119 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 119, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/pascals-triangle-ii/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 119 # by problem number lcpy gen -s pascals_triangle_ii # by problem name ``` ## Problem Given an integer `rowIndex`, return the `rowIndexth` (**0-indexed**) row of the **Pascal's triangle**. In **Pascal's triangle**, each number is the sum of the two numbers directly above it as shown:  ### Examples ``` Input: rowIndex = 3 Output: [1,3,3,1] ``` ``` Input: rowIndex = 0 Output: [1] ``` ``` Input: rowIndex = 1 Output: [1,1] ``` ### Constraints * 0 \<= rowIndex \<= 33 **Follow up:** Could you optimize your algorithm to use only `O(rowIndex)` extra space? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pascals_triangle_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pascals_triangle_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(n) def get_row(self, row_index: int) -> list[int]: row = [1] for _ in range(row_index): row.append(1) for i in range(len(row) - 2, 0, -1): row[i] += row[i - 1] return row ``` ## Complexity | Time | Space | | ------ | ----- | | O(n^2) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Patching Array Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/patching-array Tested Python solution for LeetCode 330 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 330, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/patching-array/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 330 # by problem number lcpy gen -s patching_array # by problem name ``` ## Problem Given a sorted integer array \nums\ and an integer \n\, add/patch elements to the array such that any number in the range \\[1, n]\ inclusive can be formed by the sum of some elements in the array.
Return \the minimum number of patches required\.
### Examples
```
Input: nums = [1,3], n = 6
Output: 1
Explanation:
Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4.
Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3].
Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].
So we only need 1 patch.
```
```
Input: nums = [1,5,10], n = 20
Output: 2
Explanation: The two patches can be [2, 4].
```
```
Input: nums = [1,2,2], n = 5
Output: 0
```
### Constraints
* 1 \<= nums.length \<= 1000
* 1 \<= nums\[i] \<= 10^4
* nums is sorted in ascending order.
* 1 \<= n \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/patching_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/patching_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(nums) + log n)
# Space: O(1)
def min_patches(self, nums: list[int], n: int) -> int:
patches = 0
miss = 1 # smallest sum in [1, miss) that cannot be formed yet
i = 0
while miss <= n:
if i < len(nums) and nums[i] <= miss:
miss += nums[i]
i += 1
else:
patches += 1
miss += miss
return patches
```
## Complexity
| Time | Space |
| -------------------- | ----- |
| O(len(nums) + log n) | O(1) |
## Tags
# Path Crossing Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/path-crossing
Tested Python solution for LeetCode 1496 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1496, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/path-crossing/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1496 # by problem number
lcpy gen -s path_crossing # by problem name
```
## Problem
Given a string `path`, where `path[i] = 'N'`, `'S'`, `'E'` or `'W'`, each representing moving one unit north, south, east, or west, respectively. You start at the origin `(0, 0)` on a 2D plane and walk on the path specified by `path`.
Return `true` if the path crosses itself at any point, that is, if at any time you are on a location you have previously visited. Return `false` otherwise.
### Examples

```
Input: path = "NES"
Output: false
Explanation: Notice that the path doesn't cross any point more than once.
```

```
Input: path = "NESWW"
Output: true
Explanation: Notice that the path visits the origin twice.
```
### Constraints
* 1 \<= path.length \<= 10^4
* path\[i] is either 'N', 'S', 'E', or 'W'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_crossing/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_crossing/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def is_path_crossing(self, path: str) -> bool:
x = y = 0
seen = {(0, 0)}
moves = {"N": (0, 1), "S": (0, -1), "E": (1, 0), "W": (-1, 0)}
for step in path:
dx, dy = moves[step]
x, y = x + dx, y + dy
if (x, y) in seen:
return True
seen.add((x, y))
return False
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Path Sum Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/path-sum
Tested Python solution for LeetCode 112 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 112, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/path-sum/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 112 # by problem number
lcpy gen -s path_sum # by problem name
```
## Problem
Given the `root` of a binary tree and an integer `targetSum`, return `true` if the tree has a **root-to-leaf** path such that adding up all the values along the path equals `targetSum`.
A **leaf** is a node with no children.
### Examples

```
Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
Output: true
Explanation: The root-to-leaf path with the target sum is shown.
```

```
Input: root = [1,2,3], targetSum = 5
Output: false
Explanation: There are two root-to-leaf paths in the tree:
(1 --> 2): The sum is 3.
(1 --> 3): The sum is 4.
There is no root-to-leaf path with sum = 5.
```
```
Input: root = [], targetSum = 0
Output: false
Explanation: Since the tree is empty, there are no root-to-leaf paths.
```
### Constraints
* The number of nodes in the tree is in the range \[0, 5000]
* -1000 \<= Node.val \<= 1000
* -1000 \<= targetSum \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def has_path_sum(self, root: TreeNode[int] | None, target_sum: int) -> bool:
if root is None:
return False
remaining = target_sum - root.val
if root.left is None and root.right is None:
return remaining == 0
return self.has_path_sum(root.left, remaining) or self.has_path_sum(root.right, remaining)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Path Sum II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/path-sum-ii
Tested Python solution for LeetCode 113 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 113, [Medium](/catalog/medium). Topics: [Backtracking](/catalog/topics/backtracking), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/path-sum-ii/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 113 # by problem number
lcpy gen -s path_sum_ii # by problem name
```
## Problem
Given the `root` of a binary tree and an integer `targetSum`, return all **root-to-leaf** paths where the sum of the node values in the path equals `targetSum`. Each path should be returned as a list of the node **values**, not node references.
A **root-to-leaf** path is a path starting from the root and ending at any leaf node. A **leaf** is a node with no children.
### Examples

```
Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
Output: [[5,4,11,2],[5,8,4,5]]
Explanation: There are two paths whose sum equals targetSum:
5 + 4 + 11 + 2 = 22
5 + 8 + 4 + 5 = 22
```

```
Input: root = [1,2,3], targetSum = 5
Output: []
```
```
Input: root = [1,2], targetSum = 0
Output: []
```
### Constraints
* The number of nodes in the tree is in the range `[0, 5000]`.
* `-1000 <= Node.val <= 1000`
* `-1000 <= targetSum <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) - visit each node once
# Space: O(h) - recursion depth + path storage, where h is tree height
def path_sum(self, root: TreeNode[int] | None, target_sum: int) -> list[list[int]]:
result: list[list[int]] = []
def dfs(node: TreeNode[int] | None, remaining: int, path: list[int]) -> None:
if not node:
return
# Add current node to path
path.append(node.val)
# Check if leaf node with target sum
if not node.left and not node.right and remaining == node.val:
result.append(path[:])
# Recurse on children with updated remaining sum
dfs(node.left, remaining - node.val, path)
dfs(node.right, remaining - node.val, path)
# Backtrack: remove current node from path
path.pop()
dfs(root, target_sum, [])
return result
```
## Complexity
| Time | Space |
| --------------------------- | ------------------------------------------------------------- |
| O(n) - visit each node once | O(h) - recursion depth + path storage, where h is tree height |
## Tags
[Grind](/catalog/grind).
# Path Sum III Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/path-sum-iii
Tested Python solution for LeetCode 437 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 437, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/path-sum-iii/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 437 # by problem number
lcpy gen -s path_sum_iii # by problem name
```
## Problem
Given the `root` of a binary tree and an integer `targetSum`, return *the number of paths where the sum of the values along the path equals* `targetSum`.
The path does not need to start or end at the root or a leaf, but it must go downwards (i.e., traveling only from parent nodes to child nodes).
### Examples

```
Input: root = [10,5,-3,3,2,None,11,3,-2,None,1], targetSum = 8
Output: 3
Explanation: The paths that sum to 8 are shown.
```
```
Input: root = [5,4,8,11,None,13,4,7,2,None,None,5,1], targetSum = 22
Output: 3
```
### Constraints
* The number of nodes in the tree is in the range \[0, 1000].
* -10^9 \<= Node.val \<= 10^9
* -1000 \<= targetSum \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(n)
def path_sum(self, root: TreeNode[int] | None, target_sum: int) -> int:
"""Count paths where sum equals target_sum using prefix sum technique."""
self.count = 0
prefix_counts: defaultdict[int, int] = defaultdict(int)
prefix_counts[0] = 1 # Empty path prefix
def dfs(node: TreeNode[int] | None, current_sum: int) -> None:
if not node:
return
current_sum += node.val
# Check if (current_sum - target_sum) exists in prefix_counts
self.count += prefix_counts[current_sum - target_sum]
# Add current sum to prefix_counts
prefix_counts[current_sum] += 1
# Recurse on children
dfs(node.left, current_sum)
dfs(node.right, current_sum)
# Backtrack: remove current sum from prefix_counts
prefix_counts[current_sum] -= 1
dfs(root, 0)
return self.count
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind](/catalog/grind), [AlgoMaster 75](/catalog/algo-master-75).
# Path Sum IV Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/path-sum-iv
Tested Python solution for LeetCode 666 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 666, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/path-sum-iv/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 666 # by problem number
lcpy gen -s path_sum_iv # by problem name
```
## Problem
If the depth of a tree is smaller than `5`, then this tree can be represented by an array of three-digit integers. You are given an **ascending** array `nums` consisting of three-digit integers representing a binary tree with a depth smaller than `5`, where for each integer:
* The hundreds digit represents the depth `d` of this node, where `1 <= d <= 4`.
* The tens digit represents the position `p` of this node within its level, where `1 <= p <= 8`, corresponding to its position in a **full binary tree**.
* The units digit represents the value `v` of this node, where `0 <= v <= 9`.
Return the **sum** of all **paths** from the **root** towards the **leaves**.
It is **guaranteed** that the given array represents a valid connected binary tree.
### Examples

```
Input: nums = [113,215,221]
Output: 12
Explanation: The tree that the list represents is shown. The path sum is (3 + 5) + (3 + 1) = 12.
```

```
Input: nums = [113,221]
Output: 4
Explanation: The tree that the list represents is shown. The path sum is (3 + 1) = 4.
```
### Constraints
* 1 \<= nums.length \<= 15
* 110 \<= nums\[i] \<= 489
* nums represents a valid binary tree with depth less than 5.
* nums is sorted in ascending order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum_iv/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_sum_iv/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) where n = len(nums); each node is visited once
# Space: O(n) for the node lookup map plus O(depth) recursion
def path_sum(self, nums: list[int]) -> int:
# Node key is depth * 10 + position; value is the units digit
nodes = {num // 10: num % 10 for num in nums}
total = 0
stack: list[tuple[int, int]] = [(11, 0)]
while stack:
node, running = stack.pop()
if node not in nodes:
continue
running += nodes[node]
depth, pos = divmod(node, 10)
left = (depth + 1) * 10 + pos * 2 - 1
right = left + 1
if left in nodes or right in nodes:
stack.append((left, running))
stack.append((right, running))
else:
total += running
return total
```
## Complexity
| Time | Space |
| --------------------------------------------------- | ---------------------------------------------------- |
| O(n) where n = len(nums); each node is visited once | O(n) for the node lookup map plus O(depth) recursion |
## Tags
# Path with Maximum Gold Python Solution
Source: https://leetcode-py.wisl.dev/problems/path-with-maximum-gold
Tested Python solution for LeetCode 1219 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1219, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/path-with-maximum-gold/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1219 # by problem number
lcpy gen -s path_with_maximum_gold # by problem name
```
## Problem
In a gold mine `grid` of size `m x n`, each cell in this mine has an integer representing the amount of gold in that cell, `0` if it is empty.
Return the maximum amount of gold you can collect under the conditions:
* Every time you are located in a cell you will collect all the gold in that cell.
* From your position, you can walk one step to the left, right, up, or down.
* You can't visit the same cell more than once.
* Never visit a cell with `0` gold.
* You can start and stop collecting gold from **any** position in the grid that has some gold.
### Examples
```
Input: grid = [[0,6,0],[5,8,7],[0,9,0]]
Output: 24
Explanation:
Path to get the maximum gold, 9 -> 8 -> 7.
```
```
Input: grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]
Output: 28
Explanation:
Path to get the maximum gold, 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7.
```
### Constraints
* `m == grid.length`
* `n == grid[i].length`
* `1 <= m, n <= 15`
* `0 <= grid[i][j] <= 100`
* There are at most **25** cells containing gold.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_maximum_gold/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_maximum_gold/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(25 * 4^25) worst case, bounded by gold cells
# Space: O(rows * cols)
def get_maximum_gold(self, grid: list[list[int]]) -> int:
rows, cols = len(grid), len(grid[0])
def dfs(row: int, col: int) -> int:
if row < 0 or row >= rows or col < 0 or col >= cols or grid[row][col] == 0:
return 0
gold = grid[row][col]
grid[row][col] = 0
best = gold + max(
dfs(row + 1, col),
dfs(row - 1, col),
dfs(row, col + 1),
dfs(row, col - 1),
)
grid[row][col] = gold
return best
return max((dfs(row, col) for row in range(rows) for col in range(cols)), default=0)
```
## Complexity
| Time | Space |
| ----------------------------------------------- | --------------- |
| O(25 \* 4^25) worst case, bounded by gold cells | O(rows \* cols) |
## Tags
[NeetCode All](/catalog/neetcode).
# Path With Maximum Minimum Value
Source: https://leetcode-py.wisl.dev/problems/path-with-maximum-minimum-value
Tested Python solution for LeetCode 1102 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1102, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/path-with-maximum-minimum-value/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1102 # by problem number
lcpy gen -s path_with_maximum_minimum_value # by problem name
```
## Problem
Given an `m x n` integer matrix `grid`, return *the maximum **score** of a path starting at* `(0, 0)` *and ending at* `(m - 1, n - 1)` moving in the **4** cardinal directions.
The **score** of a path is the minimum value in that path.
* For example, the score of the path `8 → 4 → 5 → 9` is `4`.
### Examples
```
Input: grid = [[5,4,5],[1,2,6],[7,4,6]]
Output: 4
Explanation: The path with the maximum score is highlighted in yellow.
```
```
Input: grid = [[2,2,1,2,2,2],[1,2,2,2,1,2]]
Output: 2
```
```
Input: grid = [[3,4,6,3,4],[0,2,1,1,7],[8,8,3,2,7],[3,2,4,9,8],[4,1,2,0,0],[4,6,5,4,3]]
Output: 3
```
### Constraints
* m == grid.length
* n == grid\[i].length
* 1 \<= m, n \<= 100
* 0 \<= grid\[i]\[j] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_maximum_minimum_value/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_maximum_minimum_value/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(m * n * log(m * n))
# Space: O(m * n)
def maximum_minimum_path(self, grid: list[list[int]]) -> int:
m, n = len(grid), len(grid[0])
heap = [(-grid[0][0], 0, 0)]
seen = [[False] * n for _ in range(m)]
while heap:
neg_v, i, j = heapq.heappop(heap)
if seen[i][j]:
continue
seen[i][j] = True
if (i, j) == (m - 1, n - 1):
return -neg_v
for a, b in ((1, 0), (-1, 0), (0, 1), (0, -1)):
x, y = i + a, j + b
if 0 <= x < m and 0 <= y < n and not seen[x][y]:
heapq.heappush(heap, (-min(-neg_v, grid[x][y]), x, y))
raise AssertionError
```
## Complexity
| Time | Space |
| ------------------------ | --------- |
| O(m \* n \* log(m \* n)) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Path with Maximum Probability Python Solution
Source: https://leetcode-py.wisl.dev/problems/path-with-maximum-probability
Tested Python solution for LeetCode 1514 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1514, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Graph Theory](/catalog/topics/graph-theory), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Shortest Path](/catalog/topics/shortest-path), Dijkstra's Algorithm. [View on LeetCode](https://leetcode.com/problems/path-with-maximum-probability/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1514 # by problem number
lcpy gen -s path_with_maximum_probability # by problem name
```
## Problem
You are given an undirected weighted graph of `n` nodes (0-indexed), represented by an edge list where `edges[i] = [ai, bi]` is an undirected edge connecting the nodes `ai` and `bi` with a probability of success of traversing that edge `succProb[i]`.
Given two nodes `start` and `end`, find the path with the maximum probability of success to go from `start` to `end` and return its success probability.
If there is no path from `start` to `end`, return `0`. Your answer will be accepted if it differs from the correct answer by at most **10\-5\**.
### Examples

```
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
Output: 0.25000
Explanation: There are two paths from start to end, one having a probability of success = 0.2 and the other has 0.5 * 0.5 = 0.25.
```

```
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
Output: 0.30000
```

```
Input: n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
Output: 0.00000
Explanation: There is no path between 0 and 2.
```
### Constraints
* 2 \<= n \<= 10^4
* 0 \<= start, end \< n
* start != end
* 0 \<= a\i\, b\i\ \< n
* a\i\ != b\i\
* 0 \<= succProb.length == edges.length \<= 2 \* 10^4
* 0 \<= succProb\[i] \<= 1
* There is at most one edge between every two nodes.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_maximum_probability/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_maximum_probability/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O((V + E) * log V)
# Space: O(V + E)
def max_probability(
self, n: int, edges: list[list[int]], succ_prob: list[float], start_node: int, end_node: int
) -> float:
adj: list[list[tuple[int, float]]] = [[] for _ in range(n)]
for (a, b), p in zip(edges, succ_prob, strict=True):
adj[a].append((b, p))
adj[b].append((a, p))
best = [0.0] * n
best[start_node] = 1.0
heap: list[tuple[float, int]] = [(-1.0, start_node)]
while heap:
neg, node = heapq.heappop(heap)
cur = -neg
if cur < best[node]:
continue
if node == end_node:
return cur
for nxt, p in adj[node]:
cand = cur * p
if cand > best[nxt]:
best[nxt] = cand
heapq.heappush(heap, (-cand, nxt))
return best[end_node]
```
## Complexity
| Time | Space |
| ------------------- | -------- |
| O((V + E) \* log V) | O(V + E) |
## Tags
[NeetCode All](/catalog/neetcode).
# Path With Minimum Effort Python Solution
Source: https://leetcode-py.wisl.dev/problems/path-with-minimum-effort
Tested Python solution for LeetCode 1631 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1631, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/path-with-minimum-effort/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1631 # by problem number
lcpy gen -s path_with_minimum_effort # by problem name
```
## Problem
You are a hiker preparing for an upcoming hike. You are given `heights`, a 2D array of size `rows x columns`, where `heights[row][col]` represents the height of cell `(row, col)`. You are situated in the top-left cell, `(0, 0)`, and you hope to travel to the bottom-right cell, `(rows-1, columns-1)` (i.e., **0-indexed**). You can move **up**, **down**, **left**, or **right**, and you wish to find a route that requires the minimum **effort**.
A route's **effort** is the **maximum absolute difference** in heights between two consecutive cells of the route.
Return *the minimum **effort** required to travel from the top-left cell to the bottom-right cell.*
### Examples

```
Input: heights = [[1,2,2],[3,8,2],[5,3,5]]
Output: 2
Explanation: The route of [1,3,5,3,5] has a maximum absolute difference of 2 in consecutive cells.
This is better than the route of [1,2,2,2,5], where the maximum absolute difference is 3.
```

```
Input: heights = [[1,2,3],[3,8,4],[5,3,5]]
Output: 1
Explanation: The route of [1,2,3,4,5] has a maximum absolute difference of 1 in consecutive cells, which is better than route [1,3,5,3,5].
```

```
Input: heights = [[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]
Output: 0
Explanation: This route does not require any effort.
```
### Constraints
* rows == heights.length
* columns == heights\[i].length
* 1 \<= rows, columns \<= 100
* 1 \<= heights\[i]\[j] \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_minimum_effort/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/path_with_minimum_effort/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(rows * cols * log(rows * cols))
# Space: O(rows * cols)
def minimum_effort_path(self, heights: list[list[int]]) -> int:
rows = len(heights)
cols = len(heights[0])
efforts = [[float("inf")] * cols for _ in range(rows)]
efforts[0][0] = 0
heap: list[tuple[int, int, int]] = [(0, 0, 0)]
while heap:
effort, row, col = heapq.heappop(heap)
if row == rows - 1 and col == cols - 1:
return effort
if effort > efforts[row][col]:
continue
for drow, dcol in ((-1, 0), (1, 0), (0, -1), (0, 1)):
new_row, new_col = row + drow, col + dcol
if 0 <= new_row < rows and 0 <= new_col < cols:
new_effort = max(effort, abs(heights[row][col] - heights[new_row][new_col]))
if new_effort < efforts[new_row][new_col]:
efforts[new_row][new_col] = new_effort
heapq.heappush(heap, (new_effort, new_row, new_col))
return 0
```
## Complexity
| Time | Space |
| ------------------------------------ | --------------- |
| O(rows \* cols \* log(rows \* cols)) | O(rows \* cols) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# 132 Pattern Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/pattern-132
Tested Python solution for LeetCode 456 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 456, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/pattern-132/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 456 # by problem number
lcpy gen -s pattern_132 # by problem name
```
## Problem
Given an array of `n` integers `nums`, a **132 pattern** is a subsequence of three integers `nums[i]`, `nums[j]` and `nums[k]` such that `i < j < k` and `nums[i] < nums[k] < nums[j]`.
Return `true` *if there is a **132 pattern** in* `nums`, otherwise, return `false`.
### Examples
```
Input: nums = [1,2,3,4]
Output: false
Explanation: There is no 132 pattern in the sequence.
```
```
Input: nums = [3,1,4,2]
Output: true
Explanation: There is a 132 pattern in the sequence: [1, 4, 2].
```
```
Input: nums = [-1,3,2,0]
Output: true
Explanation: There are three 132 patterns in the sequence: [-1, 3, 2], [-1, 3, 0] and [-1, 2, 0].
```
### Constraints
* `n == nums.length`
* `1 <= n <= 2 * 10^5`
* `-10^9 <= nums[i] <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pattern_132/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pattern_132/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def find_132pattern(self, nums: list[int]) -> bool:
if len(nums) < 3:
return False
stack: list[int] = []
third = float("-inf")
for i in range(len(nums) - 1, -1, -1):
if nums[i] < third:
return True
while stack and stack[-1] < nums[i]:
third = stack.pop()
stack.append(nums[i])
return False
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Peak Index in a Mountain Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/peak-index-in-a-mountain-array
Tested Python solution for LeetCode 852 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 852, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), Ternary Search. [View on LeetCode](https://leetcode.com/problems/peak-index-in-a-mountain-array/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 852 # by problem number
lcpy gen -s peak_index_in_a_mountain_array # by problem name
```
## Problem
You are given an integer **mountain** array `arr` of length `n` where the values increase to a **peak element** and then decrease.
Return the index of the peak element.
Your task is to solve it in `O(log(n))` time complexity.
### Examples
```
Input: arr = [0,1,0]
Output: 1
```
```
Input: arr = [0,2,1,0]
Output: 1
```
```
Input: arr = [0,10,5,2]
Output: 1
```
### Constraints
* 3 \<= arr.length \<= 10^5
* 0 \<= arr\[i] \<= 10^6
* arr is guaranteed to be a mountain array.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/peak_index_in_a_mountain_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/peak_index_in_a_mountain_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def peak_index_in_mountain_array(self, arr: list[int]) -> int:
left, right = 0, len(arr) - 1
while left < right:
mid = (left + right) // 2
if arr[mid] < arr[mid + 1]:
left = mid + 1
else:
right = mid
return left
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
# Peeking Iterator Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/peeking-iterator
Tested Python solution for LeetCode 284 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 284, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Design](/catalog/topics/design), Iterator. [View on LeetCode](https://leetcode.com/problems/peeking-iterator/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 284 # by problem number
lcpy gen -s peeking_iterator # by problem name
```
## Problem
Design an iterator that supports the peek operation on an existing iterator in addition to the hasNext and the next operations.
Implement the PeekingIterator class:
* `PeekingIterator(Iteratorx\ is an integer that can divide \x\ evenly.
Given an integer \n\, return \true\\ if \\n\\ is a perfect number, otherwise return \\false\.
### Examples
```
Input: num = 28
Output: true
Explanation: 28 = 1 + 2 + 4 + 7 + 14
1, 2, 4, 7, and 14 are all divisors of 28.
```
```
Input: num = 7
Output: false
```
### Constraints
* `1 <= num <= 10^8`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perfect_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perfect_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(sqrt(n))
# Space: O(1)
def check_perfect_number(self, num: int) -> bool:
if num <= 1:
return False
total = 1
i = 2
while i * i <= num:
if num % i == 0:
total += i
paired = num // i
if paired != i:
total += paired
i += 1
return total == num
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(sqrt(n)) | O(1) |
## Tags
# Perfect Rectangle Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/perfect-rectangle
Tested Python solution for LeetCode 391 with 43 pytest cases. Generate a practice environment with lcpy.
LeetCode 391, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry), Sweep Line. [View on LeetCode](https://leetcode.com/problems/perfect-rectangle/description/).
Generate this problem as a practice environment: tested reference solution, 43 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 391 # by problem number
lcpy gen -s perfect_rectangle # by problem name
```
## Problem
Given an array `rectangles` where `rectangles[i] = [xi, yi, ai, bi]` represents an axis-aligned rectangle. The bottom-left point of the rectangle is `(xi, yi)` and the top-right point of it is `(ai, bi)`.
Return `true` *if all the rectangles together form an exact cover of a rectangular region*.
### Examples

```
Input: rectangles = [[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]]
Output: true
Explanation: All 5 rectangles together form an exact cover of a rectangular region.
```

```
Input: rectangles = [[1,1,2,3],[1,3,2,4],[3,1,4,2],[3,2,4,4]]
Output: false
Explanation: Because there is a gap between the two rectangular regions.
```

```
Input: rectangles = [[1,1,3,3],[3,1,4,2],[1,3,2,4],[2,2,4,4]]
Output: false
Explanation: Because two of the rectangles overlap with each other.
```
### Constraints
* 1 \<= rectangles.length \<= 2 \* 10^4
* rectangles\[i].length == 4
* -10^5 \<= xi \< ai \<= 10^5
* -10^5 \<= yi \< bi \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perfect_rectangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perfect_rectangle/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def is_rectangle_cover(self, rectangles: list[list[int]]) -> bool:
area = 0
corners: set[tuple[int, int]] = set()
min_x = min_y = 10**9
max_x = max_y = -(10**9)
for x, y, a, b in rectangles:
min_x = min(min_x, x)
min_y = min(min_y, y)
max_x = max(max_x, a)
max_y = max(max_y, b)
area += (a - x) * (b - y)
for corner in ((x, y), (a, y), (x, b), (a, b)):
if corner in corners:
corners.remove(corner)
else:
corners.add(corner)
if area != (max_x - min_x) * (max_y - min_y):
return False
return corners == {(min_x, min_y), (max_x, min_y), (min_x, max_y), (max_x, max_y)}
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Perfect Squares Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/perfect-squares
Tested Python solution for LeetCode 279 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 279, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/perfect-squares/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 279 # by problem number
lcpy gen -s perfect_squares # by problem name
```
## Problem
Given an integer `n`, return *the least number of perfect square numbers that sum to* `n`.
A **perfect square** is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, `1`, `4`, `9`, and `16` are perfect squares while `3` and `11` are not.
### Examples
```
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
```
```
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
```
### Constraints
* 1 \<= n \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perfect_squares/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perfect_squares/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * sqrt(n))
# Space: O(n)
def num_squares(self, n: int) -> int:
dp = [0] + [n + 1] * n
for i in range(1, n + 1):
j = 1
while j * j <= i:
dp[i] = min(dp[i], dp[i - j * j] + 1)
j += 1
return dp[n]
```
## Complexity
| Time | Space |
| --------------- | ----- |
| O(n \* sqrt(n)) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Perform String Shifts Python Solution
Source: https://leetcode-py.wisl.dev/problems/perform-string-shifts
Tested Python solution for LeetCode 1427 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1427, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/perform-string-shifts/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1427 # by problem number
lcpy gen -s perform_string_shifts # by problem name
```
## Problem
You are given a string `s` containing lowercase English letters, and a matrix `shift`, where `shift[i] = [directioni, amounti]`:
* `directioni` can be `0` (for left shift) or `1` (for right shift).
* `amounti` is the amount by which string `s` is to be shifted.
* A left shift by 1 means remove the first character of `s` and append it to the end.
* Similarly, a right shift by 1 means remove the last character of `s` and add it to the beginning.
Return the final string after all operations.
### Examples
```
Input: s = "abc", shift = [[0,1],[1,2]]
Output: "cab"
Explanation:
[0,1] means shift to left by 1. "abc" -> "bca"
[1,2] means shift to right by 2. "bca" -> "cab"
```
```
Input: s = "abcdefg", shift = [[1,1],[1,1],[0,2],[1,3]]
Output: "efgabcd"
Explanation:
[1,1] means shift to right by 1. "abcdefg" -> "gabcdef"
[1,1] means shift to right by 1. "gabcdef" -> "fgabcde"
[0,2] means shift to left by 2. "fgabcde" -> "abcdefg"
[1,3] means shift to right by 3. "abcdefg" -> "efgabcd"
```
### Constraints
* `1 <= s.length <= 100`
* `s` only contains lower case English letters.
* `1 <= shift.length <= 100`
* `shift[i].length == 2`
* `directioni` is either `0` or `1`.
* `0 <= amounti <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perform_string_shifts/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/perform_string_shifts/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m) where n = len(s), m = len(shift)
# Space: O(n) for the result string
def string_shift(self, s: str, shift: list[list[int]]) -> str:
offset = sum(amount if direction == 1 else -amount for direction, amount in shift)
offset %= len(s)
split = len(s) - offset
return s[split:] + s[:split]
```
## Complexity
| Time | Space |
| ----------------------------------------- | -------------------------- |
| O(n + m) where n = len(s), m = len(shift) | O(n) for the result string |
## Tags
[NeetCode All](/catalog/neetcode).
# Permutation in String Python Solution
Source: https://leetcode-py.wisl.dev/problems/permutation-in-string
Tested Python solution for LeetCode 567 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 567, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/permutation-in-string/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 567 # by problem number
lcpy gen -s permutation_in_string # by problem name
```
## Problem
Given two strings `s1` and `s2`, return `true` if `s2` contains a permutation of `s1`, or `false` otherwise.
In other words, return `true` if one of `s1`'s permutations is the substring of `s2`.
### Examples
```
Input: s1 = "ab", s2 = "eidbaooo"
Output: true
Explanation: s2 contains one permutation of s1 ("ba").
```
```
Input: s1 = "ab", s2 = "eidboaoo"
Output: false
```
### Constraints
* 1 \<= s1.length, s2.length \<= 10^4
* s1 and s2 consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutation_in_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutation_in_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(s2))
# Space: O(1) - only 26 letters
def check_inclusion(self, s1: str, s2: str) -> bool:
len1, len2 = len(s1), len(s2)
if len1 > len2:
return False
s1_count = [0] * 26
window_count = [0] * 26
for c in s1:
s1_count[ord(c) - ord("a")] += 1
for i in range(len2):
window_count[ord(s2[i]) - ord("a")] += 1
if i >= len1:
window_count[ord(s2[i - len1]) - ord("a")] -= 1
if i >= len1 - 1 and window_count == s1_count:
return True
return False
```
## Complexity
| Time | Space |
| ---------- | ---------------------- |
| O(len(s2)) | O(1) - only 26 letters |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Permutation Sequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/permutation-sequence
Tested Python solution for LeetCode 60 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 60, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/permutation-sequence/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 60 # by problem number
lcpy gen -s permutation_sequence # by problem name
```
## Problem
The set `[1, 2, 3, ..., n]` contains a total of `n!` unique permutations.
By listing and labeling all of the permutations in order, we get the following sequence for `n = 3`:
* `"123"`
* `"132"`
* `"213"`
* `"231"`
* `"312"`
* `"321"`
Given `n` and `k`, return the `kth` permutation sequence.
### Examples
```
Input: Input: n = 3, k = 3
Output: "213"
```
```
Input: Input: n = 4, k = 9
Output: "2314"
```
```
Input: Input: n = 3, k = 1
Output: "123"
```
### Constraints
* `1 <= n <= 9`
* `1 <= k <= n!`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutation_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutation_sequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import math
class Solution:
# Time: O(n^2)
# Space: O(n)
def get_permutation(self, n: int, k: int) -> str:
digits = [str(i) for i in range(1, n + 1)]
remaining = k - 1
parts: list[str] = []
for i in range(n, 0, -1):
block_size = math.factorial(i - 1)
idx, remaining = divmod(remaining, block_size)
parts.append(digits.pop(idx))
return "".join(parts)
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
# Permutations Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/permutations
Tested Python solution for LeetCode 46 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 46, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/permutations/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 46 # by problem number
lcpy gen -s permutations # by problem name
```
## Problem
Given an array `nums` of distinct integers, return all the possible permutations. You can return the answer in any order.
### Examples
```
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
```
```
Input: nums = [0,1]
Output: [[0,1],[1,0]]
```
```
Input: nums = [1]
Output: [[1]]
```
### Constraints
* 1 \<= nums.length \<= 6
* -10 \<= nums\[i] \<= 10
* All the integers of nums are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutations/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutations/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n! * n)
# Space: O(n! * n) output + O(n) recursion
def permute(self, nums: list[int]) -> list[list[int]]:
result = []
def backtrack(start: int) -> None:
if start == len(nums):
result.append(nums[:])
return
for i in range(start, len(nums)):
nums[start], nums[i] = nums[i], nums[start]
backtrack(start + 1)
nums[start], nums[i] = nums[i], nums[start]
backtrack(0)
return result
```
## Complexity
| Time | Space |
| ---------- | ---------------------------------- |
| O(n! \* n) | O(n! \* n) output + O(n) recursion |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Permutations II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/permutations-ii
Tested Python solution for LeetCode 47 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 47, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/permutations-ii/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 47 # by problem number
lcpy gen -s permutations_ii # by problem name
```
## Problem
Given a collection of numbers, `nums`, that might contain duplicates, return *all possible unique permutations* in **any order**.
### Examples
```
Input: nums = [1,1,2]
Output:
[[1,1,2],
[1,2,1],
[2,1,1]]
```
```
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
```
### Constraints
* `1 <= nums.length <= 8`
* `-10 <= nums[i] <= 10`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutations_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/permutations_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * n!)
# Space: O(n)
def permute_unique(self, nums: list[int]) -> list[list[int]]:
nums.sort()
result: list[list[int]] = []
used = [False] * len(nums)
def backtrack(current: list[int]) -> None:
if len(current) == len(nums):
result.append(list(current))
return
for i in range(len(nums)):
if used[i]:
continue
if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:
continue
used[i] = True
current.append(nums[i])
backtrack(current)
current.pop()
used[i] = False
backtrack([])
return result
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n \* n!) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Plus One Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/plus-one
Tested Python solution for LeetCode 66 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 66, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/plus-one/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 66 # by problem number
lcpy gen -s plus_one # by problem name
```
## Problem
You are given a **large integer** represented as an integer array `digits`, where each `digits[i]` is the `ith` digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading `0`'s.
Increment the large integer by one and return *the resulting array of digits*.
### Examples
```
Input: digits = [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.
Incrementing by one gives 123 + 1 = 124.
Thus, the result should be [1,2,4].
```
```
Input: digits = [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.
Incrementing by one gives 4321 + 1 = 4322.
Thus, the result should be [4,3,2,2].
```
```
Input: digits = [9]
Output: [1,0]
Explanation: The array represents the integer 9.
Incrementing by one gives 9 + 1 = 10.
Thus, the result should be [1,0].
```
### Constraints
* 1 \<= digits.length \<= 100
* 0 \<= digits\[i] \<= 9
* digits does not contain any leading 0's.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/plus_one/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/plus_one/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n) for the carry-overflow list, O(1) extra otherwise
def plus_one(self, digits: list[int]) -> list[int]:
for i in range(len(digits) - 1, -1, -1):
if digits[i] < 9:
digits[i] += 1
return digits
digits[i] = 0
return [1, *digits]
```
## Complexity
| Time | Space |
| ---- | ------------------------------------------------------ |
| O(n) | O(n) for the carry-overflow list, O(1) extra otherwise |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Plus One Linked List Python Solution
Source: https://leetcode-py.wisl.dev/problems/plus-one-linked-list
Tested Python solution for LeetCode 369 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 369, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/plus-one-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 369 # by problem number
lcpy gen -s plus_one_linked_list # by problem name
```
## Problem
Given a non-negative integer represented as a linked list of digits, *plus one to the integer*.
The digits are stored such that the most significant digit is at the `head` of the list.
### Examples
```
Input: head = [1,2,3]
Output: [1,2,4]
```
```
Input: head = [0]
Output: [1]
```
### Constraints
* The number of nodes in the linked list is in the range `[1, 100]`.
* `0 <= Node.val <= 9`
* The number represented by the linked list does not contain leading zeros except for the zero itself.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/plus_one_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/plus_one_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def plus_one(self, head: ListNode[int] | None) -> ListNode[int] | None:
dummy = ListNode(0)
dummy.next = head
# rightmost node not equal to 9
last_not_nine = dummy
node = head
while node is not None:
if node.val != 9:
last_not_nine = node
node = node.next
last_not_nine.val += 1
node = last_not_nine.next
while node is not None:
node.val = 0
node = node.next
return dummy if last_not_nine is dummy else head
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Poor Pigs Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/poor-pigs
Tested Python solution for LeetCode 458 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 458, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), Combinatorics. [View on LeetCode](https://leetcode.com/problems/poor-pigs/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 458 # by problem number
lcpy gen -s poor_pigs # by problem name
```
## Problem
There are `buckets` buckets of liquid, where **exactly one** of the buckets is poisonous. To figure out which one is poisonous, you feed some number of (poor) pigs the liquid to see whether they will die or not. Unfortunately, you only have `minutesToTest` minutes to determine which bucket is poisonous.
You can feed the pigs according to these steps:
1. Choose some live pigs to feed.
2. For each pig, choose which buckets to feed it. The pig will consume all the chosen buckets simultaneously and will take no time. Each pig can feed from any number of buckets, and each bucket can be fed from by any number of pigs.
3. Wait for `minutesToDie` minutes. You may **not** feed any other pigs during this time.
4. After `minutesToDie` minutes have passed, any pigs that have been fed the poisonous bucket will die, and all others will survive.
5. Repeat this process until you run out of time.
Given `buckets`, `minutesToDie`, and `minutesToTest`, return the **minimum** number of pigs needed to figure out which bucket is poisonous within the allotted time.
### Examples
```
Input: buckets = 4, minutesToDie = 15, minutesToTest = 15
Output: 2
Explanation: We can determine the poisonous bucket as follows:
At time 0, feed the first pig buckets 1 and 2, and feed the second pig buckets 2 and 3.
At time 15, there are 4 possible outcomes:
- If only the first pig dies, then bucket 1 must be poisonous.
- If only the second pig dies, then bucket 3 must be poisonous.
- If both pigs die, then bucket 2 must be poisonous.
- If neither pig dies, then bucket 4 must be poisonous.
```
```
Input: buckets = 4, minutesToDie = 15, minutesToTest = 30
Output: 2
Explanation: We can determine the poisonous bucket as follows:
At time 0, feed the first pig bucket 1, and feed the second pig bucket 2.
At time 15, there are 2 possible outcomes:
- If either pig dies, then the poisonous bucket is the one it was fed.
- If neither pig dies, then feed the first pig bucket 3, and feed the second pig bucket 4.
At time 30, one of the two pigs must die, and the poisonous bucket is the one it was fed.
```
### Constraints
* 1 \<= buckets \<= 1000
* 1 \<= minutesToDie \<= minutesToTest \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/poor_pigs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/poor_pigs/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log(buckets))
# Space: O(1)
def poor_pigs(self, buckets: int, minutes_to_die: int, minutes_to_test: int) -> int:
states = minutes_to_test // minutes_to_die + 1
pigs = 0
covered = 1
while covered < buckets:
covered *= states
pigs += 1
return pigs
```
## Complexity
| Time | Space |
| --------------- | ----- |
| O(log(buckets)) | O(1) |
## Tags
# Populating Next Right Pointers In Each Node
Source: https://leetcode-py.wisl.dev/problems/populating-next-right-pointers-in-each-node
Tested Python solution for LeetCode 116 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 116, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/populating-next-right-pointers-in-each-node/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 116 # by problem number
lcpy gen -s populating_next_right_pointers_in_each_node # by problem name
```
## Problem
You are given a **perfect binary tree** where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:
```
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
```
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to `NULL`.
Initially, all next pointers are set to `NULL`.
### Examples

```
Input: root = [1,2,3,4,5,6,7]
Output: [1,#,2,3,#,4,5,6,7,#]
Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.
```
```
Input: root = []
Output: []
```
### Constraints
* The number of nodes in the tree is in the range \[0, 2^12 - 1]
* -1000 \<= Node.val \<= 1000
**Follow-up:**
* You may only use constant extra space.
* The recursive approach is fine. You may assume implicit stack space does not count as extra space for this problem.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/populating_next_right_pointers_in_each_node/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/populating_next_right_pointers_in_each_node/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(
self,
val: int = 0,
left: Node | None = None,
right: Node | None = None,
next: Node | None = None,
):
self.val = val
self.left = left
self.right = right
self.next = next
class Solution:
# Time: O(n)
# Space: O(1)
def connect(self, root: Node | None) -> Node | None:
leftmost = root
while leftmost is not None and leftmost.left is not None:
head = leftmost
while head is not None:
left = head.left
right = head.right
assert left is not None and right is not None
left.next = right
if head.next is not None:
right.next = head.next.left
head = head.next
leftmost = leftmost.left
return root
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Populating Next Right Pointers in Each Node II
Source: https://leetcode-py.wisl.dev/problems/populating-next-right-pointers-in-each-node-ii
Tested Python solution for LeetCode 117 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 117, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 117 # by problem number
lcpy gen -s populating_next_right_pointers_in_each_node_ii # by problem name
```
## Problem
Given a binary tree
```
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
```
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to `NULL`.
Initially, all next pointers are set to `NULL`.
### Examples

```
Input: root = [1,2,3,4,5,null,7]
Output: [1,#,2,3,#,4,5,7,#]
Explanation: Given the above binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.
```
```
Input: root = []
Output: []
```
### Constraints
* The number of nodes in the tree is in the range \[0, 6000]
* -100 \<= Node.val \<= 100
**Follow-up:**
* You may only use constant extra space.
* The recursive approach is fine. You may assume implicit stack space does not count as extra space for this problem.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/populating_next_right_pointers_in_each_node_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/populating_next_right_pointers_in_each_node_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(
self,
val: int = 0,
left: Node | None = None,
right: Node | None = None,
next: Node | None = None,
):
self.val = val
self.left = left
self.right = right
self.next = next
class Solution:
# Time: O(n)
# Space: O(1)
def connect(self, root: Node | None) -> Node | None:
current = root
while current is not None:
# Build the next level using the already-linked current level.
level_head: Node | None = None
level_tail: Node | None = None
while current is not None:
for child in (current.left, current.right):
if child is None:
continue
if level_tail is None:
level_head = child
else:
level_tail.next = child
level_tail = child
current = current.next
current = level_head
return root
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Positions of Large Groups Python Solution
Source: https://leetcode-py.wisl.dev/problems/positions-of-large-groups
Tested Python solution for LeetCode 830 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 830, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/positions-of-large-groups/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 830 # by problem number
lcpy gen -s positions_of_large_groups # by problem name
```
## Problem
In a string `s` of lowercase letters, these letters form consecutive groups of the same character.
For example, a string like `s = "abbxxxxzyy"` has the groups `"a"`, `"bb"`, `"xxxx"`, `"z"`, and `"yy"`.
A group is identified by an interval `[start, end]`, where `start` and `end` denote the start and end indices (inclusive) of the group. In the above example, `"xxxx"` has the interval `[3,6]`.
A group is considered **large** if it has 3 or more characters.
Return the intervals of every large group sorted in increasing order by start index.
### Examples
```
Input: s = "abbxxxxzzy"
Output: [[3,6]]
Explanation: "xxxx" is the only large group with start index 3 and end index 6.
```
```
Input: s = "abc"
Output: []
Explanation: We have groups "a", "b", and "c", none of which are large groups.
```
```
Input: s = "abcdddeeeeaabbbcd"
Output: [[3,5],[6,9],[12,14]]
Explanation: The large groups are "ddd", "eeee", and "bbb".
```
### Constraints
* 1 \<= s.length \<= 1000
* s contains lowercase English letters only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/positions_of_large_groups/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/positions_of_large_groups/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) excluding output
def large_group_positions(self, s: str) -> list[list[int]]:
result: list[list[int]] = []
start = 0
for i in range(1, len(s) + 1):
if i == len(s) or s[i] != s[start]:
if i - start >= 3:
result.append([start, i - 1])
start = i
return result
```
## Complexity
| Time | Space |
| ---- | --------------------- |
| O(n) | O(1) excluding output |
## Tags
# Possible Bipartition Python Solution
Source: https://leetcode-py.wisl.dev/problems/possible-bipartition
Tested Python solution for LeetCode 886 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 886, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory), Graph Coloring, Bipartite Graph. [View on LeetCode](https://leetcode.com/problems/possible-bipartition/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 886 # by problem number
lcpy gen -s possible_bipartition # by problem name
```
## Problem
We want to split a group of `n` people (labeled from `1` to `n`) into two groups of **any size**. Each person may dislike some other people, and they should not go into the same group.
Given the integer `n` and the array `dislikes` where `dislikes[i] = [ai, bi]` indicates that the person labeled `ai` does not like the person labeled `bi`, return `true` if it is possible to split everyone into two groups in this way.
### Examples
```
Input: n = 4, dislikes = [[1,2],[1,3],[2,4]]
Output: true
```
**Explanation:** The first group has \[1,4], and the second group has \[2,3].
```
Input: n = 3, dislikes = [[1,2],[1,3],[2,3]]
Output: false
```
**Explanation:** We need at least 3 groups to divide them. We cannot put them in two groups.
### Constraints
* `1 <= n <= 2000`
* `0 <= dislikes.length <= 10^4`
* `dislikes[i].length == 2`
* `1 <= ai < bi <= n`
* All the pairs of dislikes are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/possible_bipartition/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/possible_bipartition/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n + E)
# Space: O(n + E)
def possible_bipartition(self, n: int, dislikes: list[list[int]]) -> bool:
adj: list[list[int]] = [[] for _ in range(n + 1)]
for a, b in dislikes:
adj[a].append(b)
adj[b].append(a)
color = [0] * (n + 1)
for start in range(1, n + 1):
if color[start] != 0:
continue
color[start] = 1
queue = deque([start])
while queue:
person = queue.popleft()
for other in adj[person]:
if color[other] == 0:
color[other] = -color[person]
queue.append(other)
elif color[other] == color[person]:
return False
return True
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + E) | O(n + E) |
## Tags
# Pour Water Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/pour-water
Tested Python solution for LeetCode 755 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 755, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/pour-water/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 755 # by problem number
lcpy gen -s pour_water # by problem name
```
## Problem
You are given an elevation map represented as an integer array `heights` where `heights[i]` representing the height of the terrain at index `i`. The width at each index is `1`. You are also given two integers `volume` and `k`. `volume` units of water will fall at index `k`.
Water first drops at the index `k` and rests on top of the highest terrain or water at that index. Then, it flows according to the following rules:
* If the droplet would eventually fall by moving left, then move left.
* Otherwise, if the droplet would eventually fall by moving right, then move right.
* Otherwise, rise to its current position.
Here, **"eventually fall"** means that the droplet will eventually be at a lower level if it moves in that direction. Also, level means the height of the terrain plus any water in that column.
We can assume there is infinitely high terrain on the two sides out of bounds of the array. Also, there could not be partial water being spread out evenly on more than one grid block, and each unit of water has to be in exactly one block.
### Examples

```
Input: heights = [2,1,1,2,1,2,2], volume = 4, k = 3
Output: [2,2,2,3,2,2,2]
```
**Explanation:** The first drop of water lands at index k = 3. When moving left or right, the water can only move to the same level or a lower level. (By level, we mean the total height of the terrain plus any water in that column.) Since moving left will eventually make it fall, it moves left. Since moving left will not make it fall, it stays in place. The next droplet falls at index k = 3. Since the new droplet moving left will eventually make it fall, it moves left. Notice that the droplet still preferred to move left, even though it could move right (and moving right makes it fall quicker.) The third droplet falls at index k = 3. Since moving left would not eventually make it fall, it tries to move right. Since moving right would eventually make it fall, it moves right. Finally, the fourth droplet falls at index k = 3. Since moving left would not eventually make it fall, it tries to move right. Since moving right would not eventually make it fall, it stays in place.
```
Input: heights = [1,2,3,4], volume = 2, k = 2
Output: [2,3,3,4]
```
**Explanation:** The last droplet settles at index 1, since moving further left would not cause it to eventually fall to a lower height.
```
Input: heights = [3,1,3], volume = 5, k = 1
Output: [4,4,4]
```
### Constraints
* `1 <= heights.length <= 100`
* `0 <= heights[i] <= 99`
* `0 <= volume <= 2000`
* `0 <= k < heights.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pour_water/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pour_water/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(volume * n)
# Space: O(1) extra
def pour_water(self, heights: list[int], volume: int, k: int) -> list[int]:
n = len(heights)
for _ in range(volume):
best = k
for d in (-1, 1):
i = best = k
while 0 <= i + d < n and heights[i + d] <= heights[i]:
if heights[i + d] < heights[best]:
best = i + d
i += d
if best != k:
break
heights[best] += 1
return heights
```
## Complexity
| Time | Space |
| -------------- | ---------- |
| O(volume \* n) | O(1) extra |
## Tags
# Power of Four Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/power-of-four
Tested Python solution for LeetCode 342 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 342, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/power-of-four/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 342 # by problem number
lcpy gen -s power_of_four # by problem name
```
## Problem
Given an integer `n`, return `true` if it is a power of four. Otherwise, return `false`.
An integer `n` is a power of four, if there exists an integer `x` such that `n == 4^x`.
### Examples
```
Input: n = 16
Output: true
```
```
Input: n = 5
Output: false
```
```
Input: n = 1
Output: true
```
### Constraints
* -2^31 \<= n \<= 2^31 - 1
**Follow up:** Could you solve it without loops/recursion?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/power_of_four/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/power_of_four/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def is_power_of_four(self, n: int) -> bool:
# Power of two with the single set bit in an even (0-indexed) position:
# 4^x mod 3 == 1, while 2 * 4^x mod 3 == 2.
return n > 0 and n & (n - 1) == 0 and n % 3 == 1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Power of Three Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/power-of-three
Tested Python solution for LeetCode 326 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 326, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/power-of-three/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 326 # by problem number
lcpy gen -s power_of_three # by problem name
```
## Problem
Given an integer `n`, return `true` if it is a power of three. Otherwise, return `false`.
An integer `n` is a power of three, if there exists an integer `x` such that `n == 3^x`.
### Examples
```
Input: n = 27
Output: true
Explanation: 27 = 3^3
```
```
Input: n = 0
Output: false
Explanation: There is no x where 3^x = 0.
```
```
Input: n = -1
Output: false
Explanation: There is no x where 3^x = (-1).
```
### Constraints
* -2^31 \<= n \<= 2^31 - 1
**Follow up:** Could you solve it without loops/recursion?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/power_of_three/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/power_of_three/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def is_power_of_three(self, n: int) -> bool:
# 3^19 = 1162261467 is the largest power of three fitting in a signed
# 32-bit int; it is divisible by every smaller power of three and by
# no other positive integer in range. Constant time, no loops.
return n > 0 and 1162261467 % n == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
# Power of Two Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/power-of-two
Tested Python solution for LeetCode 231 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 231, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/power-of-two/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 231 # by problem number
lcpy gen -s power_of_two # by problem name
```
## Problem
Given an integer `n`, return `true` if it is a power of two. Otherwise, return `false`.
An integer `n` is a power of two, if there exists an integer `x` such that `n == 2^x`.
### Examples
```
Input: n = 1
Output: true
Explanation: 2^0 = 1
```
```
Input: n = 16
Output: true
Explanation: 2^4 = 16
```
```
Input: n = 3
Output: false
```
### Constraints
* -2^31 \<= n \<= 2^31 - 1
**Follow up:** Could you solve it without loops/recursion?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/power_of_two/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/power_of_two/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def is_power_of_two(self, n: int) -> bool:
return n > 0 and n & (n - 1) == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Powerful Integers Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/powerful-integers
Tested Python solution for LeetCode 970 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 970, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/powerful-integers/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 970 # by problem number
lcpy gen -s powerful_integers # by problem name
```
## Problem
Given three integers `x`, `y`, and `bound`, return a list of all the **powerful integers** that have a value less than or equal to `bound`.
An integer is **powerful** if it can be represented as `x^i + y^j` for some integers `i >= 0` and `j >= 0`.
You may return the answer in **any order**. In your answer, each value should occur **at most once**.
### Examples
```
Input: x = 2, y = 3, bound = 10
Output: [2,3,4,5,7,9,10]
Explanation:
2 = 2^0 + 3^0
3 = 2^1 + 3^0
4 = 2^0 + 3^1
5 = 2^1 + 3^1
7 = 2^2 + 3^1
9 = 2^3 + 3^0
10 = 2^0 + 3^2
```
```
Input: x = 3, y = 5, bound = 15
Output: [2,4,6,8,10,14]
```
### Constraints
* 1 \<= x, y \<= 100
* 0 \<= bound \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/powerful_integers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/powerful_integers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log(x, bound) * log(y, bound))
# Space: O(log(x, bound) * log(y, bound))
def powerful_integers(self, x: int, y: int, bound: int) -> list[int]:
def powers(base: int) -> list[int]:
if base == 1:
return [1] if bound >= 1 else []
vals: list[int] = []
val = 1
while val <= bound:
vals.append(val)
val *= base
return vals
found: set[int] = set()
for xi in powers(x):
for yj in powers(y):
total = xi + yj
if total <= bound:
found.add(total)
return list(found)
```
## Complexity
| Time | Space |
| --------------------------------- | --------------------------------- |
| O(log(x, bound) \* log(y, bound)) | O(log(x, bound) \* log(y, bound)) |
## Tags
# Pow(x, n) Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/powx-n
Tested Python solution for LeetCode 50 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 50, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/powx-n/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 50 # by problem number
lcpy gen -s powx_n # by problem name
```
## Problem
Implement [pow(x, n)](http://www.cplusplus.com/reference/valarray/pow/), which calculates `x` raised to the power `n` (i.e., x\n\).
### Examples
```
Input: x = 2.00000, n = 10
Output: 1024.00000
```
```
Input: x = 2.10000, n = 3
Output: 9.26100
```
```
Input: x = 2.00000, n = -2
Output: 0.25000
Explanation: 2^-2 = 1/2^2 = 1/4 = 0.25
```
### Constraints
* -100.0 \< x \< 100.0
* -2^31 \<= n \<= 2^31 - 1
* `n` is an integer.
* Either `x` is not zero or `n > 0`.
* -10^4 \<= x^n \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/powx_n/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/powx_n/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(log n)
def my_pow(self, x: float, n: int) -> float:
if n == 0:
return 1.0
if n < 0:
return 1.0 / self.my_pow(x, -n)
if n % 2 == 0:
half = self.my_pow(x, n // 2)
return half * half
return x * self.my_pow(x, n - 1)
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(log n) | O(log n) |
## Tags
[Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Predict the Winner Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/predict-the-winner
Tested Python solution for LeetCode 486 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 486, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Recursion](/catalog/topics/recursion), [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/predict-the-winner/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 486 # by problem number
lcpy gen -s predict_the_winner # by problem name
```
## Problem
You are given an integer array `nums`. Two players are playing a game with this array: player 1 and player 2.
Player 1 and player 2 take turns, with player 1 starting first. Both players start the game with a score of `0`. At each turn, the player takes one of the numbers from either end of the array (i.e., `nums[0]` or `nums[nums.length - 1]`) which reduces the size of the array by `1`. The player adds the chosen number to their score. The game ends when there are no more elements in the array.
Return `true` if Player 1 can win the game. If the scores of both players are equal, then player 1 is still the winner, and you should also return `true`. You may assume that both players are playing optimally.
### Examples
```
Input: nums = [1,5,2]
Output: false
Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return false.
```
```
Input: nums = [1,5,233,7]
Output: true
Explanation: Player 1 first chooses 1. Then player 2 has to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.
```
### Constraints
* 1 \<= nums.length \<= 20
* 0 \<= nums\[i] \<= 10^7
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/predict_the_winner/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/predict_the_winner/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def predict_the_winner(self, nums: list[int]) -> bool:
n = len(nums)
# dp[l][r] is the best score difference (current player minus opponent)
# achievable on the subarray nums[l:r + 1].
dp = [[0] * n for _ in range(n)]
for i in range(n):
dp[i][i] = nums[i]
for length in range(2, n + 1):
for left in range(n - length + 1):
right = left + length - 1
take_left = nums[left] - dp[left + 1][right]
take_right = nums[right] - dp[left][right - 1]
dp[left][right] = max(take_left, take_right)
return dp[0][n - 1] >= 0
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
# Prefix and Suffix Search Python Solution
Source: https://leetcode-py.wisl.dev/problems/prefix-and-suffix-search
Tested Python solution for LeetCode 745 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 745, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Design](/catalog/topics/design), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/prefix-and-suffix-search/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 745 # by problem number
lcpy gen -s prefix_and_suffix_search # by problem name
```
## Problem
Design a special dictionary that searches the words in it by a prefix and a suffix.
Implement the `WordFilter` class:
* `WordFilter(string[] words)` Initializes the object with the `words` in the dictionary.
* `f(string pref, string suff)` Returns *the index of the word in the dictionary,* which has the prefix `pref` and the suffix `suff`. If there is more than one valid index, return **the largest** of them. If there is no such word in the dictionary, return `-1`.
### Examples
```
Input
["WordFilter", "f"]
[[["apple"]], ["a", "e"]]
Output
[null, 0]
Explanation
WordFilter wordFilter = new WordFilter(["apple"]);
wordFilter.f("a", "e"); // return 0, because the word at index 0 has prefix = "a" and suffix = "e".
```
### Constraints
* `1 <= words.length <= 10^4`
* `1 <= words[i].length <= 7`
* `1 <= pref.length, suff.length <= 7`
* `words[i]`, `pref` and `suff` consist of lowercase English letters only.
* At most `10^4` calls will be made to the function `f`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/prefix_and_suffix_search/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/prefix_and_suffix_search/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class WordFilter:
# Time: __init__ O(n * L^2), f O(P + S)
# Space: O(n * L^2) keys, each at most 2L + 1 characters
def __init__(self, words: list[str]) -> None:
# Encode every (prefix, suffix) pair of every word as "pref#suff". Because
# words are visited in increasing index order, the last write for a key is the
# largest matching index, which is exactly what f must return.
self.best: dict[str, int] = {}
for index, word in enumerate(words):
for i in range(len(word) + 1):
prefix = word[:i]
for j in range(len(word) + 1):
self.best[f"{prefix}#{word[j:]}"] = index
# Time: O(P + S)
# Space: O(P + S)
def f(self, pref: str, suff: str) -> int:
return self.best.get(f"{pref}#{suff}", -1)
```
## Complexity
| Time | Space |
| -------------------------------- | ------------------------------------------------ |
| **init** O(n \* L^2), f O(P + S) | O(n \* L^2) keys, each at most 2L + 1 characters |
## Tags
# Preimage Size of Factorial Zeroes Function
Source: https://leetcode-py.wisl.dev/problems/preimage-size-of-factorial-zeroes-function
Tested Python solution for LeetCode 793 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 793, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/preimage-size-of-factorial-zeroes-function/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 793 # by problem number
lcpy gen -s preimage_size_of_factorial_zeroes_function # by problem name
```
## Problem
Let \f(x)\ be the number of zeroes at the end of \x!\. Recall that \x! = 1 \* 2 \* 3 \* ... \* x\ and by convention, \0! = 1\.
\f(3) = 0\ because \3! = 6\ has no zeroes at the end, while \f(11) = 2\ because \11! = 39916800\ has two zeroes at the end.\Given an integer \k\, return \the number of non-negative integers\ \x\ \have the property that\ \f(x) = k\.\
n\ members, and a list of various crimes they could commit. The \ith\ crime generates a \profit\[i]\ and requires \group\[i]\ members to participate in it. If a member participates in one crime, that member can't participate in another crime.\
\Let's call a \profitable scheme\ any subset of these crimes that generates at least \minProfit\ profit, and the total number of members participating in that subset of crimes is at most \n\.\
Return the number of schemes that can be chosen. Since the answer may be very large, return it \modulo\ \10\9\ + 7\.
### Examples
```
Input: n = 5, minProfit = 3, group = [2,2], profit = [2,3]
Output: 2
Explanation: To make a profit of at least 3, the group could either commit crimes 0 and 1, or just crime 1.
In total, there are 2 schemes.
```
```
Input: n = 10, minProfit = 5, group = [2,3,5], profit = [6,7,8]
Output: 7
Explanation: Every subset of the crimes has total members at most 10 and profit at least 5,
and 7 subsets exist, so all of them are profitable schemes.
```
### Constraints
* 1 \<= n \<= 100
* 0 \<= minProfit \<= 100
* 1 \<= group.length \<= 100
* 1 \<= group\[i] \<= 100
* profit.length == group.length
* 0 \<= profit\[i] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/profitable_schemes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/profitable_schemes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(group) * n * min_profit)
# Space: O(n * min_profit)
def profitable_schemes(
self, n: int, min_profit: int, group: list[int], profit: list[int]
) -> int:
mod = 1_000_000_007
dp = [[0] * (min_profit + 1) for _ in range(n + 1)]
dp[0][0] = 1
for members, gain in zip(group, profit, strict=True):
for used in range(n, members - 1, -1):
for earned in range(min_profit, -1, -1):
new_earned = min(min_profit, earned + gain)
dp[used][new_earned] = (dp[used][new_earned] + dp[used - members][earned]) % mod
return sum(dp[used][min_profit] for used in range(n + 1)) % mod
```
## Complexity
| Time | Space |
| --------------------------------- | ------------------- |
| O(len(group) \* n \* min\_profit) | O(n \* min\_profit) |
## Tags
[NeetCode All](/catalog/neetcode).
# Projection Area of 3D Shapes Python Solution
Source: https://leetcode-py.wisl.dev/problems/projection-area-of-3d-shapes
Tested Python solution for LeetCode 883 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 883, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/projection-area-of-3d-shapes/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 883 # by problem number
lcpy gen -s projection_area_of_3d_shapes # by problem name
```
## Problem
You are given an n x n grid where we place some 1 x 1 x 1 cubes that are axis-aligned with the x, y, and z axes.
Each value v = grid\[i]\[j] represents a tower of v cubes placed on top of the cell (i, j).
We view the projection of these cubes onto the xy, yz, and zx planes.
A projection is like a shadow, that maps our 3-dimensional figure to a 2-dimensional plane. We are viewing the "shadow" when looking at the cubes from the top, the front, and the side.
Return the total area of all three projections.
### Examples

```
Input: grid = [[1,2],[3,4]]
Output: 17
Explanation: Here are the three projections ("shadows") of the shape made with each axis-aligned plane.
```
```
Input: grid = [[2]]
Output: 5
```
```
Input: grid = [[1,0],[0,2]]
Output: 8
```
### Constraints
* n == grid.length == grid\[i].length
* 1 \<= n \<= 50
* 0 \<= grid\[i]\[j] \<= 50
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/projection_area_of_3d_shapes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/projection_area_of_3d_shapes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2) over the grid cells
# Space: O(1) extra beyond the input
def projection_area(self, grid: list[list[int]]) -> int:
top = sum(1 for row in grid for cube in row if cube > 0)
front = sum(max(row) for row in grid)
side = sum(max(col) for col in zip(*grid, strict=True))
return top + front + side
```
## Complexity
| Time | Space |
| -------------------------- | --------------------------- |
| O(n^2) over the grid cells | O(1) extra beyond the input |
## Tags
# Pseudo-Palindromic Paths in a Binary Tree
Source: https://leetcode-py.wisl.dev/problems/pseudo-palindromic-paths-in-a-binary-tree
Tested Python solution for LeetCode 1457 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 1457, [Medium](/catalog/medium). Topics: [Bit Manipulation](/catalog/topics/bit-manipulation), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/pseudo-palindromic-paths-in-a-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1457 # by problem number
lcpy gen -s pseudo_palindromic_paths_in_a_binary_tree # by problem name
```
## Problem
Given a binary tree where node values are digits from 1 to 9 only. A path in the binary tree is said to be **pseudo-palindromic** if at least one permutation of the node values in the path is a palindrome.
Return the number of **pseudo-palindromic** paths going from the root node to leaf nodes.
### Examples

```
Input: root = [2,3,1,3,1,null,1]
Output: 2
Explanation: The figure above represents the given binary tree. There are three paths going from the root node to leaf nodes: the red path [2,3,3], the green path [2,1,1], and the path [2,3,1]. Among these paths only the red path and the green path are pseudo-palindromic paths since the red path [2,3,3] can be rearranged in [3,2,3] (palindrome) and the green path [2,1,1] can be rearranged in [1,2,1] (palindrome).
```

```
Input: root = [2,1,1,1,3,null,null,null,null,null,1]
Output: 1
Explanation: The figure above represents the given binary tree. There are three paths going from the root node to leaf nodes: the green path [2,1,1], the path [2,1,3,1], and the path [2,1]. Among these paths only the green path is pseudo-palindromic since [2,1,1] can be rearranged in [1,2,1] (palindrome).
```
```
Input: root = [9]
Output: 1
```
### Constraints
* The number of nodes in the tree is in the range \[1, 10^5]
* 1 \<= Node.val \<= 9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pseudo_palindromic_paths_in_a_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pseudo_palindromic_paths_in_a_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def pseudo_palindromic_paths(self, root: TreeNode[int] | None) -> int:
if root is None:
return 0
total = 0
stack: list[tuple[TreeNode[int], int]] = [(root, 1 << root.val)]
while stack:
node, mask = stack.pop()
if node.left is None and node.right is None:
if mask & (mask - 1) == 0:
total += 1
continue
if node.left is not None:
stack.append((node.left, mask ^ (1 << node.left.val)))
if node.right is not None:
stack.append((node.right, mask ^ (1 << node.right.val)))
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Push Dominoes Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/push-dominoes
Tested Python solution for LeetCode 838 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 838, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/push-dominoes/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 838 # by problem number
lcpy gen -s push_dominoes # by problem name
```
## Problem
There are `n` dominoes in a line, and we place each domino vertically upright. In the beginning, we simultaneously push some of the dominoes either to the left or to the right.
After each second, each domino that is falling to the left pushes the adjacent domino on the left. Similarly, the dominoes falling to the right push their adjacent dominoes standing on the right.
When a vertical domino has dominoes falling on it from both sides, it stays still due to the balance of the forces.
For the purposes of this question, we will consider that a falling domino expends no additional force to a falling or already fallen domino.
You are given a string `dominoes` representing the initial state where:
* `dominoes[i] = 'L'`, if the `ith` domino has been pushed to the left,
* `dominoes[i] = 'R'`, if the `ith` domino has been pushed to the right, and
* `dominoes[i] = '.'`, if the `ith` domino has not been pushed.
Return *a string representing the final state*.
### Examples
```
Input: dominoes = "RR.L"
Output: "RR.L"
Explanation: The first domino expends no additional force on the second domino.
```
```
Input: dominoes = ".L.R...LR..L.."
Output: "LL.RR.LLRRLL.."
```
### Constraints
* n == dominoes.length
* 1 \<= n \<= 10^5
* dominoes\[i] is either 'L', 'R', or '.'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/push_dominoes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/push_dominoes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def push_dominoes(self, dominoes: str) -> str:
n = len(dominoes)
force = [0] * n
f = 0
for i in range(n):
if dominoes[i] == "R":
f = n
elif dominoes[i] == "L":
f = 0
elif f:
f -= 1
force[i] += f
f = 0
for i in range(n - 1, -1, -1):
if dominoes[i] == "L":
f = n
elif dominoes[i] == "R":
f = 0
elif f:
f -= 1
force[i] -= f
return "".join("." if x == 0 else "R" if x > 0 else "L" for x in force)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Put Boxes Into the Warehouse I Python Solution
Source: https://leetcode-py.wisl.dev/problems/put-boxes-into-the-warehouse-i
Tested Python solution for LeetCode 1564 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1564, [Medium](/catalog/medium). Topics: [Greedy](/catalog/topics/greedy), [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/put-boxes-into-the-warehouse-i/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1564 # by problem number
lcpy gen -s put_boxes_into_the_warehouse_i # by problem name
```
## Problem
You are given two arrays of positive integers, `boxes` and `warehouse`, representing the heights of some boxes of unit width and the heights of `n` rooms in a warehouse respectively. The warehouse's rooms are labelled from `0` to `n - 1` from left to right where `warehouse[i]` (0-indexed) is the height of the i\th\ room.
Boxes are put into the warehouse by the following rules:
* Boxes cannot be stacked.
* You can rearrange the insertion order of the boxes.
* Boxes can only be pushed into the warehouse from left to right only.
* If the height of some room in the warehouse is less than the height of a box, then that box and all other boxes behind it will be stopped before that room.
Return \the maximum number of boxes you can put into the warehouse.\
### Examples

```
Input: boxes = [4,3,4,1], warehouse = [5,3,3,4,1]
Output: 3
Explanation:

We can first put the box of height 1 in room 4. Then we can put the box of height 3 in either of the 3 rooms 1, 2, or 3. Lastly, we can put one box of height 4 in room 0.
There is no way we can fit all 4 boxes in the warehouse.
```

```
Input: boxes = [1,2,2,3,4], warehouse = [3,4,1,2]
Output: 3
Explanation:

Notice that it's not possible to put the box of height 4 into the warehouse since it cannot pass the first room of height 3.
Also, for the last two rooms, 2 and 3, only boxes of height 1 can fit.
We can fit 3 boxes maximum as shown above. The yellow box can also be put in room 2 instead.
Swapping the orange and green boxes is also valid, or swapping one of them with the red box.
```
```
Input: boxes = [1,2,3], warehouse = [1,2,3,4]
Output: 1
Explanation: Since the first room in the warehouse is of height 1, we can only put boxes of height 1.
```
### Constraints
* `n == warehouse.length`
* `1 <= boxes.length, warehouse.length <= 10^5`
* `1 <= boxes[i], warehouse[i] <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/put_boxes_into_the_warehouse_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/put_boxes_into_the_warehouse_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m + n log n), Space: O(n) for effective heights
def max_boxes_in_warehouse(self, boxes: list[int], warehouse: list[int]) -> int:
# A box of height b can occupy room i iff b <= min(warehouse[0..i]):
# it must survive every room on the way and fit in room i itself.
lowest: list[int] = []
reachable = warehouse[0]
for height in warehouse:
reachable = min(reachable, height)
lowest.append(reachable)
# Smallest box pairs with the smallest usable (rightmost) room.
placed = 0
room = len(lowest) - 1
for box in sorted(boxes):
while room >= 0 and lowest[room] < box:
room -= 1
if room < 0:
break
placed += 1
room -= 1
return placed
```
## Complexity
| Time | Space |
| ------------------------------------------------- | ----- |
| O(m + n log n), Space: O(n) for effective heights | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Put Marbles in Bags Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/put-marbles-in-bags
Tested Python solution for LeetCode 2551 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2551, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/put-marbles-in-bags/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2551 # by problem number
lcpy gen -s put_marbles_in_bags # by problem name
```
## Problem
You have `k` bags. You are given a **0-indexed** integer array `weights` where `weights[i]` is the weight of the `i`th marble. You are also given the integer `k`.
Divide the marbles into the `k` bags according to the following rules:
* No bag is empty.
* If the `i`th marble and `j`th marble are in a bag, then all marbles with an index between the `i`th and `j`th indices should also be in that same bag.
* If a bag consists of all the marbles with an index from `i` to `j` inclusively, then the cost of the bag is `weights[i] + weights[j]`.
The **score** after distributing the marbles is the sum of the costs of all the `k` bags.
Return the difference between the maximum and minimum scores among marble distributions.
### Examples
```
Input: weights = [1,3,5,1], k = 2
Output: 4
Explanation:
The distribution [1],[3,5,1] results in the minimal score of (1+1) + (3+1) = 6.
The distribution [1,3],[5,1], results in the maximal score of (1+3) + (5+1) = 10.
Thus, we return their difference 10 - 6 = 4.
```
```
Input: weights = [1, 3], k = 2
Output: 0
Explanation: The only distribution possible is [1],[3].
Since both the maximal and minimal score are the same, we return 0.
```
### Constraints
* `1 <= k <= weights.length <= 10^5`
* `1 <= weights[i] <= 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/put_marbles_in_bags/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/put_marbles_in_bags/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def put_marbles(self, weights: list[int], k: int) -> int:
if k == 1:
return 0
pair_sums = sorted(weights[i] + weights[i + 1] for i in range(len(weights) - 1))
splits = k - 1
return sum(pair_sums[-splits:]) - sum(pair_sums[:splits])
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Pyramid Transition Matrix Python Solution
Source: https://leetcode-py.wisl.dev/problems/pyramid-transition
Tested Python solution for LeetCode 756 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 756, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/pyramid-transition/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 756 # by problem number
lcpy gen -s pyramid_transition # by problem name
```
## Problem
You are stacking blocks to form a pyramid. Each block has a color, which is represented by a single letter. Each row of blocks contains **one less block** than the row beneath it and is centered on top.
To make the pyramid aesthetically pleasing, there are only specific **triangular patterns** that are allowed. A triangular pattern consists of a **single block** stacked on top of **two blocks**. The patterns are given as a list of three-letter strings `allowed`, where the first two characters of a pattern represent the left and right bottom blocks respectively, and the third character is the top block.
* For example, `"ABC"` represents a triangular pattern with a `'C'` block stacked on top of an `'A'` (left) and `'B'` (right) block. Note that this is different from `"BAC"` where `'B'` is on the left bottom and `'A'` is on the right bottom.
You start with a bottom row of blocks `bottom`, given as a single string, that you **must** use as the base of the pyramid.
Given `bottom` and `allowed`, return `true` if you can build the pyramid all the way to the top such that **every triangular pattern** in the pyramid is in `allowed`, or `false` otherwise.
### Examples

```
Input: bottom = "BCD", allowed = ["BCC","CDE","CEA","FFF"]
Output: true
```
**Explanation:** The allowed triangular patterns are shown on the right.
Starting from the bottom (level 3), we can build "CE" on level 2 and then build "A" on level 1.
There are three triangular patterns in the pyramid, which are "BCC", "CDE", and "CEA". All are allowed.

```
Input: bottom = "AAAA", allowed = ["AAB","AAC","BCD","BBE","DEF"]
Output: false
```
**Explanation:** The allowed triangular patterns are shown on the right.
Starting from the bottom (level 4), there are multiple ways to build level 3, but trying all the possibilites, you will get always stuck before building level 1.
### Constraints
* `2 <= bottom.length <= 6`
* `0 <= allowed.length <= 216`
* `allowed[i].length == 3`
* The letters in all input strings are from the set `{'A', 'B', 'C', 'D', 'E', 'F'}`.
* All the values of `allowed` are **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pyramid_transition/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/pyramid_transition/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from itertools import product
class Solution:
# Time: O(k^(n-1)) states memoized by row; n <= 6 so bounded by 6^5 rows
# Space: O(k^(n-1)) for the memo set of dead rows
def pyramid_transition(self, bottom: str, allowed: list[str]) -> bool:
tops: dict[str, list[str]] = {}
for pattern in allowed:
tops.setdefault(pattern[:2], []).append(pattern[2])
dead: set[str] = set()
def dfs(row: str) -> bool:
if len(row) == 1:
return True
if row in dead:
return False
dead.add(row)
options = [tops.get(row[i : i + 2], ()) for i in range(len(row) - 1)]
return any(dfs("".join(level)) for level in product(*options))
return dfs(bottom)
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------- | ---------------------------------------- |
| O(k^(n-1)) states memoized by row; n \<= 6 so bounded by 6^5 rows | O(k^(n-1)) for the memo set of dead rows |
## Tags
# Queue Reconstruction by Height Python Solution
Source: https://leetcode-py.wisl.dev/problems/queue-reconstruction-by-height
Tested Python solution for LeetCode 406 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 406, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/queue-reconstruction-by-height/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 406 # by problem number
lcpy gen -s queue_reconstruction_by_height # by problem name
```
## Problem
You are given an array of people, `people`, which are the attributes of some people in a queue (not necessarily in order). Each `people[i] = [hi, ki]` represents the i\th\ person of height `hi` with exactly `ki` other people in front who have a height greater than or equal to `hi`.
Reconstruct and return the queue that is represented by the input array `people`. The returned queue should be formatted as an array `queue`, where `queue[j] = [hj, kj]` is the attributes of the j\th\ person in the queue (`queue[0]` is the person at the front of the queue).
### Examples
```
Input: people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
Output: [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
```
**Explanation:**
* Person 0 has height 5 with no other people taller or the same height in front.
* Person 1 has height 7 with no other people taller or the same height in front.
* Person 2 has height 5 with two persons taller or the same height in front, which is person 0 and 1.
* Person 3 has height 6 with one person taller or the same height in front, which is person 1.
* Person 4 has height 4 with four people taller or the same height in front, which are people 0, 1, 2, and 3.
* Person 5 has height 7 with one person taller or the same height in front, which is person 1.
Hence `[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]` is the reconstructed queue.
```
Input: people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
Output: [[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]
```
### Constraints
* `1 <= people.length <= 2000`
* `0 <= hi <= 10^6`
* `0 <= ki < people.length`
* It is guaranteed that the queue can be reconstructed.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/queue_reconstruction_by_height/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/queue_reconstruction_by_height/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2) (n <= 2000, insertion into a list is linear)
# Space: O(n)
def reconstruct_queue(self, people: list[list[int]]) -> list[list[int]]:
# Tall first (so later, shorter insertions cannot invalidate earlier
# placements), then fewest taller-in-front first; insert at index k.
ordered = sorted(people, key=lambda p: (-p[0], p[1]))
queue: list[list[int]] = []
for height, k in ordered:
queue.insert(k, [height, k])
return queue
```
## Complexity
| Time | Space |
| ---------------------------------------------------- | ----- |
| O(n^2) (n \<= 2000, insertion into a list is linear) | O(n) |
## Tags
# Rabbits in Forest Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/rabbits-in-forest
Tested Python solution for LeetCode 781 with 47 pytest cases. Generate a practice environment with lcpy.
LeetCode 781, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/rabbits-in-forest/description/).
Generate this problem as a practice environment: tested reference solution, 47 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 781 # by problem number
lcpy gen -s rabbits_in_forest # by problem name
```
## Problem
There is a forest with an unknown number of rabbits. We asked n rabbits **"How many other rabbits have the same color as you?"** and collected the answers in an integer array `answers` where `answers[i]` is the answer of the `ith` rabbit.
Given the array `answers`, return *the minimum number of rabbits that could be in the forest*.
### Examples
```
Input: answers = [1,1,2]
Output: 5
Explanation:
The two rabbits that answered "1" could both be the same color, say red.
The rabbit that answered "2" can't be red or the answers would be inconsistent.
Say the rabbit that answered "2" was blue.
Then there should be 2 other blue rabbits in the forest that didn't answer into the array.
The smallest possible number of rabbits in the forest is therefore 5: 3 that answered plus 2 that didn't.
```
```
Input: answers = [10,10,10]
Output: 11
```
### Constraints
* `1 <= answers.length <= 1000`
* `0 <= answers[i] < 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rabbits_in_forest/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rabbits_in_forest/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(k)
def num_rabbits(self, answers: list[int]) -> int:
total = 0
for answer, count in Counter(answers).items():
group_size = answer + 1
total += -(-count // group_size) * group_size
return total
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(k) |
## Tags
# Race Car Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/race-car
Tested Python solution for LeetCode 818 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 818, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), Heuristic Search, A\* Search. [View on LeetCode](https://leetcode.com/problems/race-car/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 818 # by problem number
lcpy gen -s race_car # by problem name
```
## Problem
Your car starts at position `0` and speed `+1` on an infinite number line. Your car can go into negative positions. Your car drives automatically according to a sequence of instructions `'A'` (accelerate) and `'R'` (reverse):
* When you get an instruction `'A'`, your car does the following:
* `position += speed`
* `speed *= 2`
* When you get an instruction `'R'`, your car does the following:
* If your speed is positive then `speed = -1`
* otherwise `speed = 1`
Your position stays the same.
For example, after commands `'AAR'`, your car goes to positions `0 --> 1 --> 3 --> 3`, and your speed goes to `1 --> 2 --> 4 --> -1`.
Given a target position `target`, return *the length of the shortest sequence of instructions to get there*.
### Examples
```
Input: target = 3
Output: 2
```
**Explanation:** The shortest instruction sequence is `'AA'`. Your position goes from `0 --> 1 --> 3`.
```
Input: target = 6
Output: 5
```
**Explanation:** The shortest instruction sequence is `'AAARA'`. Your position goes from `0 --> 1 --> 3 --> 7 --> 7 --> 6`.
### Constraints
* 1 \<= target \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/race_car/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/race_car/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(target * log(target))
# Space: O(target)
def racecar(self, target: int) -> int:
dp = [0] * (target + 1)
for t in range(1, target + 1):
k = t.bit_length()
if t == 2**k - 1:
dp[t] = k
continue
best = k + 1 + dp[2**k - 1 - t]
for j in range(k - 1):
nxt = t - 2 ** (k - 1) + 2**j
best = min(best, k + j + 1 + dp[nxt])
dp[t] = best
return dp[target]
```
## Complexity
| Time | Space |
| ------------------------ | --------- |
| O(target \* log(target)) | O(target) |
## Tags
# Random Flip Matrix Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/random-flip-matrix
Tested Python solution for LeetCode 519 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 519, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), Reservoir Sampling, Randomized. [View on LeetCode](https://leetcode.com/problems/random-flip-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 519 # by problem number
lcpy gen -s random_flip_matrix # by problem name
```
## Problem
There is an `m x n` binary grid `matrix` with all the values set `0` initially. Design an algorithm to randomly pick an index `(i, j)` where `matrix[i][j] == 0` and flips it to `1`. All the indices `(i, j)` where `matrix[i][j] == 0` should be equally likely to be returned.
Optimize your algorithm to minimize the number of calls made to the **built-in** random function of your language and optimize the time and space complexity.
Implement the `Solution` class:
* `Solution(int m, int n)` Initializes the object with the size of the binary matrix `m` and `n`.
* `int[] flip()` Returns a random index `[i, j]` of the matrix where `matrix[i][j] == 0` and flips it to `1`.
* `void reset()` Resets all the values of the matrix to be `0`.
### Examples
```
Input
["Solution", "flip", "flip", "flip", "reset", "flip"]
[[3, 1], [], [], [], [], []]
Output
[null, [1, 0], [2, 0], [0, 0], null, [2, 0]]
Explanation
Solution solution = new Solution(3, 1);
solution.flip(); // return [1, 0], [0,0], [1,0], and [2,0] should be equally likely to be returned.
solution.flip(); // return [2, 0], Since [1,0] was returned, [2,0] and [0,0]
solution.flip(); // return [0, 0], Based on the previously returned indices, only [0,0] can be returned.
solution.reset(); // All the values are reset to 0 and can be returned.
solution.flip(); // return [2, 0], [0,0], [1,0], and [2,0] should be equally likely to be returned.
```
### Constraints
* `1 <= m, n <= 10^4`
* There will be at least one free cell for each call to `flip`.
* At most `1000` calls will be made to `flip` and `reset`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_flip_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_flip_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
class Solution:
# Time: __init__ O(1), flip O(1), reset O(1)
# Space: O(k) where k is the number of flips since the last reset
def __init__(self, m: int, n: int) -> None:
self.m = m
self.n = n
self.total = m * n
self.available = self.total
self.swapped: dict[int, int] = {}
def flip(self) -> list[int]:
idx = random.randrange(self.available)
self.available -= 1
picked = self.swapped.get(idx, idx)
self.swapped[idx] = self.swapped.get(self.available, self.available)
return [picked // self.n, picked % self.n]
def reset(self) -> None:
self.available = self.total
self.swapped = {}
```
## Complexity
| Time | Space |
| ------------------------------------ | -------------------------------------------------------- |
| **init** O(1), flip O(1), reset O(1) | O(k) where k is the number of flips since the last reset |
## Tags
# Random Pick Index Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/random-pick-index
Tested Python solution for LeetCode 398 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 398, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), Reservoir Sampling, Randomized. [View on LeetCode](https://leetcode.com/problems/random-pick-index/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 398 # by problem number
lcpy gen -s random_pick_index # by problem name
```
## Problem
Given an integer array `nums` with possible **duplicates**, randomly output the index of a given `target` number. You can assume that the given target number must exist in the array.
Implement the `Solution` class:
* `Solution(int[] nums)` Initializes the object with the array `nums`.
* `int pick(int target)` Picks a random index `i` from `nums` where `nums[i] == target`. If there are multiple valid `i`'s, then each index should have an equal probability of returning.
### Examples
```
Input
["Solution", "pick", "pick", "pick"]
[[[1, 2, 3, 3, 3]], [3], [1], [3]]
Output
[null, 4, 0, 2]
Explanation
Solution solution = new Solution([1, 2, 3, 3, 3]);
solution.pick(3); // It should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
solution.pick(1); // It should return 0. Since in the array only nums[0] is equal to 1.
solution.pick(3); // It should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
```
### Constraints
* `1 <= nums.length <= 2 * 10^4`
* `-2^31 <= nums[i] <= 2^31 - 1`
* `target` is an integer from `nums`.
* At most `10^4` calls will be made to `pick`.
**Follow up:** What is the time and space complexity of your solution? Could you do it with `O(1)` extra space?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_pick_index/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_pick_index/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
from collections import defaultdict
class Solution:
# Time: O(n) init, O(1) pick
# Space: O(n)
def __init__(self, nums: list[int]) -> None:
self.indices: dict[int, list[int]] = defaultdict(list)
for i, num in enumerate(nums):
self.indices[num].append(i)
def pick(self, target: int) -> int:
return random.choice(self.indices[target])
```
## Complexity
| Time | Space |
| -------------------- | ----- |
| O(n) init, O(1) pick | O(n) |
## Tags
# Random Pick with Blacklist Python Solution
Source: https://leetcode-py.wisl.dev/problems/random-pick-with-blacklist
Tested Python solution for LeetCode 710 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 710, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting), Randomized. [View on LeetCode](https://leetcode.com/problems/random-pick-with-blacklist/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 710 # by problem number
lcpy gen -s random_pick_with_blacklist # by problem name
```
## Problem
You are given an integer `n` and an array of **unique** integers `blacklist`. Design an algorithm to pick a random integer in the range `[0, n - 1]` that is **not** in `blacklist`. Any integer that is in the mentioned range and not in `blacklist` should be **equally likely** to be returned.
Optimize your algorithm such that it minimizes the number of calls to the **built-in** random function of your language.
Implement the `Solution` class:
* `Solution(int n, int[] blacklist)` Initializes the object with the integer `n` and the blacklisted integers `blacklist`.
* `int pick()` Returns a random integer in the range `[0, n - 1]` and not in `blacklist`.
### Examples
```
Input
["Solution", "pick", "pick", "pick", "pick", "pick", "pick", "pick"]
[[7, [2, 3, 5]], [], [], [], [], [], [], []]
Output
[null, 0, 4, 1, 6, 1, 0, 4]
Explanation
Solution solution = new Solution(7, [2, 3, 5]);
solution.pick(); // return 0, any integer from [0,1,4,6] should be ok. Note that for every call of pick,
// 0, 1, 4, and 6 must be equally likely to be returned (i.e., with probability 1/4).
solution.pick(); // return 4
solution.pick(); // return 1
solution.pick(); // return 6
solution.pick(); // return 1
solution.pick(); // return 0
solution.pick(); // return 4
```
### Constraints
* `1 <= n <= 10^9`
* `0 <= blacklist.length <= min(10^5, n - 1)`
* `0 <= blacklist[i] < n`
* All the values of `blacklist` are **unique**.
* At most `2 * 10^4` calls will be made to `pick`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_pick_with_blacklist/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_pick_with_blacklist/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
class Solution:
# Time: O(b) init, O(1) pick
# Space: O(b)
def __init__(self, n: int, blacklist: list[int]) -> None:
self.size = n - len(blacklist)
black = set(blacklist)
tail = [x for x in range(self.size, n) if x not in black]
self.remap: dict[int, int] = {}
for i, b in enumerate(sorted(b for b in black if b < self.size)):
self.remap[b] = tail[i]
def pick(self) -> int:
idx = random.randint(0, self.size - 1)
return self.remap.get(idx, idx)
```
## Complexity
| Time | Space |
| -------------------- | ----- |
| O(b) init, O(1) pick | O(b) |
## Tags
# Random Pick with Weight Python Solution
Source: https://leetcode-py.wisl.dev/problems/random-pick-with-weight
Tested Python solution for LeetCode 528 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 528, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/random-pick-with-weight/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 528 # by problem number
lcpy gen -s random_pick_with_weight # by problem name
```
## Problem
You are given a **0-indexed** array of positive integers `w` where `w[i]` describes the weight of the `i^th` index.
You need to implement the function `pick_index()`, which **randomly** picks an index in the range `[0, w.length - 1]` (**inclusive**) and returns it. The **probability** of picking an index `i` is `w[i] / sum(w)`.
* For example, if `w = [1, 3]`, the probability of picking index `0` is `1 / (1 + 3) = 0.25` (i.e., `25%`), and the probability of picking index `1` is `3 / (1 + 3) = 0.75` (i.e., `75%`).
### Examples
```
Input
["Solution","pickIndex"]
[[[1]],[]]
Output
[null,0]
Explanation
Solution solution = new Solution([1]);
solution.pickIndex(); // return 0. The only option is to return 0 since there is only one element in w.
```
```
Input
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output
[null,1,1,1,1,0]
Explanation
Solution solution = new Solution([1, 3]);
solution.pickIndex(); // return 1. It is returning the second element (index = 1) that has a probability of 3/4.
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 0. It is returning the first element (index = 0) that has a probability of 1/4.
Since this is a randomization problem, multiple answers are allowed.
```
### Constraints
* 1 \<= w\.length \<= 10^4
* 1 \<= w\[i] \<= 10^5
* `pickIndex` will be called at most 10^4 times.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_pick_with_weight/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_pick_with_weight/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import bisect
import random
class Solution:
# Build prefix sums of weights. pick_index draws r in [1, total],
# binary search for first prefix >= r. Each index i chosen with prob w[i]/sum.
# Time: O(n) init, O(log n) pick_index
# Space: O(n)
def __init__(self, w: list[int]) -> None:
self.prefix: list[int] = []
running = 0
for weight in w:
running += weight
self.prefix.append(running)
self.total = running
def pick_index(self) -> int:
r = random.randint(1, self.total)
return bisect.bisect_left(self.prefix, r)
```
## Complexity
| Time | Space |
| ------------------------------- | ----- |
| O(n) init, O(log n) pick\_index | O(n) |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Random Point in Non-overlapping Rectangles
Source: https://leetcode-py.wisl.dev/problems/random-point-in-non-overlapping-rectangles
Tested Python solution for LeetCode 497 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 497, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search), Reservoir Sampling, [Prefix Sum](/catalog/topics/prefix-sum), Randomized. [View on LeetCode](https://leetcode.com/problems/random-point-in-non-overlapping-rectangles/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 497 # by problem number
lcpy gen -s random_point_in_non_overlapping_rectangles # by problem name
```
## Problem
You are given an array of non-overlapping axis-aligned rectangles `rects` where `rects[i] = [ai, bi, xi, yi]` indicates that `(ai, bi)` is the bottom-left corner point of the `ith` rectangle and `(xi, yi)` is the top-right corner point of the `ith` rectangle. Design an algorithm to pick a random integer point inside the space covered by one of the given rectangles. A point on the perimeter of a rectangle is included in the space covered by the rectangle.
Any integer point inside the space covered by one of the given rectangles should be equally likely to be returned.
Note that an integer point is a point that has integer coordinates.
Implement the `Solution` class:
* `Solution(int[][] rects)` Initializes the object with the given rectangles `rects`.
* `int[] pick()` Returns a random integer point `[u, v]` inside the space covered by one of the given rectangles.
### Examples

```
Input
["Solution", "pick", "pick", "pick", "pick", "pick"]
[[[[-2, -2, 1, 1], [2, 2, 4, 6]]], [], [], [], [], []]
Output
[null, [1, -2], [1, -1], [-1, -2], [-2, -2], [0, 0]]
Explanation
Solution solution = new Solution([[-2, -2, 1, 1], [2, 2, 4, 6]]);
solution.pick(); // return [1, -2]
solution.pick(); // return [1, -1]
solution.pick(); // return [-1, -2]
solution.pick(); // return [-2, -2]
solution.pick(); // return [0, 0]
```
### Constraints
* `1 <= rects.length <= 100`
* `rects[i].length == 4`
* `-10^9 <= ai < xi <= 10^9`
* `-10^9 <= bi < yi <= 10^9`
* `xi - ai <= 2000`
* `yi - bi <= 2000`
* All the rectangles do not overlap.
* At most `10^4` calls will be made to `pick`.
**Follow up:** What is the time and space complexity of your solution? Could you do it with `O(log n)` pick time using binary search?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_point_in_non_overlapping_rectangles/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/random_point_in_non_overlapping_rectangles/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import random
from bisect import bisect_right
class Solution:
# Weight the rectangles by their integer-point counts with a prefix sum,
# draw a uniform offset into the total, bisect to the owning rectangle and
# map the leftover offset onto a (col, row) inside it. Every integer point
# (perimeter included) gets exactly one offset, so points are uniform.
# Time: __init__ O(n), pick O(log n)
# Space: O(n)
def __init__(self, rects: list[list[int]]) -> None:
self._rects = rects
self._prefix: list[int] = []
total = 0
for a, b, x, y in rects:
total += (x - a + 1) * (y - b + 1)
self._prefix.append(total)
self._total = total
def pick(self) -> list[int]:
target = random.randrange(self._total)
idx = bisect_right(self._prefix, target)
base = self._prefix[idx - 1] if idx else 0
a, b, x, _ = self._rects[idx]
width = x - a + 1
offset = target - base
return [a + offset % width, b + offset // width]
```
## Complexity
| Time | Space |
| ---------------------------- | ----- |
| **init** O(n), pick O(log n) | O(n) |
## Tags
# Range Addition Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/range-addition
Tested Python solution for LeetCode 370 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 370, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/range-addition/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 370 # by problem number
lcpy gen -s range_addition # by problem name
```
## Problem
You are given an integer `length` and an array `updates` where `updates[i] = [startIdx_i, endIdx_i, inc_i]`.
You have an array `arr` of length `length` with all zeros, and you have some operation to apply on `arr`. In the `i^th` operation, you should increment all the elements `arr[startIdx_i], arr[startIdx_i + 1], ..., arr[endIdx_i]` by `inc_i`.
Return `arr` *after applying all the* `updates`.
### Examples

```
Input: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]
Output: [-2,0,3,5,3]
```
```
Input: length = 10, updates = [[2,4,6],[5,6,8],[1,9,-4]]
Output: [0,-4,2,2,2,4,4,-4,-4,-4]
```
### Constraints
* `1 <= length <= 10^5`
* `0 <= updates.length <= 10^4`
* `0 <= startIdx_i <= endIdx_i < length`
* `-1000 <= inc_i <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/range_addition/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/range_addition/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + k) for k updates
# Space: O(1) extra (excluding output)
def get_modified_array(self, length: int, updates: list[list[int]]) -> list[int]:
diff = [0] * (length + 1)
for start, end, inc in updates:
diff[start] += inc
diff[end + 1] -= inc
result = [0] * length
running = 0
for i in range(length):
running += diff[i]
result[i] = running
return result
```
## Complexity
| Time | Space |
| ---------------------- | ----------------------------- |
| O(n + k) for k updates | O(1) extra (excluding output) |
## Tags
# Range Addition II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/range-addition-ii
Tested Python solution for LeetCode 598 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 598, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/range-addition-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 598 # by problem number
lcpy gen -s range_addition_ii # by problem name
```
## Problem
You are given an `m x n` matrix `M` initialized with all `0`'s and an array of operations `ops`, where `ops[i] = [ai, bi]` means `M[x][y]` should be incremented by one for all `0 <= x < ai` and `0 <= y < bi`.
Count and return *the number of maximum integers in the matrix after performing all the operations*.
### Examples

```
Input: m = 3, n = 3, ops = [[2,2],[3,3]]
Output: 4
Explanation: The maximum integer in M is 2, and there are four of it in M. So return 4.
```
```
Input: m = 3, n = 3, ops = [[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3]]
Output: 4
```
```
Input: m = 3, n = 3, ops = []
Output: 9
```
### Constraints
* 1 \<= m, n \<= 4 \* 10^4
* 0 \<= ops.length \<= 10^4
* ops\[i].length == 2
* 1 \<= ai \<= m
* 1 \<= bi \<= n
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/range_addition_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/range_addition_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(ops))
# Space: O(1)
def max_count(self, m: int, n: int, ops: list[list[int]]) -> int:
if not ops:
return m * n
min_a = min(op[0] for op in ops)
min_b = min(op[1] for op in ops)
return min_a * min_b
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(len(ops)) | O(1) |
## Tags
# Range Module Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/range-module
Tested Python solution for LeetCode 715 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 715, [Hard](/catalog/hard). Topics: [Design](/catalog/topics/design), [Segment Tree](/catalog/topics/segment-tree), [Ordered Set](/catalog/topics/ordered-set). [View on LeetCode](https://leetcode.com/problems/range-module/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 715 # by problem number
lcpy gen -s range_module # by problem name
```
## Problem
A Range Module is a module that tracks ranges of numbers. Design a data structure to track the ranges represented as half-open intervals and query about them.
A half-open interval `[left, right)` denotes all the real numbers `x` where `left <= x < right`.
Implement the `RangeModule` class:
* `RangeModule()` Initializes the object of the data structure.
* `void addRange(int left, int right)` Adds the half-open interval `[left, right)`, tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval `[left, right)` that are not already tracked.
* `boolean queryRange(int left, int right)` Returns `true` if every real number in the interval `[left, right)` is currently being tracked, and `false` otherwise.
* `void removeRange(int left, int right)` Stops tracking every real number currently being tracked in the half-open interval `[left, right)`.
### Examples
```
Input
["RangeModule", "addRange", "removeRange", "queryRange", "queryRange", "queryRange"]
[[], [10, 20], [14, 16], [10, 14], [13, 15], [16, 17]]
Output
[null, null, null, true, false, true]
Explanation
RangeModule rangeModule = new RangeModule();
rangeModule.addRange(10, 20);
rangeModule.removeRange(14, 16);
rangeModule.queryRange(10, 14); // return True, (Every number in [10, 14) is being tracked)
rangeModule.queryRange(13, 15); // return False, (Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked)
rangeModule.queryRange(16, 17); // return True, (The number 16 in [16, 17) is still being tracked, despite the remove operation)
```
### Constraints
* `1 <= left < right <= 10^9`
* At most `10^4` calls will be made to `addRange`, `queryRange`, and `removeRange`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/range_module/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/range_module/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_left, bisect_right
class RangeModule:
# Time: add/remove O(n) per call, query O(log n)
# Space: O(n) for the tracked disjoint intervals
def __init__(self) -> None:
# Parallel sorted arrays describing disjoint, non-adjacent half-open
# intervals: the i-th tracked range is [starts[i], ends[i]).
self.starts: list[int] = []
self.ends: list[int] = []
# Time: O(n)
# Space: O(n)
def add_range(self, left: int, right: int) -> None:
# First interval whose end reaches left, and first interval that
# starts at or after right: every interval in between overlaps and
# must be absorbed into the merged range.
i = bisect_left(self.ends, left)
j = bisect_left(self.starts, right)
if i < j:
left = min(left, self.starts[i])
right = max(right, self.ends[j - 1])
self.starts[i:j] = [left]
self.ends[i:j] = [right]
# Time: O(log n)
# Space: O(1)
def query_range(self, left: int, right: int) -> bool:
i = bisect_right(self.starts, left) - 1
return i >= 0 and self.ends[i] >= right
# Time: O(n)
# Space: O(n)
def remove_range(self, left: int, right: int) -> None:
i = bisect_left(self.ends, left)
j = bisect_left(self.starts, right)
if i >= j:
return
kept: list[tuple[int, int]] = []
if self.starts[i] < left:
kept.append((self.starts[i], left))
if self.ends[j - 1] > right:
kept.append((right, self.ends[j - 1]))
self.starts[i:j] = [start for start, _ in kept]
self.ends[i:j] = [end for _, end in kept]
```
## Complexity
| Time | Space |
| ---------------------------------------- | --------------------------------------- |
| add/remove O(n) per call, query O(log n) | O(n) for the tracked disjoint intervals |
## Tags
# Range Sum of BST Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/range-sum-of-bst
Tested Python solution for LeetCode 938 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 938, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/range-sum-of-bst/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 938 # by problem number
lcpy gen -s range_sum_of_bst # by problem name
```
## Problem
\
Given the \root\ node of a binary search tree and two integers \low\ and \high\, return \the sum of values of all nodes with a value in the \inclusive\ range \\\[low, high]\.\
\[1, 2 \* 10^4]\.\1 \<= Node.val \<= 10^5\\1 \<= low \<= high \<= 10^5\\Node.val\ are \unique\.\You are given the array \nums\ consisting of \n\ positive integers. You computed the sum of all non-empty continuous subarrays from the array and then sorted them in non-decreasing order, creating a new array of \n \* (n + 1) / 2\ numbers.\
\Return the sum of the numbers from index \\left\\ to index \\right\ (\indexed from 1\)\, inclusive, in the new array. \Since the answer can be a huge number return it modulo \10\9\ + 7\.\
n == nums.length\\1 \<= nums.length \<= 1000\\1 \<= nums\[i] \<= 100\\1 \<= left \<= right \<= n \* (n + 1) / 2\\arr1\ and \arr2\, the elements of \arr2\ are distinct, and all elements in \arr2\ are also in \arr1\.
Sort the elements of \arr1\ such that the relative ordering of items in \arr1\ are the same as in \arr2\. Elements that do not appear in \arr2\ should be placed at the end of \arr1\ in \ascending\ order.
### Examples
```
Input: arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
Output: [2,2,2,1,4,3,3,9,6,7,19]
```
```
Input: arr1 = [28,6,22,8,44,17], arr2 = [22,28,8,6]
Output: [22,28,8,6,17,44]
```
### Constraints
* \1 \<= arr1.length, arr2.length \<= 1000\
* \0 \<= arr1\[i], arr2\[i] \<= 1000\
* All the elements of \arr2\ are \distinct\.
* Each \arr2\[i]\ is in \arr1\.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/relative_sort_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/relative_sort_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def relative_sort_array(self, arr1: list[int], arr2: list[int]) -> list[int]:
rank = {v: i for i, v in enumerate(arr2)}
present = sorted((x for x in arr1 if x in rank), key=lambda x: rank[x])
rest = sorted(x for x in arr1 if x not in rank)
return present + rest
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove 9 Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/remove-9
Tested Python solution for LeetCode 660 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 660, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/remove-9/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 660 # by problem number
lcpy gen -s remove_9 # by problem name
```
## Problem
Start from integer `1`, remove any integer that contains `9` such as `9`, `19`, `29`...
Now, you will have a new integer sequence `[1, 2, 3, 4, 5, 6, 7, 8, 10, 11, ...]`.
Given an integer `n`, return *the* `n^th` (**1-indexed**) integer in the new sequence.
### Examples
```
Input: n = 9
Output: 10
```
```
Input: n = 10
Output: 11
```
### Constraints
* 1 \<= n \<= 8 \* 10^8
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_9/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_9/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(log n)
def new_integer(self, n: int) -> int:
result = 0
place = 1
while n > 0:
result += (n % 9) * place
place *= 10
n //= 9
return result
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(log n) | O(log n) |
## Tags
# Remove All Adjacent Duplicates in String II
Source: https://leetcode-py.wisl.dev/problems/remove-all-adjacent-duplicates-in-string-ii
Tested Python solution for LeetCode 1209 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1209, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/remove-all-adjacent-duplicates-in-string-ii/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1209 # by problem number
lcpy gen -s remove_all_adjacent_duplicates_in_string_ii # by problem name
```
## Problem
You are given a string `s` and an integer `k`, a `k` **duplicate removal** consists of choosing `k` adjacent and equal letters from `s` and removing them, causing the left and the right side of the deleted substring to concatenate together.
We repeatedly make `k` **duplicate removals** on `s` until we no longer can.
Return *the final string after all such duplicate removals have been made*. It is guaranteed that the answer is **unique**.
### Examples
```
Input: s = "abcd", k = 2
Output: "abcd"
Explanation: There's nothing to delete.
```
```
Input: s = "deeedbbcccbdaa", k = 3
Output: "aa"
Explanation: First delete "eee" and "ccc", get "ddbbbdaa"
Then delete "bbb", get "dddaa"
Finally delete "ddd", get "aa"
```
```
Input: s = "pbbcggttciiippooaais", k = 2
Output: "ps"
```
### Constraints
* `1 <= s.length <= 10^5`
* `2 <= k <= 10^4`
* `s` only contains lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_all_adjacent_duplicates_in_string_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_all_adjacent_duplicates_in_string_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(s))
# Space: O(len(s))
def remove_duplicates(self, s: str, k: int) -> str:
stack: list[tuple[str, int]] = []
for char in s:
if stack and stack[-1][0] == char:
char, count = stack[-1]
if count + 1 == k:
stack.pop()
else:
stack[-1] = (char, count + 1)
else:
stack.append((char, 1))
return "".join(char * count for char, count in stack)
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(len(s)) | O(len(s)) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Boxes Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/remove-boxes
Tested Python solution for LeetCode 546 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 546, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Memoization](/catalog/topics/memoization). [View on LeetCode](https://leetcode.com/problems/remove-boxes/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 546 # by problem number
lcpy gen -s remove_boxes # by problem name
```
## Problem
You are given several boxes with different colors represented by different positive numbers.
You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (i.e., composed of `k` boxes, `k >= 1`), remove them and get `k * k` points.
Return *the maximum points you can get*.
### Examples
```
Input: boxes = [1,3,2,2,2,3,4,3,1]
Output: 23
Explanation:
[1, 3, 2, 2, 2, 3, 4, 3, 1]
----> [1, 3, 3, 4, 3, 1] (3*3=9 points)
----> [1, 3, 3, 3, 1] (1*1=1 points)
----> [1, 1] (3*3=9 points)
----> [] (2*2=4 points)
```
```
Input: boxes = [1,1,1]
Output: 9
```
```
Input: boxes = [1]
Output: 1
```
### Constraints
* `1 <= boxes.length <= 100`
* `1 <= boxes[i] <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_boxes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_boxes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cache
class Solution:
# Time: O(n^4) worst case, Space: O(n^3)
def remove_boxes(self, boxes: list[int]) -> int:
@cache
def dp(left: int, right: int, k: int) -> int:
if left > right:
return 0
# Grow the leftmost run so boxes[left..end] share one color.
end = left
while end + 1 <= right and boxes[end + 1] == boxes[end]:
end += 1
attached = k + (end - left + 1)
best = attached * attached + dp(end + 1, right, 0)
for mid in range(end + 1, right + 1):
if boxes[mid] == boxes[left] and boxes[mid - 1] != boxes[mid]:
best = max(
best,
dp(end + 1, mid - 1, 0) + dp(mid, right, attached),
)
return best
return dp(0, len(boxes) - 1, 0)
```
## Complexity
| Time | Space |
| -------------------------------- | ----- |
| O(n^4) worst case, Space: O(n^3) | - |
## Tags
# Remove Colored Pieces if Both Neighbors are
Source: https://leetcode-py.wisl.dev/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color
Tested Python solution for LeetCode 2038 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 2038, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2038 # by problem number
lcpy gen -s remove_colored_pieces_if_both_neighbors_are_the_same_color # by problem name
```
## Problem
There are n pieces arranged in a line, and each piece is colored either by 'A' or by 'B'. You are given a string colors of length n where colors\[i] is the color of the ith piece.
Alice and Bob are playing a game where they take alternating turns removing pieces from the line. In this game, Alice moves first.
Alice is only allowed to remove a piece colored 'A' if both its neighbors are also colored 'A'. She is not allowed to remove pieces that are colored 'B'.
Bob is only allowed to remove a piece colored 'B' if both its neighbors are also colored 'B'. He is not allowed to remove pieces that are colored 'A'.
Alice and Bob cannot remove pieces from the edge of the line.
If a player cannot make a move on their turn, that player loses and the other player wins.
Assuming Alice and Bob play optimally, return true if Alice wins, or return false if Bob wins.
### Examples
```
Input: colors = "AAABABB"
Output: true
Explanation: AAABABB -> AABABB
Alice moves first.
She removes the second 'A' from the left since that is the only 'A' whose neighbors are both 'A'.
Now it's Bob's turn.
Bob cannot make a move on his turn since there are no 'B's whose neighbors are both 'B'.
Thus, Alice wins, so return true.
```
```
Input: colors = "AA"
Output: false
Explanation: Alice has her turn first.
There are only two 'A's and both are on the edge of the line, so she cannot move on her turn.
Thus, Bob wins, so return false.
```
```
Input: colors = "ABBBBBBBAAA"
Output: false
Explanation: ABBBBBBBAAA -> ABBBBBBBAA
Alice moves first.
Her only option is to remove the second to last 'A' from the right.
ABBBBBBBAA -> ABBBBBBAA
Next is Bob's turn.
He has many options for which 'B' piece to remove. He can pick any.
On Alice's second turn, she has no more pieces that she can remove.
Thus, Bob wins, so return false.
```
### Constraints
* 1 \<= colors.length \<= 10^5
* colors consists of only the letters 'A' and 'B'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_colored_pieces_if_both_neighbors_are_the_same_color/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_colored_pieces_if_both_neighbors_are_the_same_color/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def winner_of_game(self, colors: str) -> bool:
alice = 0
bob = 0
for i in range(1, len(colors) - 1):
if colors[i - 1] == colors[i] == colors[i + 1]:
if colors[i] == "A":
alice += 1
else:
bob += 1
return alice > bob
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Comments Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/remove-comments
Tested Python solution for LeetCode 722 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 722, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/remove-comments/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 722 # by problem number
lcpy gen -s remove_comments # by problem name
```
## Problem
Given a C++ program, remove comments from it. The program source is an array of strings `source` where `source[i]` is the `ith` line of the source code. This represents the result of splitting the original source code string by the newline character `'\n'`.
In C++, there are two types of comments, line comments, and block comments.
* The string `"//"` denotes a line comment, which represents that it and the rest of the characters to the right of it in the same line should be ignored.
* The string `"/*"` denotes a block comment, which represents that all characters until the next (non-overlapping) occurrence of `"*/"` should be ignored. (Here, occurrences happen in reading order: line by line from left to right.) To be clear, the string `"/*/"` does not yet end the block comment, as the ending would be overlapping the beginning.
The first effective comment takes precedence over others.
* For example, if the string `"//"` occurs in a block comment, it is ignored.
* Similarly, if the string `"/*"` occurs in a line or block comment, it is also ignored.
If a certain line of code is empty after removing comments, you must not output that line: each string in the answer list will be non-empty.
There will be no control characters, single quote, or double quote characters.
* For example, `source = "string s = "/* Not a comment. */";"` will not be a test case.
Also, nothing else such as defines or macros will interfere with the comments.
It is guaranteed that every open block comment will eventually be closed, so `"/*"` outside of a line or block comment always starts a new comment.
Finally, implicit newline characters can be deleted by block comments. Please see the examples below for details.
After removing the comments from the source code, return \the source code in the same format\.
### Examples
```
Input: source = ["/*Test program */", "int main()", "{ ", " // variable declaration ", "int a, b, c;", "/* This is a test", " multiline ", " comment for ", " testing */", "a = b + c;", "}"]
Output: ["int main()","{ "," ","int a, b, c;","a = b + c;","}"]
Explanation: The string /* denotes a block comment, including line 1 and lines 6-9. The string // denotes line 4 as comments. The line by line output code is visualized as below:
int main()
{
int a, b, c;
a = b + c;
}
```
```
Input: source = ["a/*comment", "line", "more_comment*/b"]
Output: ["ab"]
Explanation: The original source string is "a/*comment\nline\nmore_comment*/b". After deletion, the implicit newline characters are deleted, leaving the string "ab", which when delimited by newline characters becomes ["ab"].
```
### Constraints
* 1 \<= source.length \<= 100
* 0 \<= source\[i].length \<= 80
* source\[i] consists of printable ASCII characters.
* Every open block comment is eventually closed.
* There are no single-quote or double-quote in the input.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_comments/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_comments/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) over the total number of characters
# Space: O(n) for the output lines
def remove_comments(self, source: list[str]) -> list[str]:
result: list[str] = []
in_block = False
buf: list[str] = []
for line in source:
if not in_block:
buf = []
i = 0
while i < len(line):
if in_block:
end = line.find("*/", i)
if end == -1:
break
in_block = False
i = end + 2
else:
line_c = line.find("//", i)
block_c = line.find("/*", i)
if line_c == -1 and block_c == -1:
buf.append(line[i:])
break
if line_c != -1 and (block_c == -1 or line_c < block_c):
buf.append(line[i:line_c])
break
buf.append(line[i:block_c])
in_block = True
i = block_c + 2
if not in_block:
code = "".join(buf)
if code:
result.append(code)
return result
```
## Complexity
| Time | Space |
| ---------------------------------------- | ------------------------- |
| O(n) over the total number of characters | O(n) for the output lines |
## Tags
# Remove Covered Intervals Python Solution
Source: https://leetcode-py.wisl.dev/problems/remove-covered-intervals
Tested Python solution for LeetCode 1288 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1288, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/remove-covered-intervals/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1288 # by problem number
lcpy gen -s remove_covered_intervals # by problem name
```
## Problem
Given an array intervals where intervals\[i] = \[li, ri] represent the interval \[li, ri), remove all intervals that are covered by another interval in the list.
* The interval \[a, b) is covered by the interval \[c, d) if and only if c \<= a and b \<= d.
Return the number of remaining intervals.
### Examples
```
Input: intervals = [[1,4],[3,6],[2,8]]
Output: 2
Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.
```
```
Input: intervals = [[1,4],[2,3]]
Output: 1
```
### Constraints
* 1 \<= intervals.length \<= 1000
* intervals\[i].length == 2
* 0 \<= li \< ri \<= 10^5
* All the given intervals are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_covered_intervals/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_covered_intervals/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def remove_covered_intervals(self, intervals: list[list[int]]) -> int:
intervals.sort(key=lambda interval: (interval[0], -interval[1]))
count = 0
best_end = -1
for _, right in intervals:
if right > best_end:
count += 1
best_end = right
return count
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Duplicate Letters Python Solution
Source: https://leetcode-py.wisl.dev/problems/remove-duplicate-letters
Tested Python solution for LeetCode 316 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 316, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/remove-duplicate-letters/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 316 # by problem number
lcpy gen -s remove_duplicate_letters # by problem name
```
## Problem
Given a string `s`, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
### Examples
```
Input: s = "bcabc"
Output: "abc"
Explanation: The possible results are "abc", "bac", "bca", "cab", and "cba". The smallest is "abc".
```
```
Input: s = "cbacdcbc"
Output: "acdb"
Explanation: Removing duplicates while keeping the result smallest gives "acdb".
```
### Constraints
* `1 <= s.length <= 10^4`
* `s` consists of lowercase English letters.
**Note:** This question is the same as 1081: [Smallest Subsequence of Distinct Characters](https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/).
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicate_letters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicate_letters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) - each character is pushed and popped at most once
# Space: O(k) - stack and membership set hold at most k distinct letters (k <= 26)
def remove_duplicate_letters(self, s: str) -> str:
last_index = {char: i for i, char in enumerate(s)}
stack: list[str] = []
in_stack: set[str] = set()
for i, char in enumerate(s):
if char in in_stack:
continue
while stack and stack[-1] > char and last_index[stack[-1]] > i:
in_stack.remove(stack.pop())
stack.append(char)
in_stack.add(char)
return "".join(stack)
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | -------------------------------------------------------------------------- |
| O(n) - each character is pushed and popped at most once | O(k) - stack and membership set hold at most k distinct letters (k \<= 26) |
## Tags
# Remove Duplicates From an Unsorted Linked List
Source: https://leetcode-py.wisl.dev/problems/remove-duplicates-from-an-unsorted-linked-list
Tested Python solution for LeetCode 1836 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 1836, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/remove-duplicates-from-an-unsorted-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1836 # by problem number
lcpy gen -s remove_duplicates_from_an_unsorted_linked_list # by problem name
```
## Problem
Given the `head` of a linked list, find all the values that appear **more than once** in the list and delete the nodes that have any of those values.
Return *the linked list after the deletions*.
### Examples

```
Input: head = [1,2,3,2]
Output: [1,3]
Explanation: 2 appears twice in the linked list, so all 2's should be deleted. After deleting all 2's, we are left with [1,3].
```

```
Input: head = [2,1,1,2]
Output: []
Explanation: 2 and 1 both appear twice. All the elements should be deleted.
```

```
Input: head = [3,2,2,1,3,2,4]
Output: [1,4]
Explanation: 3 appears twice and 2 appears three times. After deleting all 3's and 2's, we are left with [1,4].
```
### Constraints
* The number of nodes in the list is in the range `[1, 10^5]`.
* `1 <= Node.val <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_an_unsorted_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_an_unsorted_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(n)
def delete_duplicates_unsorted(self, head: ListNode[int] | None) -> ListNode[int] | None:
seen: set[int] = set()
dupes: set[int] = set()
cur = head
while cur is not None:
if cur.val in seen:
dupes.add(cur.val)
seen.add(cur.val)
cur = cur.next
dummy = ListNode(0)
dummy.next = head
prev = dummy
cur = head
while cur is not None:
nxt = cur.next
if cur.val in dupes:
prev.next = nxt
else:
prev = cur
cur = nxt
return dummy.next
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Duplicates From Sorted Array
Source: https://leetcode-py.wisl.dev/problems/remove-duplicates-from-sorted-array
Tested Python solution for LeetCode 26 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 26, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 26 # by problem number
lcpy gen -s remove_duplicates_from_sorted_array # by problem name
```
## Problem
Given an integer array `nums` sorted in non-decreasing order, remove the duplicates **in-place** such that each unique element appears only once. The relative order of the elements should be kept the same. Then return *the number of unique elements in* `nums`.
Consider the number of unique elements of `nums` to be `k`. To get accepted, you need to do the following things:
* Change the array `nums` such that the first `k` elements of `nums` contain the unique elements in the order they were present in `nums` initially. The remaining elements of `nums` are not important as well as the size of `nums`.
* Return `k`.
### Examples
```
Input: nums = [1,1,2]
Output: 2, nums = [1,2,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively.
It does not matter what you leave beyond the returned k (hence the underscores).
```
```
Input: nums = [0,0,1,1,1,2,2,3,3,4]
Output: 5, nums = [0,1,2,3,4,_,_,_,_,_]
Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3, and 4 respectively.
```
### Constraints
* `1 <= nums.length <= 3 * 10^4`
* `-100 <= nums[i] <= 100`
* `nums` is sorted in non-decreasing order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def remove_duplicates(self, nums: list[int]) -> int:
if not nums:
return 0
write = 1
for read in range(1, len(nums)):
if nums[read] != nums[write - 1]:
nums[write] = nums[read]
write += 1
return write
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Remove Duplicates from Sorted Array II
Source: https://leetcode-py.wisl.dev/problems/remove-duplicates-from-sorted-array-ii
Tested Python solution for LeetCode 80 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 80, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 80 # by problem number
lcpy gen -s remove_duplicates_from_sorted_array_ii # by problem name
```
## Problem
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**.
Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the **first part** of the array `nums`. More formally, if there are `k` elements after removing the duplicates, then the first `k` elements of `nums` should hold the final result. It does not matter what you leave beyond the first `k` elements.
Return `k` *after placing the final result in the first* `k` *slots of* `nums`.
Do **not** allocate extra space for another array. You must do this by **modifying the input array in-place** with O(1) extra memory.
**Custom Judge:**
The judge will test your solution with the following code:
```
int[] nums = [...]; // Input array
int[] expectedNums = [...]; // The expected answer with correct length
int k = removeDuplicates(nums); // Calls your implementation
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
```
If all assertions pass, then your solution is accepted.
### Examples
```
Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3,_]
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).
```
```
Input: nums = [0,0,1,1,1,1,2,3,3]
Output: 7, nums = [0,0,1,1,2,3,3,_,_]
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).
```
### Constraints
* 1 \<= nums.length \<= 3 \* 10^4
* -10^4 \<= nums\[i] \<= 10^4
* nums is sorted in non-decreasing order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_array_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_array_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def remove_duplicates(self, nums: list[int]) -> int:
# Write index: next position for a kept value
k = 0
for num in nums:
# Keep num if fewer than 2 kept copies exist so far.
# nums[k - 2] != num means num appears at most once in the
# kept prefix (nums[k - 2] is the earliest possible duplicate)
if k < 2 or nums[k - 2] != num:
nums[k] = num
k += 1
return k
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Duplicates from Sorted List
Source: https://leetcode-py.wisl.dev/problems/remove-duplicates-from-sorted-list
Tested Python solution for LeetCode 83 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 83, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 83 # by problem number
lcpy gen -s remove_duplicates_from_sorted_list # by problem name
```
## Problem
Given the `head` of a sorted linked list, *delete all duplicates such that each element appears only once*. Return the linked list **sorted** as well.
### Examples

```
Input: head = [1,1,2]
Output: [1,2]
```

```
Input: head = [1,1,2,3,3]
Output: [1,2,3]
```
### Constraints
* The number of nodes in the list is in the range `[0, 300]`.
* `-100 <= Node.val <= 100`
* The list is guaranteed to be sorted in ascending order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def delete_duplicates(self, head: ListNode[int] | None) -> ListNode[int] | None:
current = head
while current and current.next:
if current.val == current.next.val:
current.next = current.next.next
else:
current = current.next
return head
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Duplicates from Sorted List II
Source: https://leetcode-py.wisl.dev/problems/remove-duplicates-from-sorted-list-ii
Tested Python solution for LeetCode 82 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 82, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 82 # by problem number
lcpy gen -s remove_duplicates_from_sorted_list_ii # by problem name
```
## Problem
Given the `head` of a sorted linked list, *delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list*. Return the linked list **sorted** as well.
### Examples

```
Input: head = [1,2,3,3,4,4,5]
Output: [1,2,5]
```

```
Input: head = [1,1,1,2,3]
Output: [2,3]
```
### Constraints
* The number of nodes in the list is in the range `[0, 300]`.
* `-100 <= Node.val <= 100`
* The list is guaranteed to be sorted in ascending order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_list_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_duplicates_from_sorted_list_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def delete_duplicates(self, head: ListNode[int] | None) -> ListNode[int] | None:
dummy: ListNode[int] = ListNode(0)
dummy.next = head
prev = dummy
while head is not None:
if head.next is not None and head.val == head.next.val:
dup = head.val
while head is not None and head.val == dup:
head = head.next
prev.next = head
else:
prev = head
head = head.next
return dummy.next
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Remove Element Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/remove-element
Tested Python solution for LeetCode 27 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 27, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/remove-element/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 27 # by problem number
lcpy gen -s remove_element # by problem name
```
## Problem
Given an integer array `nums` and an integer `val`, remove all occurrences of `val` in `nums` **in-place**. The order of the elements may be changed. Then return *the number of elements in* `nums` *which are not equal to* `val`.
Consider the number of elements in `nums` which are not equal to `val` be `k`. To get accepted, you need to do the following things:
* Change the array `nums` such that the first `k` elements of `nums` contain the elements which are not equal to `val`. The remaining elements of `nums` are not important as well as the size of `nums`.
* Return `k`.
### Examples
```
Input: nums = [3,2,2,3], val = 3
Output: 2, nums = [2,2,_,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 2.
It does not matter what you leave beyond the returned k (hence the underscores).
```
```
Input: nums = [0,1,2,2,3,0,4,2], val = 2
Output: 5, nums = [0,1,4,0,3,_,_,_]
Explanation: Your function should return k = 5, with the first five elements of nums containing 0, 0, 1, 3, and 4.
Note that the five elements can be returned in any order.
```
### Constraints
* `0 <= nums.length <= 100`
* `0 <= nums[i] <= 50`
* `0 <= val <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_element/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_element/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def remove_element(self, nums: list[int], val: int) -> int:
write = 0
for read in range(len(nums)):
if nums[read] != val:
nums[write] = nums[read]
write += 1
return write
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Remove Interval Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/remove-interval
Tested Python solution for LeetCode 1272 with 35 pytest cases. Generate a practice environment with lcpy.
LeetCode 1272, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/remove-interval/description/).
Generate this problem as a practice environment: tested reference solution, 35 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1272 # by problem number
lcpy gen -s remove_interval # by problem name
```
## Problem
A set of real numbers can be represented as the union of several disjoint intervals, where each interval is in the form `[a, b)`. A real number `x` is in the set if one of its intervals `[a, b)` contains `x` (i.e. `a <= x < b`).
You are given a **sorted** list of disjoint intervals `intervals` representing a set of real numbers as described above, where `intervals[i] = [ai, bi]` represents the interval `[ai, bi)`. You are also given another interval `toBeRemoved`.
Return *the set of real numbers with the interval* `toBeRemoved` *removed* from\* `intervals`\*. In other words, return the set of real numbers such that every `x` in the set is in `intervals` but **not** in `toBeRemoved`. Your answer should be a **sorted** list of disjoint intervals as described above.
### Examples

```
Input: intervals = [[0,2],[3,4],[5,7]], toBeRemoved = [1,6]
Output: [[0,1],[6,7]]
```

```
Input: intervals = [[0,5]], toBeRemoved = [2,3]
Output: [[0,2],[3,5]]
```
```
Input: intervals = [[-5,-4],[-3,-2],[1,2],[3,5],[8,9]], toBeRemoved = [-1,4]
Output: [[-5,-4],[-3,-2],[4,5],[8,9]]
```
### Constraints
* 1 \<= intervals.length \<= 10^4
* -10^9 \<= ai \< bi \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_interval/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_interval/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) extra (output excluded)
def remove_interval(
self, intervals: list[list[int]], to_be_removed: list[int]
) -> list[list[int]]:
start, end = to_be_removed
result: list[list[int]] = []
for a, b in intervals:
if a >= end or b <= start:
result.append([a, b])
continue
if a < start:
result.append([a, start])
if b > end:
result.append([end, b])
return result
```
## Complexity
| Time | Space |
| ---- | ---------------------------- |
| O(n) | O(1) extra (output excluded) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Invalid Parentheses Python Solution
Source: https://leetcode-py.wisl.dev/problems/remove-invalid-parentheses
Tested Python solution for LeetCode 301 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 301, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/remove-invalid-parentheses/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 301 # by problem number
lcpy gen -s remove_invalid_parentheses # by problem name
```
## Problem
Given a string `s` that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid.
Return *a list of **unique strings*** that are valid with the minimum number of removals. You may return the answer in **any order**.
### Examples
```
Input: s = "()())()"
Output: ["(())()","()()()"]
```
```
Input: s = "(a)())()"
Output: ["(a())()","(a)()()"]
```
```
Input: s = ")("
Output: [""]
```
### Constraints
* `1 <= s.length <= 25`
* `s` consists of lowercase English letters and parentheses `'('` and `')'`.
* There will be at most `20` parentheses in `s`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_invalid_parentheses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_invalid_parentheses/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^p) over the p <= 20 parenthesis positions, each kept or removed
# Space: O(n) recursion depth plus the result set
def remove_invalid_parentheses(self, s: str) -> list[str]:
rem_left = rem_right = 0
for ch in s:
if ch == "(":
rem_left += 1
elif ch == ")":
if rem_left:
rem_left -= 1
else:
rem_right += 1
results: set[str] = set()
path: list[str] = []
n = len(s)
def dfs(i: int, open_count: int, left_rem: int, right_rem: int) -> None:
if left_rem + right_rem > n - i:
return
if i == n:
if left_rem == 0 and right_rem == 0 and open_count == 0:
results.add("".join(path))
return
ch = s[i]
if ch == "(" and left_rem > 0:
dfs(i + 1, open_count, left_rem - 1, right_rem)
elif ch == ")" and right_rem > 0:
dfs(i + 1, open_count, left_rem, right_rem - 1)
path.append(ch)
if ch == "(":
dfs(i + 1, open_count + 1, left_rem, right_rem)
elif ch == ")" and open_count > 0:
dfs(i + 1, open_count - 1, left_rem, right_rem)
elif ch not in "()":
dfs(i + 1, open_count, left_rem, right_rem)
path.pop()
dfs(0, 0, rem_left, rem_right)
return list(results)
```
## Complexity
| Time | Space |
| -------------------------------------------------------------------- | ---------------------------------------- |
| O(2^p) over the p \<= 20 parenthesis positions, each kept or removed | O(n) recursion depth plus the result set |
## Tags
# Remove K Digits Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/remove-k-digits
Tested Python solution for LeetCode 402 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 402, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/remove-k-digits/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 402 # by problem number
lcpy gen -s remove_k_digits # by problem name
```
## Problem
Given string num representing a non-negative integer `num`, and an integer `k`, return *the smallest possible integer after removing* `k` *digits from* `num`*.*
### Examples
```
Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
```
```
Input: num = "10200", k = 1
Output: "200"
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
```
```
Input: num = "10", k = 2
Output: "0"
Explanation: Remove all the digits from the number and it is left with nothing which is 0.
```
### Constraints
* `1 <= k <= num.length <= 10^5`
* `num` consists of only digits.
* `num` does not have any leading zeros except for the zero itself.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_k_digits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_k_digits/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def remove_k_digits(self, num: str, k: int) -> str:
stack: list[str] = []
for digit in num:
while k and stack and stack[-1] > digit:
stack.pop()
k -= 1
stack.append(digit)
if k:
stack = stack[:-k]
return "".join(stack).lstrip("0") or "0"
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Linked List Elements Python Solution
Source: https://leetcode-py.wisl.dev/problems/remove-linked-list-elements
Tested Python solution for LeetCode 203 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 203, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/remove-linked-list-elements/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 203 # by problem number
lcpy gen -s remove_linked_list_elements # by problem name
```
## Problem
Given the `head` of a linked list and an integer `val`, remove all the nodes of the linked list that has `Node.val == val`, and return *the new head*.
### Examples

```
Input: head = [1,2,6,3,4,5,6], val = 6
Output: [1,2,3,4,5]
```
```
Input: head = [], val = 1
Output: []
```
```
Input: head = [7,7,7,7], val = 7
Output: []
```
### Constraints
* The number of nodes in the list is in the range \[0, 10\4\]
* 1 \<= Node.val \<= 50
* 0 \<= val \<= 50
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_linked_list_elements/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_linked_list_elements/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def remove_linked_list_elements(
self, head: ListNode[int] | None, val: int
) -> ListNode[int] | None:
dummy = ListNode[int](0)
dummy.next = head
current = dummy
while current.next is not None:
if current.next.val == val:
current.next = current.next.next
else:
current = current.next
return dummy.next
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Max Number of Edges to Keep Graph
Source: https://leetcode-py.wisl.dev/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable
Tested Python solution for LeetCode 1579 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1579, [Hard](/catalog/hard). Topics: [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1579 # by problem number
lcpy gen -s remove_max_number_of_edges_to_keep_graph_fully_traversable # by problem name
```
## Problem
Alice and Bob have an undirected graph of `n` nodes and three types of edges:
* Type 1: Can be traversed by Alice only.
* Type 2: Can be traversed by Bob only.
* Type 3: Can be traversed by both Alice and Bob.
Given an array `edges` where `edges[i] = [typei, ui, vi]` represents a bidirectional edge of type `typei` between nodes `ui` and `vi`, find the maximum number of edges you can remove so that after removing the edges, the graph can still be fully traversed by both Alice and Bob. The graph is fully traversed by Alice and Bob if starting from any node, they can reach all other nodes.
Return *the maximum number of edges you can remove, or return* `-1` *if Alice and Bob cannot fully traverse the graph.*
### Examples

```
Input: n = 4, edges = [[3,1,2],[3,2,3],[1,1,3],[1,2,4],[1,1,2],[2,3,4]]
Output: 2
Explanation: If we remove the 2 edges [1,1,2] and [1,1,3]. The graph will still be fully traversable by Alice and Bob. Removing any additional edge will not make it so. So the maximum number of edges we can remove is 2.
```

```
Input: n = 4, edges = [[3,1,2],[3,2,3],[1,1,4],[2,1,4]]
Output: 0
Explanation: Notice that removing any edge will not make the graph fully traversable by Alice and Bob.
```

```
Input: n = 4, edges = [[3,2,3],[1,1,2],[2,3,4]]
Output: -1
Explanation: In the current graph, Alice cannot reach node 4 from the other nodes. Likewise, Bob cannot reach 1. Therefore it's impossible to make the graph fully traversable.
```
### Constraints
* 1 \<= n \<= 10^5
* 1 \<= edges.length \<= min(10^5, 3 \* n \* (n - 1) / 2)
* edges\[i].length == 3
* 1 \<= typei \<= 3
* 1 \<= ui \< vi \<= n
* All tuples (typei, ui, vi) are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_max_number_of_edges_to_keep_graph_fully_traversable/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_max_number_of_edges_to_keep_graph_fully_traversable/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class DSU:
def __init__(self, size: int) -> None:
self.parent = list(range(size))
def find(self, x: int) -> int:
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]
x = self.parent[x]
return x
def union(self, a: int, b: int) -> bool:
root_a, root_b = self.find(a), self.find(b)
if root_a == root_b:
return False
self.parent[root_a] = root_b
return True
class Solution:
# Time: O(e * alpha(n))
# Space: O(n)
def max_num_edges_to_remove(self, n: int, edges: list[list[int]]) -> int:
alice = DSU(n + 1)
bob = DSU(n + 1)
kept = 0
for edge_type, u, v in edges:
if edge_type == 3:
merged_alice = alice.union(u, v)
merged_bob = bob.union(u, v)
if merged_alice or merged_bob:
kept += 1
for edge_type, u, v in edges:
merged = (edge_type == 1 and alice.union(u, v)) or (edge_type == 2 and bob.union(u, v))
if merged:
kept += 1
if len({alice.find(node) for node in range(1, n + 1)}) > 1:
return -1
if len({bob.find(node) for node in range(1, n + 1)}) > 1:
return -1
return len(edges) - kept
```
## Complexity
| Time | Space |
| ---------------- | ----- |
| O(e \* alpha(n)) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Nodes From Linked List Python Solution
Source: https://leetcode-py.wisl.dev/problems/remove-nodes-from-linked-list
Tested Python solution for LeetCode 2487 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2487, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/remove-nodes-from-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2487 # by problem number
lcpy gen -s remove_nodes_from_linked_list # by problem name
```
## Problem
You are given the \head\ of a linked list.
Remove every node which has a node with a \greater\ value anywhere to the \right\ side of it.
Return \the head of the modified linked list\.
### Examples

```
Input: head = [5,2,13,3,8]
Output: [13,8]
Explanation: The nodes that should be removed are 5, 2 and 3.
- Node 13 is to the right of node 5.
- Node 13 is to the right of node 2.
- Node 8 is to the right of node 3.
```
```
Input: head = [1,1,1,1]
Output: [1,1,1,1]
Explanation: Every node has value 1, so no nodes are removed.
```
### Constraints
* The number of the nodes in the given list is in the range `[1, 10^5]`.
* `1 <= Node.val <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_nodes_from_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_nodes_from_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def remove_nodes(self, head: ListNode[int] | None) -> ListNode[int] | None:
# Reverse the list so that "greater to the right" becomes "greater already kept".
prev: ListNode[int] | None = None
node = head
while node is not None:
nxt = node.next
node.next = prev
prev = node
node = nxt
cur = prev
while cur is not None:
nxt = cur.next
if nxt is None:
break
if nxt.val < cur.val:
cur.next = nxt.next
else:
cur = nxt
# Reverse back to restore left-to-right order.
result: ListNode[int] | None = None
node = prev
while node is not None:
nxt = node.next
node.next = result
result = node
node = nxt
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Remove Nth Node From End of List
Source: https://leetcode-py.wisl.dev/problems/remove-nth-node-from-end-of-list
Tested Python solution for LeetCode 19 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 19, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 19 # by problem number
lcpy gen -s remove_nth_node_from_end_of_list # by problem name
```
## Problem
Given the `head` of a linked list, remove the `nth` node from the end of the list and return its head.
### Examples

```
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
```
```
Input: head = [1], n = 1
Output: []
```
```
Input: head = [1,2], n = 1
Output: [1]
```
### Constraints
* The number of nodes in the list is `sz`.
* `1 <= sz <= 30`
* `0 <= Node.val <= 100`
* `1 <= n <= sz`
**Follow up:** Could you do this in one pass?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_nth_node_from_end_of_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_nth_node_from_end_of_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(L) where L is the length of the list
# Space: O(1)
def remove_nth_from_end(self, head: ListNode[int] | None, n: int) -> ListNode[int] | None:
dummy = ListNode(0)
dummy.next = head
fast: ListNode[int] | None = dummy
slow: ListNode[int] | None = dummy
# Move fast pointer n+1 steps ahead
for _ in range(n + 1):
assert fast
fast = fast.next
# Move both pointers until fast reaches end
while fast:
fast = fast.next
assert slow
slow = slow.next
# Remove the nth node
assert slow and slow.next
slow.next = slow.next.next
return dummy.next
```
## Complexity
| Time | Space |
| -------------------------------------- | ----- |
| O(L) where L is the length of the list | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Remove Sub-Folders from the Filesystem
Source: https://leetcode-py.wisl.dev/problems/remove-sub-folders-from-the-filesystem
Tested Python solution for LeetCode 1233 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1233, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Depth-First Search](/catalog/topics/depth-first-search), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/remove-sub-folders-from-the-filesystem/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1233 # by problem number
lcpy gen -s remove_sub_folders_from_the_filesystem # by problem name
```
## Problem
Given a list of folders `folder`, return *the folders after removing all **sub-folders** in those folders*. You may return the answer in **any order**.
If a `folder[i]` is located within another `folder[j]`, it is called a **sub-folder** of it. A sub-folder of `folder[j]` must start with `folder[j]`, followed by a `"/"`. For example, `"/a/b"` is a sub-folder of `"/a"`, but `"/b"` is not a sub-folder of `"/a/b/c"`.
The format of a path is one or more concatenated strings of the form: `'/'` followed by one or more lowercase English letters.
* For example, `"/leetcode"` and `"/leetcode/problems"` are valid paths while an empty string and `"/"` are not.
### Examples
```
Input: folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"]
Output: ["/a","/c/d","/c/f"]
Explanation: Folders "/a/b" is a subfolder of "/a" and "/c/d/e" is inside of folder "/c/d" in our filesystem.
```
```
Input: folder = ["/a","/a/b/c","/a/b/d"]
Output: ["/a"]
Explanation: Folders "/a/b/c" and "/a/b/d" will be removed because they are subfolders of "/a".
```
```
Input: folder = ["/a/b/c","/a/b/ca","/a/b/d"]
Output: ["/a/b/c","/a/b/ca","/a/b/d"]
```
### Constraints
* `1 <= folder.length <= 4 * 10^4`
* `2 <= folder[i].length <= 100`
* `folder[i]` contains only lowercase letters and `'/'`.
* `folder[i]` always starts with the character `'/'`.
* Each folder name is unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_sub_folders_from_the_filesystem/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/remove_sub_folders_from_the_filesystem/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * log(n) * len(path))
# Space: O(n * len(path))
def remove_subfolders(self, folder: list[str]) -> list[str]:
folder.sort()
result: list[str] = []
for path in folder:
if not result or not path.startswith(result[-1] + "/"):
result.append(path)
return result
```
## Complexity
| Time | Space |
| --------------------------- | ----------------- |
| O(n \* log(n) \* len(path)) | O(n \* len(path)) |
## Tags
[NeetCode All](/catalog/neetcode).
# Removing Stars From a String Python Solution
Source: https://leetcode-py.wisl.dev/problems/removing-stars-from-a-string
Tested Python solution for LeetCode 2390 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 2390, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/removing-stars-from-a-string/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2390 # by problem number
lcpy gen -s removing_stars_from_a_string # by problem name
```
## Problem
You are given a string `s`, which contains stars `*`.
In one operation, you can:
* Choose a star in `s`.
* Remove the closest **non-star** character to its **left**, as well as remove the star itself.
Return *the string after **all** stars have been removed*.
**Note:**
* The input will be generated such that the operation is always possible.
* It can be shown that the resulting string will always be unique.
### Examples
```
Input: s = "leet**cod*e"
Output: "lecoe"
Explanation: Performing the removals from left to right:
- The closest character to the 1st star is 't' in "leet**cod*e". s becomes "lee*cod*e".
- The closest character to the 2nd star is 'e' in "lee*cod*e". s becomes "lecod*e".
- The closest character to the 3rd star is 'd' in "lecod*e". s becomes "lecoe".
There are no more stars, so we return "lecoe".
```
```
Input: s = "erase*****"
Output: ""
Explanation: The entire string is removed, so we return an empty string.
```
### Constraints
* `1 <= s.length <= 10^5`
* `s` consists of lowercase English letters and stars `*`.
* The operation above can be performed on `s`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/removing_stars_from_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/removing_stars_from_a_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def remove_stars(self, s: str) -> str:
chars: list[str] = []
for ch in s:
if ch == "*":
chars.pop()
else:
chars.append(ch)
return "".join(chars)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Reorder List Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/reorder-list
Tested Python solution for LeetCode 143 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 143, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers), [Stack](/catalog/topics/stack), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/reorder-list/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 143 # by problem number
lcpy gen -s reorder_list # by problem name
```
## Problem
You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
*Reorder the list to be on the following form:*
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
### Examples

```
Input: head = [1,2,3,4]
Output: [1,4,2,3]
```

```
Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]
```
### Constraints
* The number of nodes in the list is in the range \[1, 5 \* 10^4].
* 1 \<= Node.val \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorder_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorder_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n) where n is the number of nodes
# Space: O(1) - only using constant extra space
def reorder_list(self, head: ListNode[int] | None) -> None:
"""
Reorder a linked list in-place: L0→L1→...→Ln-1→Ln becomes L0→Ln→L1→Ln-1→L2→Ln-2→...
Algorithm:
1. Find the middle of the list using slow/fast pointers
2. Reverse the second half of the list
3. Merge the first half and reversed second half alternately
This approach uses O(1) space and O(n) time.
"""
if not head or not head.next:
return
# Step 1: Find the middle of the list
slow = fast = head
while fast.next and fast.next.next:
assert slow.next
slow = slow.next
fast = fast.next.next
# Split the list into two halves
second_half = slow.next
slow.next = None # Break the connection
# Step 2: Reverse the second half
prev = None
current = second_half
while current:
next_temp = current.next
current.next = prev
prev = current
current = next_temp
second_half = prev
# Step 3: Merge the two halves alternately
first_half = head
while second_half:
assert first_half is not None
# Store next nodes
first_next = first_half.next
second_next = second_half.next
# Reorder: first -> second -> first_next
first_half.next = second_half
second_half.next = first_next
# Move to next nodes
first_half = first_next
second_half = second_next
```
## Complexity
| Time | Space |
| ----------------------------------- | -------------------------------------- |
| O(n) where n is the number of nodes | O(1) - only using constant extra space |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Reorder Data in Log Files Python Solution
Source: https://leetcode-py.wisl.dev/problems/reorder-log-files
Tested Python solution for LeetCode 937 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 937, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/reorder-log-files/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 937 # by problem number
lcpy gen -s reorder_log_files # by problem name
```
## Problem
You are given an array of logs. Each log is a space-delimited string of words, where the first word is the **identifier**.
There are two types of logs:
* **Letter-logs**: All words (except the identifier) consist of lowercase English letters.
* **Digit-logs**: All words (except the identifier) consist of digits.
Reorder these logs so that:
1. The **letter-logs** come before all **digit-logs**.
2. The **letter-logs** are sorted lexicographically by their contents. If their contents are the same, then sort them lexicographically by their identifiers.
3. The **digit-logs** maintain their relative ordering.
Return *the final order of the logs*.
### Examples
```
Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"]
Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]
Explanation:
The letter-log contents are all different, so their ordering is "art can", "art zero", "own kit dig".
The digit-logs have a relative order of "dig1 8 1 5 1", "dig2 3 6".
```
```
Input: logs = ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]
Output: ["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]
```
### Constraints
* 1 \<= logs.length \<= 100
* 3 \<= logs\[i].length \<= 100
* All the tokens of logs\[i] are separated by a single space.
* logs\[i] is guaranteed to have an identifier and at least one word after the identifier.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorder_log_files/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorder_log_files/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * m log n) where n = len(logs), m = max log length
# Space: O(n * m)
def reorder_log_files(self, logs: list[str]) -> list[str]:
letters: list[str] = []
digits: list[str] = []
for log in logs:
rest = log.split(" ", 1)[1]
if rest[0].isdigit():
digits.append(log)
else:
letters.append(log)
letters.sort(key=lambda log: (log.split(" ", 1)[1], log.split(" ", 1)[0]))
return letters + digits
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | --------- |
| O(n \* m log n) where n = len(logs), m = max log length | O(n \* m) |
## Tags
# Reorder Routes to Make All Paths Lead to the
Source: https://leetcode-py.wisl.dev/problems/reorder-routes-to-make-all-paths-lead-to-the-city-zero
Tested Python solution for LeetCode 1466 with 29 pytest cases. Generate a practice environment with lcpy.
LeetCode 1466, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/reorder-routes-to-make-all-paths-lead-to-the-city-zero/description/).
Generate this problem as a practice environment: tested reference solution, 29 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1466 # by problem number
lcpy gen -s reorder_routes_to_make_all_paths_lead_to_the_city_zero # by problem name
```
## Problem
There are `n` cities numbered from `0` to `n - 1` and `n - 1` roads such that there is only one way to travel between two different cities (this network form a tree). Last year, The ministry of transport decided to orient the roads in one direction because they are too narrow.
Roads are represented by `connections` where `connections[i] = [ai, bi]` represents a road from city `ai` to city `bi`.
This year, there will be a big event in the capital (city `0`), and many people want to travel to this city.
Your task consists of reorienting some roads such that each city can visit the city `0`. Return the **minimum** number of edges changed.
It's **guaranteed** that each city can reach city `0` after reorder.
### Examples

```
Input: n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
Output: 3
```
**Explanation:** Change the direction of edges show in red such that each node can reach the node 0 (capital).

```
Input: n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
Output: 2
```
**Explanation:** Change the direction of edges show in red such that each node can reach the node 0 (capital).
```
Input: n = 3, connections = [[1,0],[2,0]]
Output: 0
```
### Constraints
* `2 <= n <= 5 * 10^4`
* `connections.length == n - 1`
* `connections[i].length == 2`
* `0 <= ai, bi <= n - 1`
* `ai != bi`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorder_routes_to_make_all_paths_lead_to_the_city_zero/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorder_routes_to_make_all_paths_lead_to_the_city_zero/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict, deque
class Solution:
# Time: O(n)
# Space: O(n)
def min_reorder(self, n: int, connections: list[list[int]]) -> int:
adjacency: dict[int, list[tuple[int, int]]] = defaultdict(list)
for src, dst in connections:
adjacency[src].append((dst, 1))
adjacency[dst].append((src, 0))
flips = 0
visited = [False] * n
visited[0] = True
queue: deque[int] = deque([0])
while queue:
city = queue.popleft()
for neighbor, directed_out in adjacency[city]:
if visited[neighbor]:
continue
flips += directed_out
visited[neighbor] = True
queue.append(neighbor)
return flips
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Reordered Power of 2 Python Solution
Source: https://leetcode-py.wisl.dev/problems/reordered-power-of-2
Tested Python solution for LeetCode 869 with 36 pytest cases. Generate a practice environment with lcpy.
LeetCode 869, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [Sorting](/catalog/topics/sorting), [Counting](/catalog/topics/counting), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/reordered-power-of-2/description/).
Generate this problem as a practice environment: tested reference solution, 36 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 869 # by problem number
lcpy gen -s reordered_power_of_2 # by problem name
```
## Problem
You are given an integer `n`. We reorder the digits in any order (including the original order) such that the leading digit is not zero.
Return `true` if and only if we can do this so that the resulting number is a power of two.
### Examples
```
Input: n = 1
Output: true
```
```
Input: n = 10
Output: false
```
### Constraints
* 1 \<= n \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reordered_power_of_2/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reordered_power_of_2/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(d log d) where d is the number of digits in n
# Space: O(d)
def reordered_power_of_2(self, n: int) -> bool:
digits = sorted(str(n))
return any(sorted(str(1 << k)) == digits for k in range(31))
```
## Complexity
| Time | Space |
| ----------------------------------------------- | ----- |
| O(d log d) where d is the number of digits in n | O(d) |
## Tags
# Reorganize String Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/reorganize-string
Tested Python solution for LeetCode 767 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 767, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/reorganize-string/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 767 # by problem number
lcpy gen -s reorganize_string # by problem name
```
## Problem
Given a string `s`, rearrange the characters of `s` so that any two adjacent characters are not the same.
Return *any possible rearrangement of* `s` *or return* `""` *if not possible*.
### Examples
```
Input: s = "aab"
Output: "aba"
```
```
Input: s = "aaab"
Output: ""
```
### Constraints
* 1 \<= s.length \<= 500
* `s` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorganize_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reorganize_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
from collections import Counter
class Solution:
# Time: O(n log k)
# Space: O(k)
def reorganize_string(self, s: str) -> str:
counts = Counter(s)
# Impossible when the most frequent char cannot be placed apart.
if max(counts.values()) > (len(s) + 1) // 2:
return ""
# Max-heap by remaining count (negate for Python's min-heap).
heap: list[tuple[int, str]] = [(-count, char) for char, count in counts.items()]
heapq.heapify(heap)
result: list[str] = []
while len(heap) >= 2:
neg_count_a, char_a = heapq.heappop(heap)
neg_count_b, char_b = heapq.heappop(heap)
result.append(char_a)
result.append(char_b)
if neg_count_a + 1 < 0:
heapq.heappush(heap, (neg_count_a + 1, char_a))
if neg_count_b + 1 < 0:
heapq.heappush(heap, (neg_count_b + 1, char_b))
if heap:
result.append(heap[0][1])
return "".join(result)
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log k) | O(k) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Repeated DNA Sequences Python Solution
Source: https://leetcode-py.wisl.dev/problems/repeated-dna-sequences
Tested Python solution for LeetCode 187 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 187, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sliding Window](/catalog/topics/sliding-window), Rolling Hash, [Hash Function](/catalog/topics/hash-function). [View on LeetCode](https://leetcode.com/problems/repeated-dna-sequences/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 187 # by problem number
lcpy gen -s repeated_dna_sequences # by problem name
```
## Problem
The **DNA sequence** is composed of a series of nucleotides abbreviated as `'A'`, `'C'`, `'G'`, and `'T'`.
* For example, `"ACGAATTCCG"` is a **DNA sequence**.
When studying **DNA**, it is useful to identify repeated sequences within the DNA.
Given a string `s` that represents a DNA sequence, return all the **10-letter-long sequences** (substrings) that occur more than once in a DNA molecule. You may return the answer in **any order**.
### Examples
```
Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
Output: ["AAAAACCCCC","CCCCCAAAAA"]
```
```
Input: s = "AAAAAAAAAAAAA"
Output: ["AAAAAAAAAA"]
```
### Constraints
* 1 \<= s.length \<= 10\5\
* `s[i]` is either `'A'`, `'C'`, `'G'`, or `'T'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/repeated_dna_sequences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/repeated_dna_sequences/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * L) where L is the sequence length (10)
# Space: O(n * L)
def repeated_dna_sequences(self, s: str) -> list[str]:
seen: set[str] = set()
repeated: set[str] = set()
for i in range(len(s) - 9):
sequence = s[i : i + 10]
if sequence in seen:
repeated.add(sequence)
seen.add(sequence)
return list(repeated)
```
## Complexity
| Time | Space |
| --------------------------------------------- | --------- |
| O(n \* L) where L is the sequence length (10) | O(n \* L) |
## Tags
[NeetCode All](/catalog/neetcode).
# Repeated String Match Python Solution
Source: https://leetcode-py.wisl.dev/problems/repeated-string-match
Tested Python solution for LeetCode 686 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 686, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching), Z Algorithm, Knuth-Morris-Pratt Algorithm, Boyer-Moore String-Search Algorithm. [View on LeetCode](https://leetcode.com/problems/repeated-string-match/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 686 # by problem number
lcpy gen -s repeated_string_match # by problem name
```
## Problem
Given two strings `a` and `b`, return the minimum number of times you should repeat string `a` so that string `b` is a substring of it. If it is impossible for `b` to be a substring of `a` after repeating it, return `-1`.
**Notice:** string `"abc"` repeated 0 times is `""`, repeated 1 time is `"abc"` and repeated 2 times is `"abcabc"`.
### Examples
```
Input: a = "abcd", b = "cdabcdab"
Output: 3
Explanation: We return 3 because by repeating a three times "abcdabcdabcd", b is a substring of it.
```
```
Input: a = "a", b = "aa"
Output: 2
```
### Constraints
* 1 \<= a.length, b.length \<= 10^4
* a and b consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/repeated_string_match/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/repeated_string_match/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(len(a) + len(b))
# Space: O(len(a) + len(b))
def repeated_string_match(self, a: str, b: str) -> int:
min_repeats = -(-len(b) // len(a)) if b else 1
for k in (min_repeats, min_repeats + 1):
if b in a * k:
return k
return -1
```
## Complexity
| Time | Space |
| ------------------ | ------------------ |
| O(len(a) + len(b)) | O(len(a) + len(b)) |
## Tags
# Repeated Substring Pattern Python Solution
Source: https://leetcode-py.wisl.dev/problems/repeated-substring-pattern
Tested Python solution for LeetCode 459 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 459, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching). [View on LeetCode](https://leetcode.com/problems/repeated-substring-pattern/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 459 # by problem number
lcpy gen -s repeated_substring_pattern # by problem name
```
## Problem
Given a string s, check if it can be constructed by taking a substring of it and appending multiple copies of the substring together.
### Examples
```
Input: s = "abab"
Output: true
Explanation: It is the substring "ab" twice.
```
```
Input: s = "aba"
Output: false
```
```
Input: s = "abcabcabcabc"
Output: true
Explanation: It is the substring "abc" four times or the substring "abcabc" twice.
```
### Constraints
* 1 \<= s.length \<= 10^4
* s consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/repeated_substring_pattern/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/repeated_substring_pattern/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def repeated_substring_pattern(self, s: str) -> bool:
n = len(s)
lps = [0] * n
length = 0
for i in range(1, n):
while length > 0 and s[i] != s[length]:
length = lps[length - 1]
if s[i] == s[length]:
length += 1
lps[i] = length
longest_proper_suffix = lps[n - 1] if n > 0 else 0
return longest_proper_suffix > 0 and n % (n - longest_proper_suffix) == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Replace Elements with Greatest Element on
Source: https://leetcode-py.wisl.dev/problems/replace-elements-with-greatest-element-on-right-side
Tested Python solution for LeetCode 1299 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1299, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/replace-elements-with-greatest-element-on-right-side/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1299 # by problem number
lcpy gen -s replace_elements_with_greatest_element_on_right_side # by problem name
```
## Problem
Given an array arr, replace every element in that array with the greatest element among the elements to its right, and replace the last element with -1.
After doing so, return the array.
### Examples
```
Input: arr = [17,18,5,4,6,1]
Output: [18,6,6,6,1,-1]
Explanation:
- index 0 --> the greatest element to the right of index 0 is index 1 (18).
- index 1 --> the greatest element to the right of index 1 is index 4 (6).
- index 2 --> the greatest element to the right of index 2 is index 4 (6).
- index 3 --> the greatest element to the right of index 3 is index 4 (6).
- index 4 --> the greatest element to the right of index 4 is index 5 (1).
- index 5 --> there are no elements to the right of index 5, so we put -1.
```
```
Input: arr = [400]
Output: [-1]
Explanation: There are no elements to the right of index 0.
```
### Constraints
* 1 \<= arr.length \<= 10^4
* 1 \<= arr\[i] \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/replace_elements_with_greatest_element_on_right_side/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/replace_elements_with_greatest_element_on_right_side/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def replace_elements(self, arr: list[int]) -> list[int]:
result = [-1] * len(arr)
best = -1
for i in range(len(arr) - 1, -1, -1):
result[i] = best
best = max(best, arr[i])
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Replace Words Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/replace-words
Tested Python solution for LeetCode 648 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 648, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/replace-words/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 648 # by problem number
lcpy gen -s replace_words # by problem name
```
## Problem
In English, we have a concept called root, which can be followed by some other word to form another longer word - let's call this word derivative. For example, when the root "help" is followed by the word "ful", we can form a derivative "helpful".
Given a dictionary consisting of many roots and a sentence consisting of words separated by spaces, replace all the derivatives in the sentence with the root forming it. If a derivative can be replaced by more than one root, replace it with the root that has the shortest length.
Return the sentence after the replacement.
### Examples
```
Input: dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
Output: "the cat was rat by the bat"
```
```
Input: dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
Output: "a a b c"
```
### Constraints
* 1 \<= dictionary.length \<= 1000
* 1 \<= dictionary\[i].length \<= 100
* dictionary\[i] consists of only lower-case letters.
* 1 \<= sentence.length \<= 10^6
* sentence consists of only lower-case letters and spaces.
* The number of words in sentence is in the range \[1, 1000]
* The length of each word in sentence is in the range \[1, 1000]
* Every two consecutive words in sentence will be separated by exactly one space.
* sentence does not have leading or trailing spaces.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/replace_words/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/replace_words/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class _TrieNode:
__slots__ = ("children", "word")
def __init__(self) -> None:
self.children: dict[str, _TrieNode] = {}
self.word: str | None = None
class Solution:
# Time: O(total chars in dictionary + total chars in sentence)
# Space: O(total chars in dictionary)
def replace_words(self, dictionary: list[str], sentence: str) -> str:
root = _TrieNode()
for entry in dictionary:
node = root
for char in entry:
node = node.children.setdefault(char, _TrieNode())
node.word = entry
def shortest_root(word: str) -> str:
node = root
for char in word:
if node.word is not None:
return node.word
if char not in node.children:
return word
node = node.children[char]
return node.word if node.word is not None else word
return " ".join(shortest_root(word) for word in sentence.split())
```
## Complexity
| Time | Space |
| ------------------------------------------------------ | ---------------------------- |
| O(total chars in dictionary + total chars in sentence) | O(total chars in dictionary) |
## Tags
# Reshape the Matrix Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/reshape-the-matrix
Tested Python solution for LeetCode 566 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 566, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/reshape-the-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 566 # by problem number
lcpy gen -s reshape_the_matrix # by problem name
```
## Problem
In MATLAB, there is a handy function called `reshape` which can reshape an `m x n` matrix into a new one with a different size `r x c` keeping its original data.
You are given an `m x n` matrix `mat` and two integers `r` and `c` representing the number of rows and the number of columns of the wanted reshaped matrix.
The reshaped matrix should be filled with all the elements of the original matrix in the same row-traversing order as they were.
If the `reshape` operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.
### Examples

```
Input: mat = [[1,2],[3,4]], r = 1, c = 4
Output: [[1,2,3,4]]
```

```
Input: mat = [[1,2],[3,4]], r = 2, c = 4
Output: [[1,2],[3,4]]
```
### Constraints
* m == mat.length
* n == mat\[i].length
* 1 \<= m, n \<= 100
* -1000 \<= mat\[i]\[j] \<= 1000
* 1 \<= r, c \<= 300
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reshape_the_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reshape_the_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(r * c) for the output matrix
def matrix_reshape(self, mat: list[list[int]], r: int, c: int) -> list[list[int]]:
m, n = len(mat), len(mat[0])
if m * n != r * c:
return mat
result: list[list[int]] = []
row: list[int] = []
for values in mat:
for value in values:
row.append(value)
if len(row) == c:
result.append(row)
row = []
return result
```
## Complexity
| Time | Space |
| --------- | ------------------------------- |
| O(m \* n) | O(r \* c) for the output matrix |
## Tags
# Restore IP Addresses Python Solution
Source: https://leetcode-py.wisl.dev/problems/restore-ip-addresses
Tested Python solution for LeetCode 93 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 93, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/restore-ip-addresses/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 93 # by problem number
lcpy gen -s restore_ip_addresses # by problem name
```
## Problem
A **valid IP address** consists of exactly four integers separated by single dots. Each integer is between `0` and `255` (**inclusive**) and cannot have leading zeros.
* For example, `"0.1.2.201"` and `"192.168.1.1"` are **valid** IP addresses, but `"0.011.255.245"`, `"192.168.1.312"` and `"192.168@1.1"` are **invalid** IP addresses.
Given a string `s` containing only digits, return *all possible valid IP addresses that can be formed by inserting dots into* `s`. You are **not** allowed to reorder or remove any digits in `s`. You may return the valid IP addresses in **any** order.
### Examples
```
Input: s = "25525511135"
Output: ["255.255.11.135","255.255.111.35"]
```
```
Input: s = "0000"
Output: ["0.0.0.0"]
```
```
Input: s = "101023"
Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
```
### Constraints
* `1 <= s.length <= 20`
* `s` consists of digits only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/restore_ip_addresses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/restore_ip_addresses/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1)
# Space: O(1)
def restore_ip_addresses(self, s: str) -> list[str]:
results: list[str] = []
def is_valid_part(part: str) -> bool:
if len(part) > 1 and part[0] == "0":
return False
return int(part) <= 255
def backtrack(start: int, parts: list[str]) -> None:
if len(parts) == 4:
if start == len(s):
results.append(".".join(parts))
return
remaining_digits = len(s) - start
remaining_parts = 4 - len(parts)
if remaining_digits < remaining_parts or remaining_digits > remaining_parts * 3:
return
for length in range(1, 4):
if start + length > len(s):
break
part = s[start : start + length]
if is_valid_part(part):
parts.append(part)
backtrack(start + length, parts)
parts.pop()
backtrack(0, [])
return results
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(1) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Reveal Cards In Increasing Order
Source: https://leetcode-py.wisl.dev/problems/reveal-cards-in-increasing-order
Tested Python solution for LeetCode 950 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 950, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Queue](/catalog/topics/queue), [Sorting](/catalog/topics/sorting), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/reveal-cards-in-increasing-order/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 950 # by problem number
lcpy gen -s reveal_cards_in_increasing_order # by problem name
```
## Problem
\You are given an integer array \deck\. There is a deck of cards where every card has a unique integer. The integer on the \i\th\\ card is \deck\[i]\.\
You can order the deck in any order you want. Initially, all the cards start face down (unrevealed) in one deck.\
\You will do the following steps repeatedly until all cards are revealed:\
\Return \an ordering of the deck that would reveal the cards in \increasing\ order\.\
\\Note\ that the first entry in the answer is considered to be the top of the deck.\
### Examples ``` Input: deck = [17,13,11,2,3,5,7] Output: [2,13,3,11,5,17,7] Explanation: We get the deck in the order [17,13,11,2,3,5,7] (this order does not matter), and reorder it. ``` ``` Input: deck = [1,1000] Output: [1,1000] ``` ### Constraints * 1 \<= deck.length \<= 1000 * 1 \<= deck\[i] \<= 10^6 * All the values of deck are unique. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reveal_cards_in_increasing_order/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reveal_cards_in_increasing_order/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(n log n) # Space: O(n) def deck_revealed_increasing(self, deck: list[int]) -> list[int]: queue: deque[int] = deque(range(len(deck))) result: list[int] = [0] * len(deck) for card in sorted(deck): # Reveal the card at the front position result[queue.popleft()] = card # Move the next position to the bottom if queue: queue.append(queue.popleft()) return result ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Reverse Bits Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/reverse-bits Tested Python solution for LeetCode 190 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 190, [Easy](/catalog/easy). Topics: [Divide and Conquer](/catalog/topics/divide-and-conquer), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/reverse-bits/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 190 # by problem number lcpy gen -s reverse_bits # by problem name ``` ## Problem Reverse bits of a given 32 bits signed integer. ### Examples ``` Input: n = 43261596 Output: 964176192 Explanation: | Integer | Binary | |------------|-------------------------------------| | 43261596 | 00000010100101000001111010011100 | | 964176192 | 00111001011110000010100101000000 | ``` ``` Input: n = 2147483644 Output: 1073741822 Explanation: | Integer | Binary | |-------------|-------------------------------------| | 2147483644 | 01111111111111111111111111111100 | | 1073741822 | 00111111111111111111111111111110 | ``` ### Constraints * 0 \<= n \<= 2^31 - 2 * n is even. **Follow up:** If this function is called many times, how would you optimize it? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_bits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_bits/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(1) - always 32 iterations # Space: O(1) - only using constant extra space def reverse_bits(self, n: int) -> int: """ Reverse the bits of a 32-bit unsigned integer. Algorithm: 1. Initialize result to 0 2. For each of the 32 bits: - Extract the rightmost bit of n using (n & 1) - Add it to the result at the appropriate position - Right shift n to get the next bit - Left shift result to make room for the next bit 3. Return the result This approach is optimal for single calls. For multiple calls, we could use a lookup table for optimization. """ result = 0 for _ in range(32): result = (result << 1) | (n & 1) n >>= 1 return result ``` ## Complexity | Time | Space | | --------------------------- | -------------------------------------- | | O(1) - always 32 iterations | O(1) - only using constant extra space | ## Tags [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Reverse Integer Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/reverse-integer Tested Python solution for LeetCode 7 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 7, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/reverse-integer/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 7 # by problem number lcpy gen -s reverse_integer # by problem name ``` ## Problem Given a signed 32-bit integer `x`, return `x` *with its digits reversed*. If reversing `x` causes the value to go outside the signed 32-bit integer range `[-2^31, 2^31 - 1]`, then return `0`. **Assume the environment does not allow you to store 64-bit integers (signed or unsigned).** ### Examples ``` Input: x = 123 Output: 321 ``` ``` Input: x = -123 Output: -321 ``` ``` Input: x = 120 Output: 21 ``` ### Constraints * -2^31 \<= x \<= 2^31 - 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_integer/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_integer/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log(x)) # Space: O(1) def reverse(self, x: int) -> int: int_max = 2**31 - 1 result = 0 sign = 1 if x >= 0 else -1 x = abs(x) while x != 0: digit = x % 10 x //= 10 # Check for overflow before adding the digit if result > (int_max - digit) // 10: return 0 result = result * 10 + digit return sign * result ``` ## Complexity | Time | Space | | --------- | ----- | | O(log(x)) | O(1) | ## Tags [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Reverse Linked List Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/reverse-linked-list Tested Python solution for LeetCode 206 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 206, [Easy](/catalog/easy). Topics: [Linked List](/catalog/topics/linked-list), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/reverse-linked-list/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 206 # by problem number lcpy gen -s reverse_linked_list # by problem name ``` ## Problem Given the `head` of a singly linked list, reverse the list, and return the reversed list. ### Examples  ``` Input: head = [1,2,3,4,5] Output: [5,4,3,2,1] ```  ``` Input: head = [1,2] Output: [2,1] ``` ``` Input: head = [] Output: [] ``` ### Constraints * The number of nodes in the list is the range `[0, 5000]`. * `-5000 <= Node.val <= 5000` **Follow up:** A linked list can be reversed either iteratively or recursively. Could you implement both? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_linked_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) # Space: O(1) def reverse_list(self, head: ListNode[int] | None) -> ListNode[int] | None: if not head: return None # Iterative approach using three pointers # Example: [1,2,3] -> [3,2,1] # # Initial: prev curr # None ↓ # 1 -> 2 -> 3 -> None # prev: ListNode[int] | None = None curr: ListNode[int] | None = head while curr: # Store next node before breaking the link next_node = curr.next # # prev curr next_node # None ↓ ↓ # 1 -> 2 -> 3 -> None # # Reverse the current link curr.next = prev # None <- 1 2 -> 3 -> None # prev curr next_node # # Move pointers forward prev = curr curr = next_node # 1 <- 2 3 -> None # prev curr # # 1 <- 2 <- 3 None # prev curr # prev now points to new head of reversed list return prev ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Reverse Linked List II Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-linked-list-ii Tested Python solution for LeetCode 92 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 92, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/reverse-linked-list-ii/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 92 # by problem number lcpy gen -s reverse_linked_list_ii # by problem name ``` ## Problem 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. ### Examples ``` Input: head = [1,2,3,4,5], left = 2, right = 4 Output: [1,4,3,2,5] ``` ``` Input: head = [5], left = 1, right = 1 Output: [5] ``` ### Constraints * The number of nodes in the list is n * 1 \<= n \<= 500 * -500 \<= Node.val \<= 500 * 1 \<= left \<= right \<= n **Follow up:** Could you do it in one pass? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_linked_list_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_linked_list_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) # Space: O(1) def reverse_between( self, head: ListNode[int] | None, left: int, right: int ) -> ListNode[int] | None: if not head or left == right: return head dummy = ListNode[int](0) dummy.next = head prev = dummy # Move to position before left for _ in range(left - 1): assert prev.next prev = prev.next # Reverse from left to right using iterative approach # Example: [1,2,3,4,5] left=2, right=4 -> [1,4,3,2,5] # # Initial: prev curr # ↓ ↓ # 1 -> 2 -> 3 -> 4 -> 5 # assert prev.next curr = prev.next # First node to be reversed (will become last after reversal) # Reverse by moving nodes one by one to the front of the section for _ in range(right - left): assert curr.next next_node = curr.next # Node to move to front # # prev curr next_node # ↓ ↓ ↓ # 1 -> 2 -> 3 -> 4 -> 5 # curr.next = next_node.next # 1 -> 2 -----> 4 -> 5 # 3 ↗ # next_node.next = prev.next # 1 -> 2 -----> 4 -> 5 # 3 ↗ # prev.next = next_node # 1 -> 3 -> 2 -> 4 -> 5 # prev ↑ curr # next_node return dummy.next ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Reverse Nodes in k-Group Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-nodes-in-k-group Tested Python solution for LeetCode 25 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 25, [Hard](/catalog/hard). Topics: [Linked List](/catalog/topics/linked-list), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/reverse-nodes-in-k-group/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 25 # by problem number lcpy gen -s reverse_nodes_in_k_group # by problem name ``` ## Problem Given the `head` of a linked list, reverse the nodes of the list `k` at a time, and return *the modified list*. `k` is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of `k` then left-out nodes, in the end, should remain as it is. You may not alter the values in the list's nodes, only nodes themselves may be changed. ### Examples  ``` Input: head = [1,2,3,4,5], k = 2 Output: [2,1,4,3,5] ```  ``` Input: head = [1,2,3,4,5], k = 3 Output: [3,2,1,4,5] ``` ### Constraints * The number of nodes in the list is n. * 1 \<= k \<= n \<= 5000 * 0 \<= Node.val \<= 1000 **Follow-up:** Can you solve the problem in `O(1)` extra memory space? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_nodes_in_k_group/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_nodes_in_k_group/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) # Space: O(1) def reverse_k_group(self, head: ListNode[int] | None, k: int) -> ListNode[int] | None: if not head or k == 1: return head # Check if we have at least k nodes curr: ListNode[int] | None = head count = 0 while curr and count < k: curr = curr.next count += 1 if count == k: # Reverse the first k nodes prev = self.reverse_k_group(curr, k) # Recursively reverse remaining groups curr = head while count > 0 and curr is not None: next_temp = curr.next curr.next = prev prev = curr curr = next_temp count -= 1 head = prev return head ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Reverse Odd Levels of Binary Tree Source: https://leetcode-py.wisl.dev/problems/reverse-odd-levels-of-binary-tree Tested Python solution for LeetCode 2415 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 2415, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/reverse-odd-levels-of-binary-tree/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2415 # by problem number lcpy gen -s reverse_odd_levels_of_binary_tree # by problem name ``` ## Problem Given the `root` of a \perfect\ binary tree, reverse the node values at each \odd\ level of the tree. For example, suppose the node values at level 3 are `[2,1,3,4,7,11,29,18]`, then it should become `[18,29,11,7,4,3,1,2]`. Return \the root of the reversed tree\. A binary tree is \perfect\ if all parent nodes have two children and all leaves are on the same level. The \level\ of a node is the number of edges along the path between it and the root node. ### Examples  ``` Input: root = [2,3,5,8,13,21,34] Output: [2,5,3,8,13,21,34] Explanation: The tree has only one odd level. The nodes at level 1 are 3, 5 respectively, which are reversed and become 5, 3. ```  ``` Input: root = [7,13,11] Output: [7,11,13] Explanation: The nodes at level 1 are 13, 11, which are reversed and become 11, 13. ``` ``` Input: root = [0,1,2,0,0,0,0,1,1,1,1,2,2,2,2] Output: [0,2,1,0,0,0,0,2,2,2,2,1,1,1,1] Explanation: The odd levels have non-zero values. The nodes at level 1 were 1, 2, and are 2, 1 after the reversal. The nodes at level 3 were 1, 1, 1, 1, 2, 2, 2, 2, and are 2, 2, 2, 2, 1, 1, 1, 1 after the reversal. ``` ### Constraints * The number of nodes in the tree is in the range \[1, 2^14] * 0 \<= Node.val \<= 10^5 * root is a perfect binary tree ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_odd_levels_of_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_odd_levels_of_binary_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque from leetcode_py import TreeNode class Solution: # Time: O(n) # Space: O(w) for the level queue, w = 2^depth at the deepest level def reverse_odd_levels(self, root: TreeNode[int] | None) -> TreeNode[int] | None: if root is None: return None queue: deque[TreeNode[int]] = deque([root]) depth = 0 while queue: level = list(queue) if depth % 2 == 1: left = 0 right = len(level) - 1 while left < right: level[left].val, level[right].val = level[right].val, level[left].val left += 1 right -= 1 queue = deque( child for node in level for child in (node.left, node.right) if child is not None ) depth += 1 return root ``` ## Complexity | Time | Space | | ---- | ---------------------------------------------------------- | | O(n) | O(w) for the level queue, w = 2^depth at the deepest level | ## Tags [NeetCode All](/catalog/neetcode). # Reverse Only Letters Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-only-letters Tested Python solution for LeetCode 917 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 917, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-only-letters/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 917 # by problem number lcpy gen -s reverse_only_letters # by problem name ``` ## Problem Given a string `s`, reverse the string according to the following rules: * All the characters that are not English letters remain in the same position. * All the English letters (lowercase or uppercase) should be reversed. Return `s` *after reversing it*. ### Examples ``` Input: s = "ab-cd" Output: "dc-ba" ``` ``` Input: s = "a-bC-dEf-ghIj" Output: "j-Ih-gfE-dCba" ``` ``` Input: s = "Test1ng-Leet=code-Q!" Output: "Qedo1ct-eeLg=ntse-T!" ``` ### Constraints * 1 \<= s.length \<= 100 * s consists of characters with ASCII values in the range \[33, 122]. * s does not contain '"' or '\\'. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_only_letters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_only_letters/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def reverse_only_letters(self, s: str) -> str: chars = list(s) left, right = 0, len(chars) - 1 while left < right: if not chars[left].isalpha(): left += 1 elif not chars[right].isalpha(): right -= 1 else: chars[left], chars[right] = chars[right], chars[left] left += 1 right -= 1 return "".join(chars) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Reverse Pairs Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/reverse-pairs Tested Python solution for LeetCode 493 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 493, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Binary Indexed Tree](/catalog/topics/binary-indexed-tree), [Segment Tree](/catalog/topics/segment-tree), Merge Sort, [Ordered Set](/catalog/topics/ordered-set), Treap. [View on LeetCode](https://leetcode.com/problems/reverse-pairs/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 493 # by problem number lcpy gen -s reverse_pairs # by problem name ``` ## Problem Given an integer array `nums`, return the number of **reverse pairs** in the array. A reverse pair is a pair `(i, j)` where: * `0 <= i < j < nums.length` and * `nums[i] > 2 * nums[j]`. ### Examples ``` Input: nums = [1,3,2,3,1] Output: 2 ``` **Explanation:** The reverse pairs are: (1, 4) --> nums\[1] = 3, nums\[4] = 1, 3 > 2 \* 1 (3, 4) --> nums\[3] = 3, nums\[4] = 1, 3 > 2 \* 1 ``` Input: nums = [2,4,3,5,1] Output: 3 ``` **Explanation:** The reverse pairs are: (1, 4) --> nums\[1] = 4, nums\[4] = 1, 4 > 2 \* 1 (2, 4) --> nums\[2] = 3, nums\[4] = 1, 3 > 2 \* 1 (3, 4) --> nums\[3] = 5, nums\[4] = 1, 5 > 2 \* 1 ### Constraints * 1 \<= nums.length \<= 5 \* 10^4 * -2^31 \<= nums\[i] \<= 2^31 - 1 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_pairs/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) def reverse_pairs(self, nums: list[int]) -> int: def merge_sort(values: list[int]) -> tuple[list[int], int]: if len(values) <= 1: return values, 0 mid = len(values) // 2 left, left_pairs = merge_sort(values[:mid]) right, right_pairs = merge_sort(values[mid:]) pairs = left_pairs + right_pairs j = 0 for x in left: while j < len(right) and x > 2 * right[j]: j += 1 pairs += j merged: list[int] = [] i = 0 j = 0 while i < len(left) and j < len(right): if left[i] <= right[j]: merged.append(left[i]) i += 1 else: merged.append(right[j]) j += 1 merged.extend(left[i:]) merged.extend(right[j:]) return merged, pairs _, total = merge_sort(nums) return total ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags # Reverse String Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/reverse-string Tested Python solution for LeetCode 344 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 344, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-string/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 344 # by problem number lcpy gen -s reverse_string # by problem name ``` ## Problem Write a function that reverses a string. The input string is given as an array of characters `s`. You must do this by modifying the input array [in-place](https://en.wikipedia.org/wiki/In-place_algorithm) with `O(1)` extra memory. ### Examples ``` Input: s = ["h","e","l","l","o"] Output: ["o","l","l","e","h"] ``` ``` Input: s = ["H","a","n","n","a","h"] Output: ["h","a","n","n","a","H"] ``` ### Constraints * 1 \<= s.length \<= 10^5 * s\[i] is a [printable ascii character](https://en.wikipedia.org/wiki/ASCII#Printable_characters). ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def reverse_string(self, s: list[str]) -> None: left = 0 right = len(s) - 1 while left < right: s[left], s[right] = s[right], s[left] left += 1 right -= 1 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Reverse String II Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/reverse-string-ii Tested Python solution for LeetCode 541 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 541, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-string-ii/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 541 # by problem number lcpy gen -s reverse_string_ii # by problem name ``` ## Problem Given a string `s` and an integer `k`, reverse the first `k` characters for every `2k` characters counting from the start of the string. If there are fewer than `k` characters left, reverse all of them. If there are less than `2k` but greater than or equal to `k` characters, then reverse the first `k` characters and leave the other as original. ### Examples ``` Input: s = "abcdefg", k = 2 Output: "bacdfeg" ``` ``` Input: s = "abcd", k = 2 Output: "bacd" ``` ### Constraints * 1 \<= s.length \<= 10^4 * s consists of only lowercase English letters. * 1 \<= k \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_string_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_string_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def reverse_str(self, s: str, k: int) -> str: chars = list(s) for i in range(0, len(chars), 2 * k): chars[i : i + k] = reversed(chars[i : i + k]) return "".join(chars) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Reverse Substrings Between Each Pair of Source: https://leetcode-py.wisl.dev/problems/reverse-substrings-between-each-pair-of-parentheses Tested Python solution for LeetCode 1190 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 1190, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), Bracket Sequences. [View on LeetCode](https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1190 # by problem number lcpy gen -s reverse_substrings_between_each_pair_of_parentheses # by problem name ``` ## Problem You are given a string `s` that consists of lower case English letters and brackets. Reverse the strings in each pair of matching parentheses, starting from the innermost one. Your result should **not** contain any brackets. ### Examples ``` Input: s = "(abcd)" Output: "dcba" ``` ``` Input: s = "(u(love)i)" Output: "iloveu" Explanation: The substring "love" is reversed first, then the whole string is reversed. ``` ``` Input: s = "(ed(et(oc))el)" Output: "leetcode" Explanation: First, we reverse the substring "oc", then "etco", and finally, the whole string. ``` ### Constraints * `1 <= s.length <= 2000` * `s` only contains lower case English characters and parentheses. * It is guaranteed that all parentheses are balanced. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_substrings_between_each_pair_of_parentheses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_substrings_between_each_pair_of_parentheses/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) worst case, O(n) average # Space: O(n) def reverse_parentheses(self, s: str) -> str: stack: list[str] = [] for char in s: if char == ")": segment: list[str] = [] while stack and stack[-1] != "(": segment.append(stack.pop()) stack.pop() stack.extend(segment) else: stack.append(char) return "".join(stack) ``` ## Complexity | Time | Space | | ------------------------------- | ----- | | O(n^2) worst case, O(n) average | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Reverse Vowels of a String Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-vowels-of-a-string Tested Python solution for LeetCode 345 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 345, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-vowels-of-a-string/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 345 # by problem number lcpy gen -s reverse_vowels_of_a_string # by problem name ``` ## Problem Given a string `s`, reverse only all the vowels in the string and return it. The vowels are `'a'`, `'e'`, `'i'`, `'o'`, and `'u'`, and they can appear in both lower and upper cases, more than once. ### Examples ``` Input: s = \"IceCreAm\" Output: \"AceCreIm\" ``` **Explanation:** The vowels in `s` are `['I', 'e', 'e', 'A']`. On reversing the vowels, `s` becomes "AceCreIm". ``` Input: s = \"leetcode\" Output: \"leotcede\" ``` ### Constraints * 1 \<= s.length \<= 3 \* 10^5 * s consists of printable ASCII characters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_vowels_of_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_vowels_of_a_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def reverse_vowels(self, s: str) -> str: vowels = set("aeiouAEIOU") chars = list(s) left, right = 0, len(chars) - 1 while left < right: while left < right and chars[left] not in vowels: left += 1 while left < right and chars[right] not in vowels: right -= 1 chars[left], chars[right] = chars[right], chars[left] left += 1 right -= 1 return "".join(chars) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Reverse Words in a String Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-words-in-a-string Tested Python solution for LeetCode 151 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 151, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-words-in-a-string/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 151 # by problem number lcpy gen -s reverse_words_in_a_string # by problem name ``` ## Problem Given an input string `s`, reverse the order of the words. A word is defined as a sequence of non-space characters. The words in `s` will be separated by at least one space. Return a string of the words in reverse order concatenated by a single space. ### Examples ``` Input: s = "the sky is blue" Output: "blue is sky the" ``` ``` Input: s = " hello world " Output: "world hello" Explanation: Your reversed string should not contain leading or trailing spaces. ``` ``` Input: s = "a good example" Output: "example good a" Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string. ``` ### Constraints * 1 \<= s.length \<= 10^4 * s contains English letters (upper-case and lower-case), digits, and spaces ' '. * There is at least one word in s. **Follow up:** If the string data type is mutable in your language, can you solve it in-place with O(1) extra space? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_words_in_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_words_in_a_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) where n is the length of the string # Space: O(n) for the split list def reverse_words(self, s: str) -> str: # Split by whitespace (handles multiple spaces) words = s.split() # Reverse the list and join with single space return " ".join(reversed(words)) ``` ## Complexity | Time | Space | | ---------------------------------------- | ----------------------- | | O(n) where n is the length of the string | O(n) for the split list | ## Tags [AlgoMaster 75](/catalog/algo-master-75). # Reverse Words in a String II Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-words-in-a-string-ii Tested Python solution for LeetCode 186 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 186, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-words-in-a-string-ii/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 186 # by problem number lcpy gen -s reverse_words_in_a_string_ii # by problem name ``` ## Problem Given a character array `s`, reverse the order of the **words**. A **word** is defined as a sequence of non-space characters. The **words** in `s` will be separated by a single space. Your code must solve the problem **in-place**, i.e. without allocating extra space. ### Examples ``` Input: s = ["t","h","e"," ","s","k","y"," ","i","s"," ","b","l","u","e"] Output: ["b","l","u","e"," ","i","s"," ","s","k","y"," ","t","h","e"] ``` ``` Input: s = ["a"] Output: ["a"] ``` ### Constraints * 1 \<= s.length \<= 10^5 * s\[i] is an English letter (uppercase or lowercase), digit, or space ' ' * There is at least one word in s * s does not contain leading or trailing spaces * All the words in s are guaranteed to be separated by a single space ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_words_in_a_string_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_words_in_a_string_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def reverse_words(self, s: list[str]) -> None: def reverse(left: int, right: int) -> None: while left < right: s[left], s[right] = s[right], s[left] left += 1 right -= 1 reverse(0, len(s) - 1) start = 0 for i, ch in enumerate(s): if ch == " ": reverse(start, i - 1) start = i + 1 reverse(start, len(s) - 1) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Reverse Words in a String III Python Solution Source: https://leetcode-py.wisl.dev/problems/reverse-words-in-a-string-iii Tested Python solution for LeetCode 557 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 557, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/reverse-words-in-a-string-iii/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 557 # by problem number lcpy gen -s reverse_words_in_a_string_iii # by problem name ``` ## Problem Given a string `s`, reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. ### Examples ``` Input: s = "Let's take LeetCode contest" Output: "s'teL ekat edoCteeL tsetnoc" ``` ``` Input: s = "Mr Ding" Output: "rM gniD" ``` ### Constraints * 1 \<= s.length \<= 5 \* 10^4 * `s` contains printable ASCII characters. * `s` does not contain any leading or trailing spaces. * There is **at least one** word in `s`. * All the words in `s` are separated by a single space. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_words_in_a_string_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/reverse_words_in_a_string_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def reverse_words(self, s: str) -> str: return " ".join(word[::-1] for word in s.split(" ")) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # RLE Iterator Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rle-iterator Tested Python solution for LeetCode 900 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 900, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Design](/catalog/topics/design), [Counting](/catalog/topics/counting), Iterator. [View on LeetCode](https://leetcode.com/problems/rle-iterator/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 900 # by problem number lcpy gen -s rle_iterator # by problem name ``` ## Problem We can use run-length encoding (i.e., RLE) to encode a sequence of integers. In a run-length encoded array of even length `encoding` (0-indexed), for all even `i`, `encoding[i]` tells us the number of times that the non-negative integer value `encoding[i + 1]` is repeated in the sequence. * For example, the sequence `arr = [8,8,8,5,5]` can be encoded to be `encoding = [3,8,2,5]`. `encoding = [3,8,0,9,2,5]` and `encoding = [2,8,1,8,2,5]` are also valid RLE of `arr`. Given a run-length encoded array, design an iterator that iterates through it. Implement the `RLEIterator` class: * `RLEIterator(int[] encoded)` Initializes the object with the encoded array `encoded`. * `int next(int n)` Exhausts the next `n` elements and returns the last element exhausted in this way. If there is no element left to exhaust, return `-1` instead. ### Examples ``` Input ["RLEIterator", "next", "next", "next", "next"] [[[3, 8, 0, 9, 2, 5]], [2], [1], [1], [2]] Output [null, 8, 8, 5, -1] Explanation RLEIterator rLEIterator = new RLEIterator([3, 8, 0, 9, 2, 5]); // This maps to the sequence [8,8,8,5,5]. rLEIterator.next(2); // exhausts 2 terms of the sequence, returning 8. The remaining sequence is now [8, 5, 5]. rLEIterator.next(1); // exhausts 1 term of the sequence, returning 8. The remaining sequence is now [5, 5]. rLEIterator.next(1); // exhausts 1 term of the sequence, returning 5. The remaining sequence is now [5]. rLEIterator.next(2); // exhausts 2 terms, returning -1. This is because the first term exhausted was 5, but the second term did not exist. Since the last term exhausted does not exist, we return -1. ``` ### Constraints * `2 <= encoding.length <= 1000` * `encoding.length` is even. * `0 <= encoding[i] <= 10^9` * `1 <= n <= 10^9` * At most `1000` calls will be made to `next`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rle_iterator/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rle_iterator/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from bisect import bisect_left class RLEIterator: # Time: O(1) init, O(log k) next where k is the number of runs # Space: O(k) for the prefix counts def __init__(self, encoding: list[int]) -> None: self.prefix: list[int] = [] self.values = encoding[1::2] self.pos: int = 0 total = 0 for count in encoding[::2]: total += count self.prefix.append(total) def next(self, n: int) -> int: self.pos += n idx = bisect_left(self.prefix, self.pos) if idx == len(self.prefix): return -1 return self.values[idx] ``` ## Complexity | Time | Space | | ------------------------------------------------------ | -------------------------- | | O(1) init, O(log k) next where k is the number of runs | O(k) for the prefix counts | ## Tags # Robot Bounded In Circle Python Solution Source: https://leetcode-py.wisl.dev/problems/robot-bounded-in-circle Tested Python solution for LeetCode 1041 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 1041, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/robot-bounded-in-circle/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1041 # by problem number lcpy gen -s robot_bounded_in_circle # by problem name ``` ## Problem On an infinite plane, a robot initially stands at `(0, 0)` and faces north. Note that: * The north direction is the positive direction of the y-axis. * The south direction is the negative direction of the y-axis. * The east direction is the positive direction of the x-axis. * The west direction is the negative direction of the x-axis. The robot can receive one of three instructions: * `"G"`: go straight 1 unit. * `"L"`: turn 90 degrees to the left (i.e., anti-clockwise direction). * `"R"`: turn 90 degrees to the right (i.e., clockwise direction). The robot performs the `instructions` given in order, and repeats them forever. Return `true` if and only if there exists a circle in the plane such that the robot never leaves the circle. ### Examples ``` Input: instructions = "GGLLGG" Output: true Explanation: The robot is initially at (0, 0) facing the north direction. "G": move one step. Position: (0, 1). Direction: North. "G": move one step. Position: (0, 2). Direction: North. "L": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: West. "L": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: South. "G": move one step. Position: (0, 1). Direction: South. "G": move one step. Position: (0, 0). Direction: South. Repeating the instructions, the robot goes into the cycle: (0, 0) --> (0, 1) --> (0, 2) --> (0, 1) --> (0, 0). Based on that, we return true. ``` ``` Input: instructions = "GG" Output: false Explanation: The robot is initially at (0, 0) facing the north direction. "G": move one step. Position: (0, 1). Direction: North. "G": move one step. Position: (0, 2). Direction: North. Repeating the instructions, keeps advancing in the north direction and does not go into cycles. Based on that, we return false. ``` ``` Input: instructions = "GL" Output: true Explanation: The robot is initially at (0, 0) facing the north direction. "G": move one step. Position: (0, 1). Direction: North. "L": turn 90 degrees anti-clockwise. Position: (0, 1). Direction: West. "G": move one step. Position: (-1, 1). Direction: West. "L": turn 90 degrees anti-clockwise. Position: (-1, 1). Direction: South. "G": move one step. Position: (-1, 0). Direction: South. "L": turn 90 degrees anti-clockwise. Position: (-1, 0). Direction: East. "G": move one step. Position: (0, 0). Direction: East. "L": turn 90 degrees anti-clockwise. Position: (0, 0). Direction: North. Repeating the instructions, the robot goes into the cycle: (0, 0) --> (0, 1) --> (-1, 1) --> (-1, 0) --> (0, 0). Based on that, we return true. ``` ### Constraints * `1 <= instructions.length <= 100` * `instructions[i]` is `'G'`, `'L'` or, `'R'`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_bounded_in_circle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_bounded_in_circle/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def is_robot_bounded(self, instructions: str) -> bool: x = y = 0 dx, dy = 0, 1 for instruction in instructions: if instruction == "G": x, y = x + dx, y + dy elif instruction == "L": dx, dy = -dy, dx else: dx, dy = dy, -dx return (x == 0 and y == 0) or (dx, dy) != (0, 1) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Robot Collisions Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/robot-collisions Tested Python solution for LeetCode 2751 with 30 pytest cases. Generate a practice environment with lcpy. LeetCode 2751, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Sorting](/catalog/topics/sorting), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/robot-collisions/description/). Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2751 # by problem number lcpy gen -s robot_collisions # by problem name ``` ## Problem There are n 1-indexed robots, each having a position on a line, health, and movement direction. You are given 0-indexed integer arrays positions, healths, and a string directions (directions\[i] is either 'L' for left or 'R' for right). All integers in positions are unique. All robots start moving on the line simultaneously at the same speed in their given directions. If two robots ever share the same position while moving, they will collide. If two robots collide, the robot with lower health is removed from the line, and the health of the other robot decreases by one. The surviving robot continues in the same direction it was going. If both robots have the same health, they are both removed from the line. Your task is to determine the health of the robots that survive the collisions, in the same order that the robots were given, i.e. final health of robot 1 (if survived), final health of robot 2 (if survived), and so on. If there are no survivors, return an empty array. Return an array containing the health of the remaining robots (in the order they were given in the input), after no further collisions can occur. Note: The positions may be unsorted. ### Examples  ``` Input: positions = [5,4,3,2,1], healths = [2,17,9,15,10], directions = "RRRRR" Output: [2,17,9,15,10] Explanation: No collision occurs in this example, since all robots are moving in the same direction. So, the health of the robots in order from the first robot is returned, [2, 17, 9, 15, 10]. ```  ``` Input: positions = [3,5,2,6], healths = [10,10,15,12], directions = "RLRL" Output: [14] Explanation: There are 2 collisions in this example. Firstly, robot 1 and robot 2 will collide, and since both have the same health, they will be removed from the line. Next, robot 3 and robot 4 will collide and since robot 4's health is smaller, it gets removed, and robot 3's health becomes 15 - 1 = 14. Only robot 3 remains, so we return [14]. ```  ``` Input: positions = [1,2,5,6], healths = [10,10,11,11], directions = "RLRL" Output: [] Explanation: Robot 1 and robot 2 will collide and since both have the same health, they are both removed. Robot 3 and 4 will collide and since both have the same health, they are both removed. So, we return an empty array, []. ``` ### Constraints * 1 \<= positions.length == healths.length == directions.length == n \<= 10^5 * 1 \<= positions\[i], healths\[i] \<= 10^9 * `directions[i]` is `'L'` or `'R'` * All values in `positions` are distinct ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_collisions/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_collisions/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n log n) # Space: O(n) def survived_robots_healths( self, positions: list[int], healths: list[int], directions: str ) -> list[int]: remaining = list(healths) stack: list[int] = [] for i in sorted(range(len(positions)), key=positions.__getitem__): if directions[i] == "R": stack.append(i) continue while stack and remaining[i] > 0: j = stack[-1] if remaining[j] > remaining[i]: remaining[j] -= 1 remaining[i] = 0 elif remaining[j] < remaining[i]: stack.pop() remaining[j] = 0 remaining[i] -= 1 else: stack.pop() remaining[j] = 0 remaining[i] = 0 return [remaining[i] for i in range(len(positions)) if remaining[i] > 0] ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Robot Return to Origin Python Solution Source: https://leetcode-py.wisl.dev/problems/robot-return-to-origin Tested Python solution for LeetCode 657 with 32 pytest cases. Generate a practice environment with lcpy. LeetCode 657, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/robot-return-to-origin/description/). Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 657 # by problem number lcpy gen -s robot_return_to_origin # by problem name ``` ## Problem There is a robot starting at the position `(0, 0)`, the origin, on a 2D plane. Given a sequence of its moves, judge if this robot **ends up at** `(0, 0)` after it completes its moves. You are given a string `moves` that represents the move sequence of the robot where `moves[i]` represents its `ith` move. Valid moves are `'R'` (right), `'L'` (left), `'U'` (up), and `'D'` (down). Return `true` *if the robot returns to the origin after it finishes all of its moves, or* `false` *otherwise*. **Note**: The way that the robot is "facing" is irrelevant. `'R'` will always make the robot move to the right once, `'L'` will always make it move left, etc. Also, assume that the magnitude of the robot's movement is the same for each move. ### Examples ``` Input: moves = "UD" Output: true Explanation: The robot moves up once, and then down once. All moves have the same magnitude, so it ended up at the origin where it started. Therefore, we return true. ``` ``` Input: moves = "LL" Output: false Explanation: The robot moves left twice. It ends up two "moves" to the left of the origin. We return false because it is not at the origin at the end of its moves. ``` ### Constraints * 1 \<= moves.length \<= 2 \* 10^4 * moves only contains the characters 'U', 'D', 'L' and 'R'. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_return_to_origin/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_return_to_origin/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def judge_circle(self, moves: str) -> bool: x = 0 y = 0 for move in moves: if move == "U": y += 1 elif move == "D": y -= 1 elif move == "L": x -= 1 else: x += 1 return x == 0 and y == 0 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Robot Room Cleaner Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/robot-room-cleaner Tested Python solution for LeetCode 489 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 489, [Hard](/catalog/hard). Topics: [Backtracking](/catalog/topics/backtracking), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/robot-room-cleaner/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 489 # by problem number lcpy gen -s robot_room_cleaner # by problem name ``` ## Problem You are controlling a robot that is located somewhere in a room. The room is modeled as an `m x n` binary grid where `0` represents a wall and `1` represents an empty slot. The robot starts at an unknown location in the room that is guaranteed to be empty, and you do not have access to the grid, but you can move the robot using the given API `Robot`. You are tasked to use the robot to clean the entire room (i.e. clean every empty cell in the room). The robot with the four given APIs can move forward, turn left, or turn right. Each turn is `90` degrees. When the robot tries to move into a wall cell, its bumper sensor detects the obstacle, and it stays on the current cell. Design an algorithm to clean the entire room using the following APIs: ``` interface Robot { // returns true if next cell is open and robot moves into the cell. // returns false if next cell is obstacle and robot stays on the current cell. boolean move(); // Robot will stay on the same cell after calling turnLeft/turnRight. // Each turn will be 90 degrees. void turnLeft(); void turn_right(); // Clean the current cell. void clean(); } ``` **Note** that the initial direction of the robot will be facing up. You can assume all four edges of the grid are all surrounded by a wall. ### Examples  ``` Input: room = [[1,1,1,1,1,0,1,1],[1,1,1,1,1,0,1,1],[1,0,1,1,1,1,1,1],[0,0,0,1,0,0,0,0],[1,1,1,1,1,1,1,1]], row = 1, col = 3 Output: Robot cleaned all rooms. Explanation: All grids in the room are marked by either 0 or 1. 0 means the cell is blocked, while 1 means the cell is accessible. The robot initially starts at the position of row=1, col=3. ``` ``` Input: room = [[1]], row = 0, col = 0 Output: Robot cleaned all rooms. ``` ### Constraints * `m == room.length` * `n == room[i].length` * `1 <= m <= 100` * `1 <= n <= 200` * `room[i][j]` is either `0` or `1`. * `0 <= row < m` * `0 <= col < n` * `room[row][col] == 1` * All the empty cells can be visited from the starting position. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_room_cleaner/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/robot_room_cleaner/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Robot: # Test-harness API: backs the interactive move/turn/clean interface with the grid def __init__(self, room: list[list[int]], row: int, col: int) -> None: self.room = room self.row = row self.col = col self.direction = 0 # 0 up, 1 right, 2 down, 3 left self.cleaned: set[tuple[int, int]] = set() def move(self) -> bool: dr = (-1, 0, 1, 0)[self.direction] dc = (0, 1, 0, -1)[self.direction] nr, nc = self.row + dr, self.col + dc if ( nr < 0 or nr >= len(self.room) or nc < 0 or nc >= len(self.room[0]) or self.room[nr][nc] == 0 ): return False self.row, self.col = nr, nc return True def turn_left(self) -> None: self.direction = (self.direction + 3) % 4 def turn_right(self) -> None: self.direction = (self.direction + 1) % 4 def clean(self) -> None: self.cleaned.add((self.row, self.col)) class Solution: # Time: O(m * n) # Space: O(m * n) visited set def clean_room(self, robot: Robot) -> None: deltas = ((-1, 0), (0, 1), (1, 0), (0, -1)) visited: set[tuple[int, int]] = set() def go_back() -> None: robot.turn_right() robot.turn_right() robot.move() robot.turn_right() robot.turn_right() def backtrack(cell: tuple[int, int], direction: int) -> None: visited.add(cell) robot.clean() for k in range(4): nd = (direction + k) % 4 ncell = (cell[0] + deltas[nd][0], cell[1] + deltas[nd][1]) if ncell not in visited and robot.move(): backtrack(ncell, nd) go_back() robot.turn_right() backtrack((0, 0), 0) ``` ## Complexity | Time | Space | | --------- | --------------------- | | O(m \* n) | O(m \* n) visited set | ## Tags [NeetCode All](/catalog/neetcode). # Roman to Integer Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/roman-to-integer Tested Python solution for LeetCode 13 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 13, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [Math](/catalog/topics/math), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/roman-to-integer/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 13 # by problem number lcpy gen -s roman_to_integer # by problem name ``` ## Problem Roman numerals are represented by seven different symbols: `I`, `V`, `X`, `L`, `C`, `D` and `M`. **Symbol** **Value** I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, `2` is written as `II` in Roman numeral, just two ones added together. `12` is written as `XII`, which is simply `X + II`. The number `27` is written as `XXVII`, which is `XX + V + II`. Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not `IIII`. Instead, the number four is written as `IV`. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as `IX`. There are six instances where subtraction is used: * `I` can be placed before `V` (5) and `X` (10) to make 4 and 9. * `X` can be placed before `L` (50) and `C` (100) to make 40 and 90. * `C` can be placed before `D` (500) and `M` (1000) to make 400 and 900. Given a roman numeral, convert it to an integer. ### Examples ``` Input: s = "III" Output: 3 Explanation: III = 3. ``` ``` Input: s = "LVIII" Output: 58 Explanation: L = 50, V= 5, III = 3. ``` ``` Input: s = "MCMXCIV" Output: 1994 Explanation: M = 1000, CM = 900, XC = 90 and IV = 4. ``` ### Constraints * 1 \<= s.length \<= 15 * `s` contains only the characters (`'I'`, `'V'`, `'X'`, `'L'`, `'C'`, `'D'`, `'M'`). * It is guaranteed that `s` is a valid roman numeral in the range `[1, 3999]`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/roman_to_integer/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/roman_to_integer/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def roman_to_int(self, s: str) -> int: values: dict[str, int] = { "I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000, } total = 0 prev = 0 # Walk right-to-left; subtract when a symbol is smaller than the previous one for char in reversed(s): current = values[char] if current < prev: total -= current else: total += current prev = current return total ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Rotate Array Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotate-array Tested Python solution for LeetCode 189 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 189, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/rotate-array/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 189 # by problem number lcpy gen -s rotate_array # by problem name ``` ## Problem Given an integer array `nums`, rotate the array to the right by `k` steps, where `k` is non-negative. ### Examples ``` Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] 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] ``` ``` Input: nums = [-1,-100,3,99], k = 2 Output: [3,99,-1,-100] Explanation: rotate 1 steps to the right: [99,-1,-100,3] rotate 2 steps to the right: [3,99,-1,-100] ``` ### Constraints * 1 \<= nums.length \<= 10^5 * -2^31 \<= nums\[i] \<= 2^31 - 1 * 0 \<= k \<= 10^5 **Follow up:** * Try to come up with as many solutions as you can. There are at least **three** different ways to solve this problem. * Could you do it in-place with `O(1)` extra space? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_array/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) - three passes through array # Space: O(1) - in-place rotation using reversal def rotate(self, nums: list[int], k: int) -> None: """ Rotate array right by k steps using triple reversal. Example: nums = [1,2,3,4,5,6,7], k = 3 Step 1: Reverse entire array [1,2,3,4,5,6,7] → [7,6,5,4,3,2,1] Step 2: Reverse first k elements [7,6,5,4,3,2,1] → [5,6,7,4,3,2,1] ↑k=3↑ Step 3: Reverse remaining elements [5,6,7,4,3,2,1] → [5,6,7,1,2,3,4] ✓ ↑remaining↑ """ n = len(nums) k = k % n # Handle k > n def reverse(start: int, end: int) -> None: while start < end: nums[start], nums[end] = nums[end], nums[start] start += 1 end -= 1 # Step 1: Reverse entire array reverse(0, n - 1) # Step 2: Reverse first k elements reverse(0, k - 1) # Step 3: Reverse remaining elements reverse(k, n - 1) ``` ## Complexity | Time | Space | | --------------------------------- | --------------------------------------- | | O(n) - three passes through array | O(1) - in-place rotation using reversal | ## Tags [Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Rotate Function Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotate-function Tested Python solution for LeetCode 396 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 396, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/rotate-function/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 396 # by problem number lcpy gen -s rotate_function # by problem name ``` ## Problem You are given an integer array `nums` of length `n`. Assume `arrk` to be an array obtained by rotating `nums` by `k` positions clock-wise. We define the **rotation function** `F` on `nums` as follow: * `F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1].` Return *the maximum value of* `F(0), F(1), ..., F(n-1)`. The test cases are generated so that the answer fits in a **32-bit** integer. ### Examples ``` Input: nums = [4,3,2,6] Output: 26 ``` **Explanation:** F(0) = (0 \* 4) + (1 \* 3) + (2 \* 2) + (3 \* 6) = 0 + 3 + 4 + 18 = 25 F(1) = (0 \* 6) + (1 \* 4) + (2 \* 3) + (3 \* 2) = 0 + 4 + 6 + 6 = 16 F(2) = (0 \* 2) + (1 \* 6) + (2 \* 4) + (3 \* 3) = 0 + 6 + 8 + 9 = 23 F(3) = (0 \* 3) + (1 \* 2) + (2 \* 6) + (3 \* 4) = 0 + 2 + 12 + 12 = 26 So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. ``` Input: nums = [100] Output: 0 ``` ### Constraints * n == nums.length * 1 \<= n \<= 10^5 * -100 \<= nums\[i] \<= 100 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_function/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_function/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def max_rotate_function(self, nums: list[int]) -> int: total = sum(nums) cur = sum(i * v for i, v in enumerate(nums)) best = cur for k in range(1, len(nums)): # rotating clockwise by k moves the last element of arr_(k-1) to index 0 # and adds total to every other index: F(k) = F(k-1) + total - n * nums[n - k] cur += total - len(nums) * nums[-k] best = max(best, cur) return best ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Rotate Image Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotate-image Tested Python solution for LeetCode 48 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 48, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/rotate-image/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 48 # by problem number lcpy gen -s rotate_image # by problem name ``` ## Problem You are given an `n x n` 2D `matrix` representing an image, rotate the image by **90** degrees (clockwise). You have to rotate the image **in-place**, which means you have to modify the input 2D matrix directly. **DO NOT** allocate another 2D matrix and do the rotation. ### Examples  ``` Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] Output: [[7,4,1],[8,5,2],[9,6,3]] ```  ``` Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]] ``` ### Constraints * `n == matrix.length == matrix[i].length` * `1 <= n <= 20` * `-1000 <= matrix[i][j] <= 1000` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_image/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_image/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n²) # Space: O(1) def rotate(self, matrix: list[list[int]]) -> None: n = len(matrix) # Transpose matrix for i in range(n): for j in range(i, n): matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] # Reverse each row for i in range(n): matrix[i].reverse() ``` ## Complexity | Time | Space | | ----- | ----- | | O(n²) | O(1) | ## Tags [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Rotate List Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotate-list Tested Python solution for LeetCode 61 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 61, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/rotate-list/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 61 # by problem number lcpy gen -s rotate_list # by problem name ``` ## Problem Given the `head` of a linked list, rotate the list to the right by `k` places. ### Examples  ``` Input: head = [1,2,3,4,5], k = 2 Output: [4,5,1,2,3] ```  ``` Input: head = [0,1,2], k = 4 Output: [2,0,1] ``` ### Constraints * The number of nodes in the list is in the range \[0, 500]. * -100 \<= Node.val \<= 100 * 0 \<= k \<= 2 \* 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n) — single pass to close ring then cut # Space: O(1) def rotate_right(self, head: ListNode[int] | None, k: int) -> ListNode[int] | None: if not head or not head.next or k == 0: return head # Count length and close the list into a ring tail = head length = 1 while tail.next: tail = tail.next length += 1 tail.next = head # Effective rotations; new tail is at (length - k % length) steps from head k %= length steps_to_new_tail = length - k new_tail = head for _ in range(steps_to_new_tail - 1): assert new_tail.next is not None new_tail = new_tail.next assert new_tail.next is not None new_head = new_tail.next new_tail.next = None return new_head ``` ## Complexity | Time | Space | | ----------------------------------------- | ----- | | O(n) — single pass to close ring then cut | O(1) | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Rotate String Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotate-string Tested Python solution for LeetCode 796 with 30 pytest cases. Generate a practice environment with lcpy. LeetCode 796, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching). [View on LeetCode](https://leetcode.com/problems/rotate-string/description/). Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 796 # by problem number lcpy gen -s rotate_string # by problem name ``` ## Problem Given two strings `s` and `goal`, return `true` *if and only if* `s` *can become* `goal` after some number of **shifts** on `s`. A **shift** on `s` consists of moving the leftmost character of `s` to the rightmost position. * For example, if `s = "abcde"`, then it will be `"bcdea"` after one shift. ### Examples ``` Input: s = "abcde", goal = "cdeab" Output: true ``` ``` Input: s = "abcde", goal = "abced" Output: false ``` ### Constraints * 1 \<= s.length, goal.length \<= 100 * s and goal consist of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotate_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def rotate_string(self, s: str, goal: str) -> bool: return len(s) == len(goal) and goal in s + s ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Rotated Digits Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotated-digits Tested Python solution for LeetCode 788 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 788, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/rotated-digits/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 788 # by problem number lcpy gen -s rotated_digits # by problem name ``` ## Problem An integer x is a good if after rotating each digit individually by 180 degrees, we get a valid number that is different from x. Each digit must be rotated - we cannot choose to leave it alone. A number is valid if each digit remains a digit after rotation. For example: * 0, 1, and 8 rotate to themselves, * 2 and 5 rotate to each other (in this case they are rotated in a different direction, in other words, 2 or 5 gets mirrored), * 6 and 9 rotate to each other, and * the rest of the numbers do not rotate to any other number and become invalid. Given an integer n, return the number of good integers in the range \[1, n]. ### Examples ``` Input: n = 10 Output: 4 Explanation: There are four good numbers in the range [1, 10] : 2, 5, 6, 9. Note that 1 and 10 are not good numbers, since they remain unchanged after rotating. ``` ``` Input: n = 1 Output: 0 ``` ``` Input: n = 2 Output: 1 ``` ### Constraints * 1 \<= n \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotated_digits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotated_digits/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log n) # Space: O(log n) def rotated_digits(self, n: int) -> int: valid = frozenset("0125689") flipping = frozenset("2569") digits = str(n) total = 0 has_flip = False for i, ch in enumerate(digits): rest = len(digits) - i - 1 for c in "0123456789"[: int(ch)]: if c not in valid: continue if has_flip or c in flipping: total += 7**rest else: total += 7**rest - 3**rest if ch not in valid: return total has_flip = has_flip or ch in flipping return total + (1 if has_flip else 0) ``` ## Complexity | Time | Space | | -------- | -------- | | O(log n) | O(log n) | ## Tags # Rotating the Box Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotating-the-box Tested Python solution for LeetCode 1861 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 1861, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/rotating-the-box/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1861 # by problem number lcpy gen -s rotating_the_box # by problem name ``` ## Problem You are given an `m x n` matrix of characters `boxGrid` representing a side-view of a box. Each cell of the box is one of the following: * A stone `'#'` * A stationary obstacle `'*'` * Empty `'.'` The box is rotated **90 degrees clockwise**, causing some of the stones to fall due to gravity. Each stone falls down until it lands on an obstacle, another stone, or the bottom of the box. Gravity **does not** affect the obstacles' positions, and the inertia from the box's rotation **does not** affect the stones' horizontal positions. It is **guaranteed** that each stone in `boxGrid` rests on an obstacle, another stone, or the bottom of the box. Return *an* `n x m` *matrix representing the box after the rotation described above*. ### Examples  ``` Input: boxGrid = [['#','.','#']] Output: [['.'],['#'],['#']] ```  ``` Input: boxGrid = [['#','.','*','.'],['#','#','*','.']] Output: [['#','.'],['#','#'],['*','*'],['.','.']] ```  ``` Input: boxGrid = [['#','#','*','.','*','.'],['#','#','#','*','.','.'],['#','#','#','.','#','.']] Output: [['.','#','#'],['.','#','#'],['#','#','*'],['#','*','.'],['#','.','*'],['#','.','.']] ``` ### Constraints * `m == boxGrid.length` * `n == boxGrid[i].length` * `1 <= m, n <= 500` * `boxGrid[i][j]` is either `'#'`, `'*'`, or `'.'`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotating_the_box/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotating_the_box/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(m * n) for the result (O(n) auxiliary) def rotate_the_box(self, box_grid: list[list[str]]) -> list[list[str]]: m, n = len(box_grid), len(box_grid[0]) def settle(row: list[str]) -> list[str]: out = ["."] * n write = n - 1 for i in range(n - 1, -1, -1): cell = row[i] if cell == "*": out[i] = "*" write = i - 1 elif cell == "#": out[write] = "#" write -= 1 return out settled = [settle(row) for row in box_grid] return [[settled[m - 1 - j][i] for j in range(m)] for i in range(n)] ``` ## Complexity | Time | Space | | --------- | ----------------------------------------- | | O(m \* n) | O(m \* n) for the result (O(n) auxiliary) | ## Tags [NeetCode All](/catalog/neetcode). # Rotting Oranges Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/rotting-oranges Tested Python solution for LeetCode 994 with 11 pytest cases. Generate a practice environment with lcpy. LeetCode 994, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/rotting-oranges/description/). Generate this problem as a practice environment: tested reference solution, 11 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 994 # by problem number lcpy gen -s rotting_oranges # by problem name ``` ## Problem You are given an `m x n` `grid` where each cell can have one of three values: * `0` representing an empty cell, * `1` representing a fresh orange, or * `2` representing a rotten orange. Every minute, any fresh orange that is **4-directionally adjacent** to a rotten orange becomes rotten. Return *the minimum number of minutes that must elapse until no cell has a fresh orange*. If *this is impossible, return* `-1`. ### Examples  ``` Input: grid = [[2,1,1],[1,1,0],[0,1,1]] Output: 4 ``` ``` Input: grid = [[2,1,1],[0,1,1],[1,0,1]] Output: -1 ``` **Explanation:** The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally. ``` Input: grid = [[0,2]] Output: 0 ``` **Explanation:** Since there are already no fresh oranges at minute 0, the answer is just 0. ### Constraints * `m == grid.length` * `n == grid[i].length` * `1 <= m, n <= 10` * `grid[i][j]` is `0`, `1`, or `2`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotting_oranges/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/rotting_oranges/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(m*n) # Space: O(m*n) def oranges_rotting(self, grid: list[list[int]]) -> int: EMPTY, FRESH, ROTTEN = 0, 1, 2 # noqa: N806 _ = EMPTY m, n = len(grid), len(grid[0]) queue: deque[tuple[int, int]] = deque() fresh = 0 # Find all rotten oranges and count fresh ones for i in range(m): for j in range(n): if grid[i][j] == ROTTEN: queue.append((i, j)) elif grid[i][j] == FRESH: fresh += 1 if fresh == 0: return 0 minutes = 0 directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] while queue: size = len(queue) for _ in range(size): x, y = queue.popleft() for dx, dy in directions: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == FRESH: grid[nx][ny] = ROTTEN fresh -= 1 queue.append((nx, ny)) if queue: minutes += 1 return minutes if fresh == 0 else -1 ``` ## Complexity | Time | Space | | ------- | ------- | | O(m\*n) | O(m\*n) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Russian Doll Envelopes Python Solution Source: https://leetcode-py.wisl.dev/problems/russian-doll-envelopes Tested Python solution for LeetCode 354 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 354, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Sorting](/catalog/topics/sorting), Longest Increasing Subsequence. [View on LeetCode](https://leetcode.com/problems/russian-doll-envelopes/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 354 # by problem number lcpy gen -s russian_doll_envelopes # by problem name ``` ## Problem You are given a 2D array of integers `envelopes` where `envelopes[i] = [wi, hi]` represents the width and the height of an envelope. One envelope can fit into another if and only if both the width and height of one envelope are greater than the other envelope's width and height. Return *the maximum number of envelopes you can Russian doll (i.e., put one inside the other)*. **Note:** You cannot rotate an envelope. ### Examples ``` Input: envelopes = [[5,4],[6,4],[6,7],[2,3]] Output: 3 Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]). ``` ``` Input: envelopes = [[1,1],[1,1],[1,1]] Output: 1 ``` ### Constraints * 1 \<= envelopes.length \<= 10\5\ * `envelopes[i].length == 2` * 1 \<= w\i\, h\i\ \<= 10\5\ ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/russian_doll_envelopes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/russian_doll_envelopes/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from bisect import bisect_left class Solution: # Sort widths ascending (heights descending within equal widths), then the # answer is the longest strictly increasing subsequence of heights: patience # sorting with bisect_left keeps equal heights from chaining. # Time: O(n log n) # Space: O(n) def max_envelopes(self, envelopes: list[list[int]]) -> int: tails: list[int] = [] for _, height in sorted(envelopes, key=lambda e: (e[0], -e[1])): index = bisect_left(tails, height) if index == len(tails): tails.append(height) else: tails[index] = height return len(tails) ``` ## Complexity | Time | Space | | ---------- | ----- | | O(n log n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Same Tree Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/same-tree Tested Python solution for LeetCode 100 with 11 pytest cases. Generate a practice environment with lcpy. LeetCode 100, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/same-tree/description/). Generate this problem as a practice environment: tested reference solution, 11 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 100 # by problem number lcpy gen -s same_tree # by problem name ``` ## Problem Given the roots of two binary trees `p` and `q`, write a function to check if they are the same or not. Two binary trees are considered the same if they are structurally identical, and the nodes have the same value. ### Examples  ``` Input: p = [1,2,3], q = [1,2,3] Output: true ```  ``` Input: p = [1,2], q = [1,null,2] Output: false ```  ``` Input: p = [1,2,1], q = [1,1,2] Output: false ``` ### Constraints * The number of nodes in both trees is in the range \[0, 100]. * -10^4 \<= Node.val \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/same_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/same_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(min(m, n)) where m and n are the number of nodes in the two trees # Space: O(min(m, n)) for the recursion stack def is_same_tree(self, p: TreeNode[int] | None, q: TreeNode[int] | None) -> bool: # Base case: both nodes are None if p is None and q is None: return True # Base case: one node is None, the other is not if p is None or q is None: return False # Check if current nodes have the same value if p.val != q.val: return False # Recursively check left and right subtrees return self.is_same_tree(p.left, q.left) and self.is_same_tree(p.right, q.right) ``` ## Complexity | Time | Space | | ------------------------------------------------------------------- | ------------------------------------ | | O(min(m, n)) where m and n are the number of nodes in the two trees | O(min(m, n)) for the recursion stack | ## Tags [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Satisfiability of Equality Equations Source: https://leetcode-py.wisl.dev/problems/satisfiability-of-equality-equations Tested Python solution for LeetCode 990 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 990, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Union-Find](/catalog/topics/union-find), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/satisfiability-of-equality-equations/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 990 # by problem number lcpy gen -s satisfiability_of_equality_equations # by problem name ``` ## Problem You are given an array of strings `equations` that represent relationships between variables where each string `equations[i]` is of length `4` and takes one of two different forms: `xi==yi` or `xi!=yi`. Here, `xi` and `yi` are lowercase letters (not necessarily different) that represent one-letter variable names. Return `true` if it is possible to assign integers to variable names so as to satisfy all the given equations, or `false` otherwise. ### Examples ``` Input: equations = ["a==b","b!=a"] Output: false Explanation: If we assign say, a = 1 and b = 1, then the first equation is satisfied, but not the second. There is no way to assign the variables to satisfy both equations. ``` ``` Input: equations = ["b==a","a==b"] Output: true Explanation: We could assign a = 1 and b = 1 to satisfy both equations. ``` ### Constraints * 1 \<= equations.length \<= 500 * equations\[i].length == 4 * equations\[i]\[0] is a lowercase letter. * equations\[i]\[1] is either '=' or '!'. * equations\[i]\[2] is '='. * equations\[i]\[3] is a lowercase letter. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/satisfiability_of_equality_equations/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/satisfiability_of_equality_equations/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n * alpha(26)) # Space: O(26) def equations_possible(self, equations: list[str]) -> bool: parent: list[int] = list(range(26)) def find(x: int) -> int: while parent[x] != x: parent[x] = parent[parent[x]] x = parent[x] return x def union(a: int, b: int) -> None: root_a, root_b = find(a), find(b) if root_a != root_b: parent[root_a] = root_b for equation in equations: if equation[1] == "=": union(ord(equation[0]) - ord("a"), ord(equation[3]) - ord("a")) for equation in equations: if equation[1] == "!" and find(ord(equation[0]) - ord("a")) == find( ord(equation[3]) - ord("a") ): return False return True ``` ## Complexity | Time | Space | | ----------------- | ----- | | O(n \* alpha(26)) | O(26) | ## Tags # Score After Flipping Matrix Python Solution Source: https://leetcode-py.wisl.dev/problems/score-after-flipping-matrix Tested Python solution for LeetCode 861 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 861, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Bit Manipulation](/catalog/topics/bit-manipulation), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/score-after-flipping-matrix/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 861 # by problem number lcpy gen -s score_after_flipping_matrix # by problem name ``` ## Problem You are given an `m x n` binary matrix `grid`. A move consists of choosing any row or column and toggling each value in that row or column (i.e., changing all `0`'s to `1`'s, and all `1`'s to `0`'s). Every row of the matrix is interpreted as a binary number, and the score of the matrix is the sum of these numbers. Return *the highest possible score after making any number of moves (including zero moves)*. ### Examples ``` Input: grid = [[0,0,1,1],[1,0,1,0],[1,1,0,0]] Output: 39 Explanation: 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39 ``` ``` Input: grid = [[0]] Output: 1 ``` ### Constraints * m == grid.length * n == grid\[i].length * 1 \<= m, n \<= 20 * grid\[i]\[j] is either 0 or 1. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/score_after_flipping_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/score_after_flipping_matrix/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(1) def matrix_score(self, grid: list[list[int]]) -> int: m, n = len(grid), len(grid[0]) score = 0 for j in range(n): # After the optimal row flip, a row's bit at j is 1 exactly when # grid[i][j] == grid[i][0] (the leading bit is always set to 1) ones = sum(1 for row in grid if row[j] == row[0]) score += max(ones, m - ones) * (1 << (n - 1 - j)) return score ``` ## Complexity | Time | Space | | --------- | ----- | | O(m \* n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Score of a String Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/score-of-a-string Tested Python solution for LeetCode 3110 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 3110, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/score-of-a-string/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 3110 # by problem number lcpy gen -s score_of_a_string # by problem name ``` ## Problem You are given a string `s`. The **score** of a string is defined as the sum of the absolute difference between the **ASCII** values of adjacent characters. Return the **score** of `s`. ### Examples ``` Input: s = "hello" Output: 13 Explanation: The ASCII values of the characters in `s` are: `'h' = 104`, `'e' = 101`, `'l' = 108`, `'o' = 111`. So, the score of `s` would be `|104 - 101| + |101 - 108| + |108 - 108| + |108 - 111| = 3 + 7 + 0 + 3 = 13`. ``` ``` Input: s = "zaz" Output: 50 Explanation: The ASCII values of the characters in `s` are: `'z' = 122`, `'a' = 97`. So, the score of `s` would be `|122 - 97| + |97 - 122| = 25 + 25 = 50`. ``` ### Constraints * 2 \<= s.length \<= 100 * `s` consists only of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/score_of_a_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/score_of_a_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def score_of_string(self, s: str) -> int: return sum(abs(ord(s[i]) - ord(s[i + 1])) for i in range(len(s) - 1)) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Score of Parentheses Python Solution Source: https://leetcode-py.wisl.dev/problems/score-of-parentheses Tested Python solution for LeetCode 856 with 23 pytest cases. Generate a practice environment with lcpy. LeetCode 856, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), Bracket Sequences. [View on LeetCode](https://leetcode.com/problems/score-of-parentheses/description/). Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 856 # by problem number lcpy gen -s score_of_parentheses # by problem name ``` ## Problem Given a balanced parentheses string `s`, return *the **score** of the string*. The **score** of a balanced parentheses string is based on the following rule: * `"()"` has score `1`. * `AB` has score `A + B`, where `A` and `B` are balanced parentheses strings. * `(A)` has score `2 * A`, where `A` is a balanced parentheses string. ### Examples ``` Input: s = "()" Output: 1 ``` ``` Input: s = "(())" Output: 2 ``` ``` Input: s = "()()" Output: 2 ``` ### Constraints * 2 \<= s.length \<= 50 * s consists of only `'('` and `')'`. * s is a balanced parentheses string. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/score_of_parentheses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/score_of_parentheses/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def score_of_parentheses(self, s: str) -> int: stack = [0] for char in s: if char == "(": stack.append(0) else: inner = stack.pop() stack[-1] += max(2 * inner, 1) return stack[0] ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags # Scramble String Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/scramble-string Tested Python solution for LeetCode 87 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 87, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/scramble-string/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 87 # by problem number lcpy gen -s scramble_string # by problem name ``` ## Problem We can scramble a string s to get a string t using the following algorithm: 1. If the length of the string is 1, stop. 2. If the length of the string is > 1, do the following: 1. Split the string into two non-empty substrings at a random index, i.e., if the string is `s`, divide it to `x` and `y` where `s = x + y`. 2. Randomly decide to swap the two substrings or to keep them in the same order. i.e., after this step, `s` may become `s = x + y` or `s = y + x`. 3. Apply step 1 recursively on each of the two substrings `x` and `y`. Given two strings `s1` and `s2` of **the same length**, return `true` if `s2` is a scrambled string of `s1`, otherwise, return `false`. ### Examples ``` Input: s1 = "great", s2 = "rgeat" Output: true ``` **Explanation:** One possible scenario applied on `s1` is: `"great" --> "gr/eat"` // divide at random index. `"gr/eat" --> "gr/eat"` // random decision is not to swap the two substrings and keep them in order. `"gr/eat" --> "g/r / e/at"` // apply the same algorithm recursively on both substrings. divide at random index each of them. `"g/r / e/at" --> "r/g / e/at"` // random decision was to swap the first substring and to keep the second substring in the same order. `"r/g / e/at" --> "r/g / e/ a/t"` // again apply the algorithm recursively, divide "at" to "a/t". `"r/g / e/ a/t" --> "r/g / e/ a/t"` // random decision is to keep both substrings in the same order. The algorithm stops now, and the result string is `"rgeat"` which is `s2`. As one possible scenario led `s1` to be scrambled to `s2`, we return `true`. ``` Input: s1 = "abcde", s2 = "caebd" Output: false ``` ``` Input: s1 = "a", s2 = "a" Output: true ``` ### Constraints * s1.length == s2.length * 1 \<= s1.length \<= 30 * s1 and s2 consist of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/scramble_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/scramble_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^4) substring pairs times O(n) split points, memoized # Space: O(n^2) memo entries over substring pairs def is_scramble(self, s1: str, s2: str) -> bool: if len(s1) != len(s2): return False memo: dict[tuple[str, str], bool] = {} return self.solve(s1, s2, memo) def solve(self, s1: str, s2: str, memo: dict[tuple[str, str], bool]) -> bool: if s1 == s2: return True if sorted(s1) != sorted(s2): return False key = (s1, s2) cached = memo.get(key) if cached is not None: return cached n = len(s1) result = False for i in range(1, n): if self.solve(s1[:i], s2[:i], memo) and self.solve(s1[i:], s2[i:], memo): result = True break if self.solve(s1[:i], s2[n - i :], memo) and self.solve(s1[i:], s2[: n - i], memo): result = True break memo[key] = result return result ``` ## Complexity | Time | Space | | -------------------------------------------------------- | ---------------------------------------- | | O(n^4) substring pairs times O(n) split points, memoized | O(n^2) memo entries over substring pairs | ## Tags # Search a 2D Matrix Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/search-a-2d-matrix Tested Python solution for LeetCode 74 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 74, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/search-a-2d-matrix/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 74 # by problem number lcpy gen -s search_a_2d_matrix # by problem name ``` ## Problem You are given an `m x n` integer matrix `matrix` with the following two properties: * Each row is sorted in non-decreasing order. * The first integer of each row is greater than the last integer of the previous row. Given an integer `target`, return `true` *if* `target` *is in* `matrix` *or* `false` *otherwise*. You must write a solution in `O(log(m * n))` time complexity. ### Examples  ``` Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 Output: true ```  ``` Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 Output: false ``` ### Constraints * m == matrix.length * n == matrix\[i].length * 1 \<= m, n \<= 100 * -10^4 \<= matrix\[i]\[j], target \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_a_2d_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_a_2d_matrix/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log(m * n)) # Space: O(1) def search_matrix(self, matrix: list[list[int]], target: int) -> bool: rows, cols = len(matrix), len(matrix[0]) lo, hi = 0, rows * cols - 1 while lo <= hi: mid = (lo + hi) // 2 value = matrix[mid // cols][mid % cols] if value == target: return True if value < target: lo = mid + 1 else: hi = mid - 1 return False ``` ## Complexity | Time | Space | | -------------- | ----- | | O(log(m \* n)) | O(1) | ## Tags [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Search a 2D Matrix II Python Solution Source: https://leetcode-py.wisl.dev/problems/search-a-2d-matrix-ii Tested Python solution for LeetCode 240 with 25 pytest cases. Generate a practice environment with lcpy. LeetCode 240, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/search-a-2d-matrix-ii/description/). Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 240 # by problem number lcpy gen -s search_a_2d_matrix_ii # by problem name ``` ## Problem Write an efficient algorithm that searches for a value `target` in an `m x n` integer matrix `matrix`. This matrix has the following properties: * Integers in each row are sorted in ascending from left to right. * Integers in each column are sorted in ascending from top to bottom. ### Examples  ``` Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5 Output: true ```  ``` Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20 Output: false ``` ### Constraints * m == matrix.length * n == matrix\[i].length * 1 \<= n, m \<= 300 * -10^9 \<= matrix\[i]\[j] \<= 10^9 * All the integers in each row are sorted in ascending order. * All the integers in each column are sorted in ascending order. * -10^9 \<= target \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_a_2d_matrix_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_a_2d_matrix_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m + n) # Space: O(1) def search_matrix(self, matrix: list[list[int]], target: int) -> bool: row, col = 0, len(matrix[0]) - 1 while row < len(matrix) and col >= 0: val = matrix[row][col] if val == target: return True if val > target: col -= 1 else: row += 1 return False ``` ## Complexity | Time | Space | | -------- | ----- | | O(m + n) | O(1) | ## Tags # Search in a Binary Search Tree Python Solution Source: https://leetcode-py.wisl.dev/problems/search-in-a-binary-search-tree Tested Python solution for LeetCode 700 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 700, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/search-in-a-binary-search-tree/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 700 # by problem number lcpy gen -s search_in_a_binary_search_tree # by problem name ``` ## Problem You are given the `root` of a binary search tree (BST) and an integer `val`. Find the node in the BST that the node's value equals `val` and return the subtree rooted with that node. If such a node does not exist, return `null`. ### Examples  ``` Input: root = [4,2,7,1,3], val = 2 Output: [2,1,3] ```  ``` Input: root = [4,2,7,1,3], val = 5 Output: [] ``` ### Constraints * The number of nodes in the tree is in the range \[1, 5000]. * 1 \<= Node.val \<= 10^7 * root is a binary search tree. * 1 \<= val \<= 10^7 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_a_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_a_binary_search_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import TreeNode class Solution: # Time: O(h) where h is the tree height # Space: O(1) def search_bst(self, root: TreeNode[int] | None, val: int) -> TreeNode[int] | None: node = root while node is not None: if val == node.val: return node node = node.left if val < node.val else node.right return None ``` ## Complexity | Time | Space | | ------------------------------- | ----- | | O(h) where h is the tree height | O(1) | ## Tags # Search in a Sorted Array of Unknown Size Source: https://leetcode-py.wisl.dev/problems/search-in-a-sorted-array-of-unknown-size Tested Python solution for LeetCode 702 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 702, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/search-in-a-sorted-array-of-unknown-size/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 702 # by problem number lcpy gen -s search_in_a_sorted_array_of_unknown_size # by problem name ``` ## Problem This is an \\interactive problem\\. You have a sorted array of \unique\ elements and an \unknown size\. You do not have an access to the array but you can use the \ArrayReader\ interface to access it. You can call \ArrayReader.get(i)\ that:
\i\th\\ index (\0-indexed\) of the secret array (i.e., \secret\[i]\), or\2\31\ - 1\ if the \i\ is out of the boundary of the array.\target\.
Return the index \k\ of the hidden array where \secret\[k] == target\ or return \-1\ otherwise.
You must write an algorithm with \O(log n)\ runtime complexity.
### Examples
```
Input: secret = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in secret and its index is 4.
```
```
Input: secret = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: 2 does not exist in secret so return -1.
```
### Constraints
* `1 <= secret.length <= 10^4`
* `-10^4 <= secret[i], target <= 10^4`
* All the integers of `secret` are \unique\.
* `secret` is sorted in a strictly increasing order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_a_sorted_array_of_unknown_size/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_a_sorted_array_of_unknown_size/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class ArrayReader:
# Test-harness API: backs get() with the hidden sorted array
def __init__(self, secret: list[int]) -> None:
self.secret = secret
def get(self, index: int) -> int:
if 0 <= index < len(self.secret):
return self.secret[index]
return 2147483647
class Solution:
# Time: O(log M), M = index of the target (bounds doubling then binary search)
# Space: O(1)
def search(self, reader: ArrayReader, target: int) -> int:
# Grow the upper bound exponentially until get(right) >= target;
# the out-of-bounds sentinel 2^31 - 1 is >= any valid target, so this
# always terminates. The target, if present, lies in [right // 2, right].
right = 1
while reader.get(right) < target:
right <<= 1
left = right >> 1
while left < right:
mid = (left + right) >> 1
if reader.get(mid) >= target:
right = mid
else:
left = mid + 1
return left if reader.get(left) == target else -1
```
## Complexity
| Time | Space |
| ---------------------------------------------------------------------- | ----- |
| O(log M), M = index of the target (bounds doubling then binary search) | O(1) |
## Tags
# Search in Rotated Sorted Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/search-in-rotated-sorted-array
Tested Python solution for LeetCode 33 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 33, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/search-in-rotated-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 33 # by problem number
lcpy gen -s search_in_rotated_sorted_array # by problem name
```
## Problem
There is an integer array `nums` sorted in ascending order (with **distinct** values).
Prior to being passed to your function, `nums` is **possibly left rotated** at an unknown index `k` (`1 <= k < nums.length`) such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,5,6,7]` might be left rotated by 3 indices and become `[4,5,6,7,0,1,2]`.
Given the array `nums` **after** the possible rotation and an integer `target`, return *the index of* `target` *if it is in* `nums`*, or* `-1` *if it is not in* `nums`.
You must write an algorithm with `O(log n)` runtime complexity.
### Examples
```
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
```
```
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
```
```
Input: nums = [1], target = 0
Output: -1
```
### Constraints
* `1 <= nums.length <= 5000`
* `-10^4 <= nums[i] <= 10^4`
* All values of `nums` are **unique**.
* `nums` is an ascending array that is possibly rotated.
* `-10^4 <= target <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_rotated_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_rotated_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def search(self, nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
# Left half is sorted
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
# Right half is sorted
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Search in Rotated Sorted Array II
Source: https://leetcode-py.wisl.dev/problems/search-in-rotated-sorted-array-ii
Tested Python solution for LeetCode 81 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 81, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 81 # by problem number
lcpy gen -s search_in_rotated_sorted_array_ii # by problem name
```
## Problem
There is an integer array `nums` sorted in non-decreasing order (not necessarily with **distinct** values).
Before being passed to your function, `nums` is **rotated** at an unknown pivot index `k` (`0 <= k < nums.length`) such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]` (**0-indexed**). For example, `[0,1,2,4,4,4,5,6,6,7]` might be rotated at pivot index `5` and become `[4,5,6,6,7,0,1,2,4,4]`.
Given the array `nums` **after** the rotation and an integer `target`, return `true` *if* `target` *is in* `nums`*, or* `false` *if it is not in* `nums`*.*
You must decrease the overall operation steps as much as possible.
### Examples
```
Input: nums = [2,5,6,0,0,1,2], target = 0
Output: true
```
```
Input: nums = [2,5,6,0,0,1,2], target = 3
Output: false
```
### Constraints
* 1 \<= nums.length \<= 5000
* -10^4 \<= nums\[i] \<= 10^4
* `nums` is guaranteed to be rotated at some pivot.
* -10^4 \<= target \<= 10^4
**Follow up:** This problem is similar to [Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/description/), but `nums` may contain **duplicates**. Would this affect the runtime complexity? How and why?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_rotated_sorted_array_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_in_rotated_sorted_array_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) worst case (duplicates collapse bounds), O(log n) average
# Space: O(1)
def search(self, nums: list[int], target: int) -> bool:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return True
# Ambiguous boundary: shrink from both ends when all three equal
if nums[left] == nums[mid] == nums[right]:
left += 1
right -= 1
elif nums[left] <= nums[mid]: # left half sorted
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else: # right half sorted
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return False
```
## Complexity
| Time | Space |
| -------------------------------------------------------------- | ----- |
| O(n) worst case (duplicates collapse bounds), O(log n) average | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Search Insert Position Python Solution
Source: https://leetcode-py.wisl.dev/problems/search-insert-position
Tested Python solution for LeetCode 35 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 35, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/search-insert-position/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 35 # by problem number
lcpy gen -s search_insert_position # by problem name
```
## Problem
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.
You must write an algorithm with `O(log n)` runtime complexity.
### Examples
```
Input: nums = [1,3,5,6], target = 5
Output: 2
```
```
Input: nums = [1,3,5,6], target = 2
Output: 1
```
```
Input: nums = [1,3,5,6], target = 7
Output: 4
```
### Constraints
* `1 <= nums.length <= 10^4`
* `-10^4 <= nums[i] <= 10^4`
* `nums` contains **distinct** values sorted in **ascending** order.
* `-10^4 <= target <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_insert_position/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_insert_position/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log n)
# Space: O(1)
def search_insert(self, nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Search Suggestions System Python Solution
Source: https://leetcode-py.wisl.dev/problems/search-suggestions-system
Tested Python solution for LeetCode 1268 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1268, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Binary Search](/catalog/topics/binary-search), [Trie](/catalog/topics/trie), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/search-suggestions-system/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1268 # by problem number
lcpy gen -s search_suggestions_system # by problem name
```
## Problem
You are given an array of strings products and a string searchWord.
Design a system that suggests at most three product names from products after each character of searchWord is typed. Suggested products should have common prefix with searchWord. If there are more than three products with a common prefix return the three lexicographically minimums products.
Return a list of lists of the suggested products after each character of searchWord is typed.
### Examples
```
Input: products = ["mobile","mouse","moneypot","monitor","mousepad"], searchWord = "mouse"
Output: [["mobile","moneypot","monitor"],["mobile","moneypot","monitor"],["mouse","mousepad"],["mouse","mousepad"],["mouse","mousepad"]]
Explanation: products sorted lexicographically = ["mobile","moneypot","monitor","mouse","mousepad"].
After typing m and mo all products match and we show user ["mobile","moneypot","monitor"].
After typing mou, mous and mouse the system suggests ["mouse","mousepad"].
```
```
Input: products = ["havana"], searchWord = "havana"
Output: [["havana"],["havana"],["havana"],["havana"],["havana"],["havana"]]
Explanation: The only word "havana" will be always suggested while typing the search word.
```
### Constraints
* 1 \<= products.length \<= 1000
* 1 \<= products\[i].length \<= 3000
* 1 \<= sum(products\[i].length) \<= 2 \* 10^4
* All the strings of products are unique.
* products\[i] consists of lowercase English letters.
* 1 \<= searchWord.length \<= 1000
* searchWord consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_suggestions_system/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/search_suggestions_system/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from bisect import bisect_left
class Solution:
def suggested_products(self, products: list[str], search_word: str) -> list[list[str]]:
products = sorted(products)
result: list[list[str]] = []
prefix = ""
for ch in search_word:
prefix += ch
start = bisect_left(products, prefix)
matches = []
for product in products[start : start + 3]:
if not product.startswith(prefix):
break
matches.append(product)
result.append(matches)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Seat Reservation Manager Python Solution
Source: https://leetcode-py.wisl.dev/problems/seat-reservation-manager
Tested Python solution for LeetCode 1845 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1845, [Medium](/catalog/medium). Topics: [Design](/catalog/topics/design), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/seat-reservation-manager/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1845 # by problem number
lcpy gen -s seat_reservation_manager # by problem name
```
## Problem
Design a system that manages the reservation state of `n` seats that are numbered from `1` to `n`.
Implement the `SeatManager` class:
* `SeatManager(int n)` Initializes a `SeatManager` object that will manage `n` seats numbered from `1` to `n`. All seats are initially available.
* `int reserve()` Fetches the **smallest-numbered** unreserved seat, reserves it, and returns its number.
* `void unreserve(int seatNumber)` Unreserves the seat with the given `seatNumber`.
### Examples
```
Input
["SeatManager", "reserve", "reserve", "unreserve", "reserve", "reserve", "reserve", "reserve", "unreserve"]
[[5], [], [], [2], [], [], [], [], [5]]
Output
[null, 1, 2, null, 2, 3, 4, 5, null]
Explanation
SeatManager seatManager = new SeatManager(5); // Initializes a SeatManager with 5 seats.
seatManager.reserve(); // All seats are available, so return the lowest numbered seat, which is 1.
seatManager.reserve(); // The available seats are [2,3,4,5], so return the lowest of them, which is 2.
seatManager.unreserve(2); // Unreserve seat 2, so now the available seats are [2,3,4,5].
seatManager.reserve(); // The available seats are [2,3,4,5], so return the lowest of them, which is 2.
seatManager.reserve(); // The available seats are [3,4,5], so return the lowest of them, which is 3.
seatManager.reserve(); // The available seats are [4,5], so return the lowest of them, which is 4.
seatManager.reserve(); // The only available seat is seat 5, so return 5.
seatManager.unreserve(5); // Unreserve seat 5, so now the available seats are [5].
```
### Constraints
* `1 <= n <= 10^5`
* `1 <= seatNumber <= n`
* For each call to `reserve`, it is guaranteed that there will be at least one unreserved seat.
* For each call to `unreserve`, it is guaranteed that `seatNumber` will be reserved.
* At most `10^5` calls in total will be made to `reserve` and `unreserve`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/seat_reservation_manager/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/seat_reservation_manager/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class SeatManager:
# Time: O(1) init, O(log n) reserve, O(log n) unreserve
# Space: O(n)
def __init__(self, n: int) -> None:
self.next_seat = 1
self.returned: list[int] = []
def reserve(self) -> int:
if self.returned and self.returned[0] < self.next_seat:
return heapq.heappop(self.returned)
seat = self.next_seat
self.next_seat += 1
return seat
def unreserve(self, seat_number: int) -> None:
heapq.heappush(self.returned, seat_number)
```
## Complexity
| Time | Space |
| ----------------------------------------------- | ----- |
| O(1) init, O(log n) reserve, O(log n) unreserve | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Second Minimum Node In a Binary Tree
Source: https://leetcode-py.wisl.dev/problems/second-minimum-node-in-a-binary-tree
Tested Python solution for LeetCode 671 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 671, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 671 # by problem number
lcpy gen -s second_minimum_node_in_a_binary_tree # by problem name
```
## Problem
Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this tree has exactly `two` or `zero` sub-node. If the node has two sub-nodes, then this node's value is the smaller value among its two sub-nodes. More formally, the property `root.val = min(root.left.val, root.right.val)` always holds.
Given such a binary tree, you need to output the **second minimum** value in the set made of all the nodes' value in the whole tree.
If no such second minimum value exists, output -1 instead.
### Examples

```
Input: root = [2,2,5,null,null,5,7]
Output: 5
Explanation: The smallest value is 2, the second smallest value is 5.
```

```
Input: root = [2,2,2]
Output: -1
Explanation: The smallest value is 2, but there isn't any second smallest value.
```
### Constraints
* The number of nodes in the tree is in the range \[1, 25]
* 1 \<= Node.val \<= 2^31 - 1
* root.val == min(root.left.val, root.right.val) for each internal node of the tree
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/second_minimum_node_in_a_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/second_minimum_node_in_a_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def find_second_minimum_value(self, root: TreeNode[int] | None) -> int:
if root is None:
return -1
return self._dfs(root, root.val)
def _dfs(self, node: TreeNode[int] | None, smallest: int) -> int:
if node is None:
return -1
if node.val > smallest:
return node.val
left = self._dfs(node.left, smallest)
right = self._dfs(node.right, smallest)
if left == -1:
return right
if right == -1:
return left
return min(left, right)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
# Second Minimum Time to Reach Destination
Source: https://leetcode-py.wisl.dev/problems/second-minimum-time-to-reach-destination
Tested Python solution for LeetCode 2045 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 2045, [Hard](/catalog/hard). Topics: [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Shortest Path](/catalog/topics/shortest-path). [View on LeetCode](https://leetcode.com/problems/second-minimum-time-to-reach-destination/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2045 # by problem number
lcpy gen -s second_minimum_time_to_reach_destination # by problem name
```
## Problem
A city is represented as a **bi-directional connected** graph with `n` vertices where each vertex is labeled from `1` to `n` (**inclusive**). The edges in the graph are represented as a 2D integer array `edges`, where each `edges[i] = [ui, vi]` denotes a bi-directional edge between vertex `ui` and vertex `vi`. Every vertex pair is connected by **at most one** edge, and no vertex has an edge to itself. The time taken to traverse any edge is `time` minutes.
Each vertex has a traffic signal which changes its color from **green** to **red** and vice versa every `change` minutes. All signals change **at the same time**. You can enter a vertex at **any time**, but can leave a vertex **only when the signal is green**. You **cannot wait** at a vertex if the signal is **green**.
The **second minimum value** is defined as the smallest value **strictly larger** than the minimum value.
* For example the second minimum value of `[2, 3, 4]` is `3`, and the second minimum value of `[2, 2, 4]` is `4`.
Given `n`, `edges`, `time`, and `change`, return *the **second minimum time** it will take to go from vertex* `1` *to vertex* `n`.
**Notes:**
* You can go through any vertex **any** number of times, **including** `1` and `n`.
* You can assume that when the journey **starts**, all signals have just turned **green**.
### Examples
 
```
Input: n = 5, edges = [[1,2],[1,3],[1,4],[3,4],[4,5]], time = 3, change = 5
Output: 13
```

```
Input: n = 2, edges = [[1,2]], time = 3, change = 2
Output: 11
```
**Explanation:** The minimum time path is `1 -> 2` with time = 3 minutes. The second minimum time path is `1 -> 2 -> 1 -> 2` with time = 11 minutes.
### Constraints
* `2 <= n <= 104`
* `n - 1 <= edges.length <= min(2 * 104, n * (n - 1) / 2)`
* `edges[i].length == 2`
* `1 <= ui, vi <= n`
* `ui != vi`
* There are no duplicate edges.
* Each vertex can be reached directly or indirectly from every other vertex.
* `1 <= time, change <= 103`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/second_minimum_time_to_reach_destination/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/second_minimum_time_to_reach_destination/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n + m) BFS plus O(second_path_length) for the signal simulation
# Space: O(n + m)
def second_minimum(self, n: int, edges: list[list[int]], time: int, change: int) -> int:
adj: list[list[int]] = [[] for _ in range(n + 1)]
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
# two smallest distinct arrival edge-counts per vertex (BFS order)
dists: list[list[int]] = [[] for _ in range(n + 1)]
dists[1].append(0)
queue: deque[tuple[int, int]] = deque([(1, 0)])
while queue:
node, steps = queue.popleft()
for nb in adj[node]:
nxt = steps + 1
if len(dists[nb]) < 2 and nxt not in dists[nb]:
dists[nb].append(nxt)
queue.append((nb, nxt))
elapsed = 0
for _ in range(dists[n][1]):
if (elapsed // change) % 2 == 1:
elapsed = (elapsed // change + 1) * change
elapsed += time
return elapsed
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------- | -------- |
| O(n + m) BFS plus O(second\_path\_length) for the signal simulation | O(n + m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Self Crossing Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/self-crossing
Tested Python solution for LeetCode 335 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 335, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry). [View on LeetCode](https://leetcode.com/problems/self-crossing/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 335 # by problem number
lcpy gen -s self_crossing # by problem name
```
## Problem
You are given an array of integers `distance`.
You start at the point `(0, 0)` on an **X-Y plane,** and you move `distance[0]` meters to the north, then `distance[1]` meters to the west, `distance[2]` meters to the south, `distance[3]` meters to the east, and so on. In other words, after each move, your direction changes counter-clockwise.
Return `true` if your path crosses itself or `false` if it does not.
### Examples

```
Input: distance = [2,1,1,2]
Output: true
Explanation: The path crosses itself at the point (0, 1).
```

```
Input: distance = [1,2,3,4]
Output: false
Explanation: The path does not cross itself at any point.
```

```
Input: distance = [1,1,1,2,1]
Output: true
Explanation: The path crosses itself at the point (0, 0).
```
### Constraints
* 1 \<= distance.length \<= 10^5
* 1 \<= distance\[i] \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/self_crossing/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/self_crossing/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def is_self_crossing(self, distance: list[int]) -> bool:
d = distance
for i in range(3, len(d)):
# Fourth segment crosses the first.
if d[i] >= d[i - 2] and d[i - 3] >= d[i - 1]:
return True
# Fifth segment touches the first.
if i >= 4 and d[i - 1] == d[i - 3] and d[i] + d[i - 4] >= d[i - 2]:
return True
# Sixth segment crosses the first after an expanding spiral contracts.
if (
i >= 5
and d[i - 2] > d[i - 4]
and d[i - 3] > d[i - 1]
and d[i - 1] + d[i - 5] >= d[i - 3]
and d[i] + d[i - 4] >= d[i - 2]
):
return True
return False
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Self Dividing Numbers Python Solution
Source: https://leetcode-py.wisl.dev/problems/self-dividing-numbers
Tested Python solution for LeetCode 728 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 728, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/self-dividing-numbers/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 728 # by problem number
lcpy gen -s self_dividing_numbers # by problem name
```
## Problem
A **self-dividing number** is a number that is divisible by every digit it contains.
* For example, `128` is **a self-dividing number** because `128 % 1 == 0`, `128 % 2 == 0`, and `128 % 8 == 0`.
A **self-dividing number** is not allowed to contain the digit zero.
Given two integers `left` and `right`, return *a list of all the **self-dividing numbers** in the range* `[left, right]` *(both **inclusive**)*.
### Examples
```
Input: left = 1, right = 22
Output: [1,2,3,4,5,6,7,8,9,11,12,15,22]
```
```
Input: left = 47, right = 85
Output: [48,55,66,77]
```
### Constraints
* `1 <= left <= right <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/self_dividing_numbers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/self_dividing_numbers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O((right - left + 1) * log10(right))
# Space: O(1) extra (output excluded)
def self_dividing_numbers(self, left: int, right: int) -> list[int]:
def is_self_dividing(num: int) -> bool:
remaining = num
while remaining > 0:
digit = remaining % 10
if digit == 0 or num % digit != 0:
return False
remaining //= 10
return True
return [num for num in range(left, right + 1) if is_self_dividing(num)]
```
## Complexity
| Time | Space |
| ------------------------------------- | ---------------------------- |
| O((right - left + 1) \* log10(right)) | O(1) extra (output excluded) |
## Tags
# Sentence Screen Fitting Python Solution
Source: https://leetcode-py.wisl.dev/problems/sentence-screen-fitting
Tested Python solution for LeetCode 418 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 418, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/sentence-screen-fitting/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 418 # by problem number
lcpy gen -s sentence_screen_fitting # by problem name
```
## Problem
Given a `rows x cols` screen and a `sentence` represented as a list of strings, return *the number of times the given sentence can be fitted on the screen*.
The order of words in the sentence must remain unchanged, and a word cannot be split into two lines. A single space must separate two consecutive words in a line.
### Examples
```
Input: sentence = ["hello","world"], rows = 2, cols = 8
Output: 1
Explanation:
hello---
world---
The character '-' signifies an empty space on the screen.
```
```
Input: sentence = ["a", "bcd", "e"], rows = 3, cols = 6
Output: 2
Explanation:
a-bcd-
e-a---
bcd-e-
The character '-' signifies an empty space on the screen.
```
```
Input: sentence = ["i","had","apple","pie"], rows = 4, cols = 5
Output: 1
Explanation:
i-had
apple
pie-i
had--
The character '-' signifies an empty space on the screen.
```
### Constraints
* `1 <= sentence.length`
* `1 <= rows, cols <= 4 * 10^4`
* `1 <= sentence[i].length <= 10`
* `sentence[i]` consists of only lower-case English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_screen_fitting/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_screen_fitting/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(rows + total_sentence_length)
# Space: O(total_sentence_length) for the joined sentence string
def words_typing(self, sentence: list[str], rows: int, cols: int) -> int:
s = " ".join(sentence) + " "
n = len(s)
total = 0
for _ in range(rows):
total += cols
if s[total % n] == " ":
total += 1
else:
while total > 0 and s[(total - 1) % n] != " ":
total -= 1
return total // n
```
## Complexity
| Time | Space |
| --------------------------------- | --------------------------------------------------------- |
| O(rows + total\_sentence\_length) | O(total\_sentence\_length) for the joined sentence string |
## Tags
[NeetCode All](/catalog/neetcode).
# Sentence Similarity Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/sentence-similarity
Tested Python solution for LeetCode 734 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 734, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/sentence-similarity/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 734 # by problem number
lcpy gen -s sentence_similarity # by problem name
```
## Problem
We can represent a sentence as an array of words, for example, the sentence `"I am happy with leetcode"` can be represented as `arr = ["I","am","happy","with","leetcode"]`.
Given two sentences `sentence1` and `sentence2` each represented as a string array, and given an array of string pairs `similarPairs` where `similarPairs[i] = [xi, yi]` indicates that the two words `xi` and `yi` are similar.
Return `true` if `sentence1` and `sentence2` are similar, or `false` if they are not similar.
Two sentences are similar if:
* They have the **same** length (i.e., the same number of words)
* `sentence1[i]` and `sentence2[i]` are similar.
Notice that a word is always similar to itself, also notice that the similarity relation is not transitive. For example, if the words `a` and `b` are similar, and the words `b` and `c` are similar, `a` and `c` are **not necessarily** similar.
### Examples
```
Input: sentence1 = ["great","acting","skills"], sentence2 = ["fine","drama","talent"], similarPairs = [["great","fine"],["drama","acting"],["skills","talent"]]
Output: true
Explanation: The two sentences have the same length and each word i of sentence1 is also similar to the corresponding word in sentence2.
```
```
Input: sentence1 = ["great"], sentence2 = ["great"], similarPairs = []
Output: true
Explanation: A word is similar to itself.
```
```
Input: sentence1 = ["great"], sentence2 = ["doubleplus","good"], similarPairs = [["great","doubleplus"]]
Output: false
Explanation: As they don't have the same length, we return false.
```
### Constraints
* 1 \<= sentence1.length, sentence2.length \<= 1000
* 1 \<= sentence1\[i].length, sentence2\[i].length \<= 20
* sentence1\[i] and sentence2\[i] consist of English letters.
* 0 \<= similarPairs.length \<= 1000
* similarPairs\[i].length == 2
* 1 \<= xi.length, yi.length \<= 20
* xi and yi consist of lower-case and upper-case English letters.
* All the pairs (xi, yi) are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_similarity/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_similarity/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + p)
# Space: O(p)
def are_sentences_similar(
self, sentence1: list[str], sentence2: list[str], similar_pairs: list[list[str]]
) -> bool:
if len(sentence1) != len(sentence2):
return False
s = {tuple(p) for p in similar_pairs}
return all(
x == y or (x, y) in s or (y, x) in s for x, y in zip(sentence1, sentence2, strict=True)
)
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + p) | O(p) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sentence Similarity II Python Solution
Source: https://leetcode-py.wisl.dev/problems/sentence-similarity-ii
Tested Python solution for LeetCode 737 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 737, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find). [View on LeetCode](https://leetcode.com/problems/sentence-similarity-ii/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 737 # by problem number
lcpy gen -s sentence_similarity_ii # by problem name
```
## Problem
We can represent a sentence as an array of words, for example, the sentence `"I am happy with leetcode"` can be represented as `arr = ["I","am","happy","with","leetcode"]`.
Given two sentences `sentence1` and `sentence2` each represented as a string array, and given an array of string pairs `similarPairs` where `similarPairs[i] = [xi, yi]` indicates that the two words `xi` and `yi` are similar.
Return `true` if `sentence1` and `sentence2` are similar, or `false` if they are not similar.
Two sentences are similar if:
* They have the **same** length (i.e., the same number of words)
* `sentence1[i]` and `sentence2[i]` are similar.
Notice that a word is always similar to itself, also notice that the similarity relation **is transitive**. For example, if the words `a` and `b` are similar, and the words `b` and `c` are similar, then `a` and `c` are similar.
### Examples
```
Input: sentence1 = ["great","acting","skills"], sentence2 = ["fine","drama","talent"], similarPairs = [["great","good"],["fine","good"],["drama","acting"],["skills","talent"]]
Output: true
Explanation: The two sentences have the same length and each word i of sentence1 is also similar to the corresponding word in sentence2.
```
```
Input: sentence1 = ["I","love","leetcode"], sentence2 = ["I","love","onepiece"], similarPairs = [["manga","onepiece"],["platform","anime"],["leetcode","platform"],["anime","manga"]]
Output: true
Explanation: "leetcode" -> "platform" -> "anime" -> "manga" -> "onepiece".
```
```
Input: sentence1 = ["I","love","leetcode"], sentence2 = ["I","love","onepiece"], similarPairs = [["manga","hunterXhunter"],["platform","anime"],["leetcode","platform"],["anime","manga"]]
Output: false
Explanation: "leetcode" is not similar to "onepiece".
```
### Constraints
* 1 \<= sentence1.length, sentence2.length \<= 1000
* 1 \<= sentence1\[i].length, sentence2\[i].length \<= 20
* sentence1\[i] and sentence2\[i] consist of lower-case and upper-case English letters.
* 0 \<= similarPairs.length \<= 2000
* similarPairs\[i].length == 2
* 1 \<= xi.length, yi.length \<= 20
* xi and yi consist of English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_similarity_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_similarity_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O((n + m) * alpha(n)) for n pairs and m words
# Space: O(n)
def are_sentences_similar_two(
self, sentence1: list[str], sentence2: list[str], similar_pairs: list[list[str]]
) -> bool:
if len(sentence1) != len(sentence2):
return False
parent: dict[str, str] = {}
def find(x: str) -> str:
parent.setdefault(x, x)
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
for a, b in similar_pairs:
parent.setdefault(a, a)
parent.setdefault(b, b)
ra, rb = find(a), find(b)
if ra != rb:
parent[ra] = rb
return all(x == y or find(x) == find(y) for x, y in zip(sentence1, sentence2, strict=True))
```
## Complexity
| Time | Space |
| ---------------------------------------------- | ----- |
| O((n + m) \* alpha(n)) for n pairs and m words | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sentence Similarity III Python Solution
Source: https://leetcode-py.wisl.dev/problems/sentence-similarity-iii
Tested Python solution for LeetCode 1813 with 28 pytest cases. Generate a practice environment with lcpy.
LeetCode 1813, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/sentence-similarity-iii/description/).
Generate this problem as a practice environment: tested reference solution, 28 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1813 # by problem number
lcpy gen -s sentence_similarity_iii # by problem name
```
## Problem
You are given two strings `sentence1` and `sentence2`, each representing a **sentence** composed of words. A sentence is a list of **words** that are separated by a **single** space with no leading or trailing spaces. Each word consists of only uppercase and lowercase English characters.
Two sentences `s1` and `s2` are considered **similar** if it is possible to insert an arbitrary sentence (*possibly empty*) inside one of these sentences such that the two sentences become equal. **Note** that the inserted sentence must be separated from existing words by spaces.
For example,
* `s1 = "Hello Jane"` and `s2 = "Hello my name is Jane"` can be made equal by inserting `"my name is"` between `"Hello"` and `"Jane"` in `s1`.
* `s1 = "Frog cool"` and `s2 = "Frogs are cool"` are **not** similar, since although there is a sentence `"s are"` inserted into `s1`, it is not separated from `"Frog"` by a space.
Given two sentences `sentence1` and `sentence2`, return `true` if `sentence1` and `sentence2` are similar. Otherwise, return `false`.
### Examples
```
Input: sentence1 = "My name is Haley", sentence2 = "My Haley"
Output: true
```
sentence2 can be turned to sentence1 by inserting "name is" between "My" and "Haley".
```
Input: sentence1 = "of", sentence2 = "A lot of words"
Output: false
```
No single sentence can be inserted inside one of the sentences to make it equal to the other.
```
Input: sentence1 = "Eating right now", sentence2 = "Eating"
Output: true
```
sentence2 can be turned to sentence1 by inserting "right now" at the end of the sentence.
### Constraints
* 1 \<= sentence1.length, sentence2.length \<= 100
* sentence1 and sentence2 consist of lowercase and uppercase English letters and spaces.
* The words in sentence1 and sentence2 are separated by a single space.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_similarity_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sentence_similarity_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m) where n, m are the sentence lengths
# Space: O(n + m) for the split word lists
def are_sentences_similar(self, sentence1: str, sentence2: str) -> bool:
words1 = sentence1.split()
words2 = sentence2.split()
if len(words1) < len(words2):
words1, words2 = words2, words1
prefix = 0
while prefix < len(words2) and words1[prefix] == words2[prefix]:
prefix += 1
suffix = 0
while (
suffix < len(words2) - prefix
and words1[len(words1) - 1 - suffix] == words2[len(words2) - 1 - suffix]
):
suffix += 1
return prefix + suffix == len(words2)
```
## Complexity
| Time | Space |
| -------------------------------------------- | --------------------------------- |
| O(n + m) where n, m are the sentence lengths | O(n + m) for the split word lists |
## Tags
[NeetCode All](/catalog/neetcode).
# Separate Black and White Balls Python Solution
Source: https://leetcode-py.wisl.dev/problems/separate-black-and-white-balls
Tested Python solution for LeetCode 2938 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 2938, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/separate-black-and-white-balls/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2938 # by problem number
lcpy gen -s separate_black_and_white_balls # by problem name
```
## Problem
There are `n` balls on a table, each ball has a color black or white.
You are given a 0-indexed binary string `s` of length `n`, where `1` and `0` represent black and white balls, respectively.
In each step, you can choose two adjacent balls and swap them.
Return *the minimum number of steps to group all the black balls to the right and all the white balls to the left*.
### Examples
```
Input: s = "101"
Output: 1
Explanation: We can group all the black balls to the right in the following way:
- Swap s[0] and s[1], s = "011".
Initially, 1s are not grouped together, requiring at least 1 step to group them to the right.
```
```
Input: s = "100"
Output: 2
Explanation: We can group all the black balls to the right in the following way:
- Swap s[0] and s[1], s = "010".
- Swap s[1] and s[2], s = "001".
It can be proven that the minimum number of steps needed is 2.
```
```
Input: s = "0111"
Output: 0
Explanation: All the black balls are already grouped to the right.
```
### Constraints
* 1 \<= n == s.length \<= 10^5
* s\[i] is either '0' or '1'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/separate_black_and_white_balls/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/separate_black_and_white_balls/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def minimum_steps(self, s: str) -> int:
steps = 0
ones = 0
for ball in s:
if ball == "1":
ones += 1
else:
steps += ones
return steps
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sequence Reconstruction Python Solution
Source: https://leetcode-py.wisl.dev/problems/sequence-reconstruction
Tested Python solution for LeetCode 444 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 444, [Medium](/catalog/medium). Topics: [Graph](/catalog/topics/graph), [Topological Sort](/catalog/topics/topological-sort), [Array](/catalog/topics/array), Directed Acyclic Graph. [View on LeetCode](https://leetcode.com/problems/sequence-reconstruction/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 444 # by problem number
lcpy gen -s sequence_reconstruction # by problem name
```
## Problem
You are given an integer array `nums` of length `n` where `nums` is a permutation of the integers in the range `[1, n]`. You are also given a 2D integer array `sequences` where `sequences[i]` is a subsequence of `nums`.
Check if `nums` is the shortest possible and the only **supersequence**. The shortest **supersequence** is a sequence **with the shortest length** and has all `sequences[i]` as subsequences. There could be multiple valid **supersequences** for the given array `sequences`.
* For example, for `sequences = [[1,2],[1,3]]`, there are two shortest **supersequences**, `[1,2,3]` and `[1,3,2]`.
* While for `sequences = [[1,2],[1,3],[1,2,3]]`, the only shortest **supersequence** possible is `[1,2,3]`. `[1,2,3,4]` is a possible supersequence but not the shortest.
Return `true` if `nums` is the only shortest **supersequence** for `sequences`, or `false` otherwise.
A **subsequence** is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.
### Examples
```
Input: nums = [1,2,3], sequences = [[1,2],[1,3]]
Output: false
Explanation: There are two possible supersequences: [1,2,3] and [1,3,2]. Since nums is not the only shortest supersequence, we return false.
```
```
Input: nums = [1,2,3], sequences = [[1,2]]
Output: false
Explanation: The shortest possible supersequence is [1,2]. Since nums is not the shortest supersequence, we return false.
```
```
Input: nums = [1,2,3], sequences = [[1,2],[1,3],[2,3]]
Output: true
Explanation: The shortest possible supersequence is [1,2,3]. Since nums is the only shortest supersequence, we return true.
```
### Constraints
* `n == nums.length`
* `1 <= n <= 10^4`
* `nums` is a permutation of all the integers in the range `[1, n]`.
* `1 <= sequences.length <= 10^4`
* `1 <= sequences[i].length <= 10^4`
* `1 <= sum(sequences[i].length) <= 10^5`
* `1 <= sequences[i][j] <= n`
* All the arrays of `sequences` are **unique**.
* `sequences[i]` is a subsequence of `nums`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sequence_reconstruction/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sequence_reconstruction/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(total sequence length)
# Space: O(n)
def sequence_reconstruction(self, nums: list[int], sequences: list[list[int]]) -> bool:
pos = {v: i for i, v in enumerate(nums)}
following: set[tuple[int, int]] = set()
for seq in sequences:
for i in range(len(seq) - 1):
a, b = seq[i], seq[i + 1]
if a not in pos or b not in pos or pos[a] >= pos[b]:
return False
following.add((a, b))
return all((nums[i], nums[i + 1]) in following for i in range(len(nums) - 1))
```
## Complexity
| Time | Space |
| ------------------------ | ----- |
| O(total sequence length) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sequential Digits Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/sequential-digits
Tested Python solution for LeetCode 1291 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1291, [Medium](/catalog/medium). Topics: [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/sequential-digits/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1291 # by problem number
lcpy gen -s sequential_digits # by problem name
```
## Problem
An integer has sequential digits if and only if each digit in the number is one more than the previous digit.
Return a sorted list of all the integers in the range \[low, high] inclusive that have sequential digits.
### Examples
```
Input: low = 100, high = 300
Output: [123,234]
```
```
Input: low = 1000, high = 13000
Output: [1234,2345,3456,4567,5678,6789,12345]
```
### Constraints
* 10 \<= low \<= high \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sequential_digits/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sequential_digits/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def sequential_digits(self, low: int, high: int) -> list[int]:
result: list[int] = []
for length in range(2, 10):
for start in range(1, 11 - length):
num = int("".join(str(start + i) for i in range(length)))
if low <= num <= high:
result.append(num)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Serialize and Deserialize Binary Tree
Source: https://leetcode-py.wisl.dev/problems/serialize-and-deserialize-binary-tree
Tested Python solution for LeetCode 297 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 297, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Design](/catalog/topics/design), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 297 # by problem number
lcpy gen -s serialize_and_deserialize_binary_tree # by problem name
```
## Problem
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
**Clarification:** The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
### Examples

```
Input: root = [1,2,3,null,null,4,5]
Output: [1,2,3,null,null,4,5]
```
```
Input: root = []
Output: []
```
### Constraints
* The number of nodes in the tree is in the range \[0, 10^4].
* -1000 \<= Node.val \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/serialize_and_deserialize_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/serialize_and_deserialize_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Codec:
# Preorder with Null Markers
# Time: O(n)
# Space: O(n)
def __init__(self) -> None:
pass
# Time: O(n)
# Space: O(n)
def serialize(self, root: TreeNode[int] | None) -> str:
vals = []
def dfs(node: TreeNode[int] | None):
if not node:
vals.append("#")
return
vals.append(str(node.val))
dfs(node.left)
dfs(node.right)
dfs(root)
return ",".join(vals)
# Time: O(n)
# Space: O(n)
def deserialize(self, data: str) -> TreeNode[int] | None:
vals = iter(data.split(","))
def dfs():
val = next(vals)
if val == "#":
return None
node = TreeNode[int](int(val))
node.left = dfs()
node.right = dfs()
return node
return dfs()
# Binary Tree Serialization Techniques
# Example Tree:
# 1
# / \
# 2 3
# / \
# 4 5
# 1. Preorder with Null Markers (This Implementation)
# Visit: root → left → right, mark nulls with '#'
# Result: "1,2,#,#,3,4,#,#,5,#,#"
# Pros: Self-contained, unambiguous, O(n) reconstruction
# Cons: Longer string due to null markers
# 2. Level-order (BFS) with Null Markers
# Visit level by level, mark nulls with '#'
# Result: "1,2,3,#,#,4,5"
# Pros: Simple format like preorder, level-by-level intuitive
# Cons: Still requires queue processing
# 3. Postorder with Null Markers
# Visit: left → right → root
# Result: "#,#,2,#,#,4,#,#,5,3,1"
# Pros: Bottom-up reconstruction
# Cons: Less intuitive than preorder
# 4. Inorder + Preorder (Two Arrays)
# Inorder: [2,1,4,3,5], Preorder: [1,2,3,4,5]
# Pros: Works for any binary tree structure
# Cons: Requires two arrays, only works with unique values
# 5. Parenthetical Preorder
# Same traversal as #1 but with parentheses format: value(left)(right)
# Result: "1(2()())(3(4()())(5()()))"
# Pros: Human readable structure, shows nesting clearly
# Cons: Complex parsing, verbose
# 6. Parenthetical Postorder
# Same traversal as #3 but with parentheses format: (left)(right)value
# Result: "(()()2)((()()4)(()()5)3)1"
# Pros: Bottom-up readable structure
# Cons: Even more complex parsing
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Serialize and Deserialize BST Python Solution
Source: https://leetcode-py.wisl.dev/problems/serialize-and-deserialize-bst
Tested Python solution for LeetCode 449 with 27 pytest cases. Generate a practice environment with lcpy.
LeetCode 449, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Design](/catalog/topics/design), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/serialize-and-deserialize-bst/description/).
Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 449 # by problem number
lcpy gen -s serialize_and_deserialize_bst # by problem name
```
## Problem
Serialization is converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a **binary search tree**. There is no restriction on how your serialization/deserialization algorithm should work. You need to ensure that a binary search tree can be serialized to a string, and this string can be deserialized to the original tree structure.
The encoded string should be as compact as possible.
### Examples
```
Input: root = [2,1,3]
Output: [2,1,3]
```
```
Input: root = []
Output: []
```
### Constraints
* The number of nodes in the tree is in the range \[0, 10^4].
* 0 \<= Node.val \<= 10^4
* The input tree is guaranteed to be a binary search tree.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/serialize_and_deserialize_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/serialize_and_deserialize_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Codec:
# Time: O(n) serialize, O(h) amortized per node for deserialize
# Space: O(n)
def __init__(self) -> None:
pass
def serialize(self, root: TreeNode[int] | None) -> str:
values: list[str] = []
stack: list[TreeNode[int]] = [root] if root is not None else []
while stack:
node = stack.pop()
values.append(str(node.val))
if node.right is not None:
stack.append(node.right)
if node.left is not None:
stack.append(node.left)
return ",".join(values)
def deserialize(self, data: str) -> TreeNode[int] | None:
values = [int(token) for token in data.split(",") if token]
if not values:
return None
root = TreeNode(values[0])
stack: list[TreeNode[int]] = [root]
for value in values[1:]:
node = TreeNode(value)
if value < stack[-1].val:
stack[-1].left = node
else:
parent = stack[-1]
while stack and stack[-1].val < value:
parent = stack.pop()
parent.right = node
stack.append(node)
return root
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | ----- |
| O(n) serialize, O(h) amortized per node for deserialize | O(n) |
## Tags
# Serialize and Deserialize N-ary Tree
Source: https://leetcode-py.wisl.dev/problems/serialize-and-deserialize-n-ary-tree
Tested Python solution for LeetCode 428 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 428, [Hard](/catalog/hard). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/serialize-and-deserialize-n-ary-tree/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 428 # by problem number
lcpy gen -s serialize_and_deserialize_n_ary_tree # by problem name
```
## Problem
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize an N-ary tree. An N-ary tree is a rooted tree in which each node has no more than N children. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that an N-ary tree can be serialized to a string and this string can be deserialized to the original tree structure.
For example, you may serialize the following `3-ary` tree as `[1 [3[5 6] 2 4]]`. Note that this is just an example, you do not necessarily need to follow this format.
Or you can follow LeetCode's level order traversal serialization format, where each group of children is separated by the null value. For example, the above tree may be serialized as `[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]`.
You do not necessarily need to follow the above-suggested formats, there are many more different formats that work so please be creative and come up with different approaches yourself.
### Examples

```
Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Output: [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
```

```
Input: root = [1,null,3,2,4,null,5,6]
Output: [1,null,3,2,4,null,5,6]
```
```
Input: root = []
Output: []
```
### Constraints
* The number of nodes in the tree is in the range `[0, 10^4]`.
* `0 <= Node.val <= 10^4`.
* The height of the n-ary tree is less than or equal to `1000`.
* Do not use class member/global/static variables to store states. Your encode and decode algorithms should be stateless.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/serialize_and_deserialize_n_ary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/serialize_and_deserialize_n_ary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from __future__ import annotations
class Node:
def __init__(self, val: int = 0, children: list[Node] | None = None) -> None:
self.val = val
self.children = children if children is not None else []
class Codec:
# Time: O(n) for encode and decode
# Space: O(n)
def __init__(self) -> None:
pass
def encode(self, root: Node | None) -> str:
vals: list[str] = []
def dfs(node: Node | None) -> None:
if node is None:
return
vals.append(str(node.val))
vals.append(str(len(node.children)))
for child in node.children:
dfs(child)
dfs(root)
return ",".join(vals)
def decode(self, data: str) -> Node | None:
vals = [int(v) for v in data.split(",") if v != ""]
pos = 0
def dfs() -> Node | None:
nonlocal pos
if pos >= len(vals):
return None
node = Node(vals[pos])
count = vals[pos + 1]
pos += 2
for _ in range(count):
child = dfs()
assert child is not None
node.children.append(child)
return node
return dfs()
```
## Complexity
| Time | Space |
| -------------------------- | ----- |
| O(n) for encode and decode | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Set Intersection Size At Least Two
Source: https://leetcode-py.wisl.dev/problems/set-intersection-size-at-least-two
Tested Python solution for LeetCode 757 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 757, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/set-intersection-size-at-least-two/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 757 # by problem number
lcpy gen -s set_intersection_size_at_least_two # by problem name
```
## Problem
You are given a 2D integer array `intervals` where `intervals[i] = [starti, endi]` represents all the integers from `starti` to `endi` inclusively.
A **containing set** is an array `nums` where each interval from `intervals` has **at least two** integers in `nums`.
For example, if `intervals = [[1,3], [3,7], [8,9]]`, then `[1,2,4,7,8,9]` and `[2,3,4,8,9]` are containing sets.
Return the minimum possible size of a containing set.
### Examples
```
Input: intervals = [[1,3],[3,7],[8,9]]
Output: 5
```
**Explanation:** let nums = \[2, 3, 4, 8, 9]. It can be shown that there cannot be any containing array of size 4.
```
Input: intervals = [[1,3],[1,4],[2,5],[3,5]]
Output: 3
```
**Explanation:** let nums = \[2, 3, 4]. It can be shown that there cannot be any containing array of size 2.
```
Input: intervals = [[1,2],[2,3],[2,4],[4,5]]
Output: 5
```
**Explanation:** let nums = \[1, 2, 3, 4, 5]. It can be shown that there cannot be any containing array of size 4.
### Constraints
* `1 <= intervals.length <= 3000`
* `intervals[i].length == 2`
* `0 <= starti < endi <= 10^8`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/set_intersection_size_at_least_two/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/set_intersection_size_at_least_two/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n)
def intersection_size_two(self, intervals: list[list[int]]) -> int:
# Sort by end ascending, start descending: later intervals shrink leftward,
# so tracking the two largest chosen numbers suffices to test coverage.
srt = sorted(intervals, key=lambda iv: (iv[1], -iv[0]))
second_last = -1
last = -1
count = 0
for start, end in srt:
if start <= second_last:
continue
if start > last:
count += 2
second_last, last = end - 1, end
else:
count += 1
second_last, last = last, end
return count
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
# Set Matrix Zeroes Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/set-matrix-zeroes
Tested Python solution for LeetCode 73 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 73, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/set-matrix-zeroes/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 73 # by problem number
lcpy gen -s set_matrix_zeroes # by problem name
```
## Problem
Given an `m x n` integer matrix `matrix`, if an element is `0`, set its entire row and column to `0`'s. You must do it in place.
### Examples

```
Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]
```

```
Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m, n \<= 200
* -2^31 \<= matrix\[i]\[j] \<= 2^31 - 1
* Follow up: Could you devise a constant space solution?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/set_matrix_zeroes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/set_matrix_zeroes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(1)
def set_zeroes(self, matrix: list[list[int]]) -> None:
row_count: int = len(matrix)
col_count: int = len(matrix[0]) if row_count > 0 else 0
first_row_has_zero: bool = any(matrix[0][col_index] == 0 for col_index in range(col_count))
first_col_has_zero: bool = any(matrix[row_index][0] == 0 for row_index in range(row_count))
for row_index in range(1, row_count):
for col_index in range(1, col_count):
if matrix[row_index][col_index] == 0:
matrix[row_index][0] = 0
matrix[0][col_index] = 0
for row_index in range(1, row_count):
for col_index in range(1, col_count):
if matrix[row_index][0] == 0 or matrix[0][col_index] == 0:
matrix[row_index][col_index] = 0
if first_row_has_zero:
for col_index in range(col_count):
matrix[0][col_index] = 0
if first_col_has_zero:
for row_index in range(row_count):
matrix[row_index][0] = 0
```
## Complexity
| Time | Space |
| --------- | ----- |
| O(m \* n) | O(1) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Set Mismatch Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/set-mismatch
Tested Python solution for LeetCode 645 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 645, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/set-mismatch/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 645 # by problem number
lcpy gen -s set_mismatch # by problem name
```
## Problem
You have a set of integers `s`, which originally contains all the numbers from `1` to `n`. Unfortunately, due to some error, one of the numbers in `s` got duplicated to another number in the set, which results in **repetition of one** number and **loss of another** number.
You are given an integer array `nums` representing the data status of this set after the error.
Find the number that occurs twice and the number that is missing and return *them in the form of an array*.
### Examples
```
Input: nums = [1,2,2,4]
Output: [2,3]
```
```
Input: nums = [1,1]
Output: [1,2]
```
### Constraints
* 2 \<= nums.length \<= 10^4
* 1 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/set_mismatch/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/set_mismatch/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(n)
def find_error_nums(self, nums: list[int]) -> list[int]:
n = len(nums)
counts = Counter(nums)
duplicate = missing = -1
for value in range(1, n + 1):
if counts[value] == 2:
duplicate = value
elif counts[value] == 0:
missing = value
return [duplicate, missing]
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shift 2D Grid Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/shift-2d-grid
Tested Python solution for LeetCode 1260 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1260, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/shift-2d-grid/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1260 # by problem number
lcpy gen -s shift_2d_grid # by problem name
```
## Problem
Given a 2D grid of size m x n and an integer k. You need to shift the grid k times.
In one shift operation:
* Element at grid\[i]\[j] moves to grid\[i]\[j + 1].
* Element at grid\[i]\[n - 1] moves to grid\[i + 1]\[0].
* Element at grid\[m - 1]\[n - 1] moves to grid\[0]\[0].
Return the 2D grid after applying shift operation k times.
### Examples

```
Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1
Output: [[9,1,2],[3,4,5],[6,7,8]]
```

```
Input: grid = [[3,8,1,9],[19,7,2,5],[4,6,11,10],[12,0,21,13]], k = 4
Output: [[12,0,21,13],[3,8,1,9],[19,7,2,5],[4,6,11,10]]
```
```
Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 9
Output: [[1,2,3],[4,5,6],[7,8,9]]
```
### Constraints
* m == grid.length
* n == grid\[i].length
* 1 \<= m \<= 50
* 1 \<= n \<= 50
* -1000 \<= grid\[i]\[j] \<= 1000
* 0 \<= k \<= 100
**Follow up:**
* Can you find a O(n \* m) solution?
* Can you find an in-place solution?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shift_2d_grid/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shift_2d_grid/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
def shift_grid(self, grid: list[list[int]], k: int) -> list[list[int]]:
m, n = len(grid), len(grid[0])
total = m * n
k %= total
flat = [grid[i][j] for i in range(m) for j in range(n)]
flat = flat[-k:] + flat[:-k] if k else flat
return [flat[i * n : (i + 1) * n] for i in range(m)]
```
## Complexity
| Time | Space |
| ---- | ----- |
| - | - |
## Tags
[NeetCode All](/catalog/neetcode).
# Shifting Letters Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/shifting-letters
Tested Python solution for LeetCode 848 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 848, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/shifting-letters/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 848 # by problem number
lcpy gen -s shifting_letters # by problem name
```
## Problem
You are given a string `s` of lowercase English letters and an integer array `shifts` of the same length.
Call the `shift()` of a letter, the next letter in the alphabet, (wrapping around so that `'z'` becomes `'a'`).
* For example, `shift('a') = 'b'`, `shift('t') = 'u'`, and `shift('z') = 'a'`.
Now for each `shifts[i] = x`, we want to shift the first `i + 1` letters of `s`, `x` times.
Return *the final string after all such shifts to s are applied*.
### Examples
```
Input: s = "abc", shifts = [3,5,9]
Output: "rpl"
Explanation: We start with "abc".
After shifting the first 1 letters of s by 3, we have "dbc".
After shifting the first 2 letters of s by 5, we have "igc".
After shifting the first 3 letters of s by 9, we have "rpl", the answer.
```
```
Input: s = "aaa", shifts = [1,2,3]
Output: "gfd"
```
### Constraints
* 1 \<= s.length \<= 10^5
* s consists of lowercase English letters.
* shifts.length == s.length
* 0 \<= shifts\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shifting_letters/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shifting_letters/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def shifting_letters(self, s: str, shifts: list[int]) -> str:
total = 0
result = list(s)
for i in range(len(s) - 1, -1, -1):
total = (total + shifts[i]) % 26
result[i] = chr((ord(result[i]) - 97 + total) % 26 + 97)
return "".join(result)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Shifting Letters II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/shifting-letters-ii
Tested Python solution for LeetCode 2381 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 2381, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/shifting-letters-ii/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2381 # by problem number
lcpy gen -s shifting_letters_ii # by problem name
```
## Problem
You are given a string `s` of lowercase English letters and a 2D integer array `shifts` where `shifts[i] = [starti, endi, directioni]`. For every `i`, **shift** the characters in `s` from the index `starti` to the index `endi` (**inclusive**) forward if `directioni = 1`, or shift the characters backward if `directioni = 0`.
Shifting a character **forward** means replacing it with the **next** letter in the alphabet (wrapping around so that `'z'` becomes `'a'`). Similarly, shifting a character **backward** means replacing it with the **previous** letter in the alphabet (wrapping around so that `'a'` becomes `'z'`).
Return *the final string after all such shifts to* `s` *are applied*.
### Examples
```
Input: s = "abc", shifts = [[0,1,0],[1,2,1],[0,2,1]]
Output: "ace"
Explanation: Firstly, shift the characters from index 0 to index 1 backward. Now s = "zac".
Secondly, shift the characters from index 1 to index 2 forward. Now s = "zbd".
Finally, shift the characters from index 0 to index 2 forward. Now s = "ace".
```
```
Input: s = "dztz", shifts = [[0,0,0],[1,1,1]]
Output: "catz"
Explanation: Firstly, shift the characters from index 0 to index 0 backward. Now s = "cztz".
Finally, shift the characters from index 1 to index 1 forward. Now s = "catz".
```
### Constraints
* `1 <= s.length, shifts.length <= 5 * 10^4`
* `shifts[i].length == 3`
* `0 <= start_i <= end_i < s.length`
* `0 <= direction_i <= 1`
* `s` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shifting_letters_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shifting_letters_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + m)
# Space: O(n)
def shifting_letters(self, s: str, shifts: list[list[int]]) -> str:
diff = [0] * (len(s) + 1)
for start, end, direction in shifts:
offset = 1 if direction == 1 else -1
diff[start] += offset
diff[end + 1] -= offset
result: list[str] = []
running = 0
for i, char in enumerate(s):
running += diff[i]
result.append(chr((ord(char) - ord("a") + running) % 26 + ord("a")))
return "".join(result)
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + m) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shopping Offers Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/shopping-offers
Tested Python solution for LeetCode 638 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 638, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Memoization](/catalog/topics/memoization), [Bitmask](/catalog/topics/bitmask), Knapsack Problem, Complete Knapsack. [View on LeetCode](https://leetcode.com/problems/shopping-offers/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 638 # by problem number
lcpy gen -s shopping_offers # by problem name
```
## Problem
In LeetCode Store, there are `n` items to sell. Each item has a price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price.
You are given an integer array `price` where `price[i]` is the price of the `i_th` item, and an integer array `needs` where `needs[i]` is the number of pieces of the `i_th` item you want to buy.
You are also given an array `special` where `special[i]` is of size `n + 1` where `special[i][j]` is the number of pieces of the `j_th` item in the `i_th` offer and `special[i][n]` (i.e., the last integer in the array) is the price of the `i_th` offer.
Return *the lowest price you have to pay for exactly certain items as given, where you could make optimal use of the special offers*. You are not allowed to buy more items than you want, even if that would lower the overall price. You could use any of the special offers as many times as you want.
### Examples
```
Input: price = [2,5], special = [[3,0,5],[1,2,10]], needs = [3,2]
Output: 14
```
**Explanation:** There are two kinds of items, A and B. Their prices are $2 and $5 respectively. In special offer 1, you can pay $5 for 3A and 0B. In special offer 2, you can pay $10 for 1A and 2B. You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer #2), and $4 for 2A.
```
Input: price = [2,3,4], special = [[1,1,0,4],[2,2,1,9]], needs = [1,2,1]
Output: 11
```
**Explanation:** The price of A is $2, and $3 for B, $4 for C. You may pay $4 for 1A and 1B, and $9 for 2A, 2B and 1C. You need to buy 1A, 2B and 1C, so you may pay $4 for 1A and 1B (special offer #1), and $3 for 1B, $4 for 1C. You cannot add more items, though only \$9 for 2A, 2B and 1C.
### Constraints
* `n == price.length == needs.length`
* `1 <= n <= 6`
* `0 <= price[i], needs[i] <= 10`
* `1 <= special.length <= 100`
* `special[i].length == n + 1`
* `0 <= special[i][j] <= 50`
* The input is generated that at least one of `special[i][j]` is non-zero for `0 <= j <= n - 1`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shopping_offers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shopping_offers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cache
class Solution:
# Time: O(len(special) * product(needs[i] + 1))
# Space: O(product(needs[i] + 1)) for the memo
def shopping_offers(self, price: list[int], special: list[list[int]], needs: list[int]) -> int:
offers = [
(tuple(offer[:-1]), offer[-1])
for offer in special
if sum(a * b for a, b in zip(offer[:-1], price, strict=True)) > offer[-1]
]
@cache
def dfs(need: tuple[int, ...]) -> int:
best = sum(p * c for p, c in zip(price, need, strict=True))
for items, cost in offers:
if all(have >= take for have, take in zip(need, items, strict=True)):
rest = tuple(have - take for have, take in zip(need, items, strict=True))
best = min(best, cost + dfs(rest))
return best
return dfs(tuple(needs))
```
## Complexity
| Time | Space |
| ----------------------------------------- | -------------------------------------- |
| O(len(special) \* product(needs\[i] + 1)) | O(product(needs\[i] + 1)) for the memo |
## Tags
# Short Encoding of Words Python Solution
Source: https://leetcode-py.wisl.dev/problems/short-encoding-of-words
Tested Python solution for LeetCode 820 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 820, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Trie](/catalog/topics/trie). [View on LeetCode](https://leetcode.com/problems/short-encoding-of-words/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 820 # by problem number
lcpy gen -s short_encoding_of_words # by problem name
```
## Problem
A **valid encoding** of an array of `words` is any reference string `s` and array of indices `indices` such that:
* `words.length == indices.length`
* The reference string `s` ends with the `'#'` character.
* For each index `indices[i]`, the **substring** of `s` starting from `indices[i]` and up to (but not including) the next `'#'` character is equal to `words[i]`.
Given an array of `words`, return *the **length of the shortest reference string** \* `s` \* possible of any **valid encoding** of \* `words`*.
### Examples
```
Input: words = ["time", "me", "bell"]
Output: 10
Explanation: A valid encoding would be s = "time#bell#" and indices = [0, 2, 5].
words[0] = "time", the substring of s starting from indices[0] = 0 to the next '#' is underlined in "time#bell#"
words[1] = "me", the substring of s starting from indices[1] = 2 to the next '#' is underlined in "ti*me*#bell#"
words[2] = "bell", the substring of s starting from indices[2] = 5 to the next '#' is underlined in "time#*bell*#"
```
```
Input: words = ["t"]
Output: 2
Explanation: A valid encoding would be s = "t#" and indices = [0].
```
### Constraints
* 1 \<= words.length \<= 2000
* 1 \<= words\[i].length \<= 7
* words\[i] consists of only lowercase letters.
**Follow up:** Can you solve it in O(n \* max(words\[i].length)) time using a Trie?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/short_encoding_of_words/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/short_encoding_of_words/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * L^2) where n = len(words), L = max word length (suffix slices)
# Space: O(n * L)
def minimum_length_encoding(self, words: list[str]) -> int:
unique = set(words)
return sum(
len(word) + 1
for word in unique
if not any(other.endswith(word) for other in unique if other != word)
)
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------- | --------- |
| O(n \* L^2) where n = len(words), L = max word length (suffix slices) | O(n \* L) |
## Tags
# Shortest Bridge Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/shortest-bridge
Tested Python solution for LeetCode 934 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 934, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/shortest-bridge/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 934 # by problem number
lcpy gen -s shortest_bridge # by problem name
```
## Problem
\You are given an \n x n\ binary matrix \grid\ where \1\ represents land and \0\ represents water.\
An island is a 4-directionally connected group of \1\'s not connected to any other \1\'s. There are \exactly two islands\ in \grid\.\
You may change \0\'s to \1\'s to connect the two islands to form \one island\.\
Return \the smallest number of \\0\\'s you must flip to connect the two islands\.\
str1\ and \str2\, return \the shortest string that has both \\str1\\ and \\str2\\ as \subsequences\\. If there are multiple valid strings, return \any\ of them.
A string \s\ is a \subsequence\ of string \t\ if deleting some number of characters from \t\ (possibly \0\) results in the string \s\.
### Examples
```
Input: str1 = "abac", str2 = "cab"
Output: "cabac"
Explanation: str1 = "abac" is a subsequence of "cabac" because we can delete the first "c". str2 = "cab" is a subsequence of "cabac" because we can delete the last "ac". The answer provided is the shortest such string that satisfies these properties.
```
```
Input: str1 = "aaaaaaaa", str2 = "aaaaaaaa"
Output: "aaaaaaaa"
```
### Constraints
* \1 \<= str1.length, str2.length \<= 1000\
* \str1\ and \str2\ consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_common_supersequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_common_supersequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def shortest_common_supersequence(self, str1: str, str2: str) -> str:
m, n = len(str1), len(str2)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if str1[i - 1] == str2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
out: list[str] = []
i, j = m, n
while i > 0 and j > 0:
if str1[i - 1] == str2[j - 1]:
out.append(str1[i - 1])
i -= 1
j -= 1
elif dp[i - 1][j] >= dp[i][j - 1]:
out.append(str1[i - 1])
i -= 1
else:
out.append(str2[j - 1])
j -= 1
out.extend(str1[:i][::-1])
out.extend(str2[:j][::-1])
return "".join(reversed(out))
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Completing Word Python Solution
Source: https://leetcode-py.wisl.dev/problems/shortest-completing-word
Tested Python solution for LeetCode 748 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 748, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/shortest-completing-word/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 748 # by problem number
lcpy gen -s shortest_completing_word # by problem name
```
## Problem
Given a string `licensePlate` and an array of strings `words`, find the **shortest completing** word in `words`.
A **completing** word is a word that **contains all the letters** in `licensePlate`. **Ignore numbers and spaces** in `licensePlate`, and treat letters as **case insensitive**. If a letter appears more than once in `licensePlate`, then it must appear in the word the same number of times or more.
For example, if `licensePlate = "aBc 12c"`, then it contains letters `'a'`, `'b'` (ignoring case), and `'c'` twice. Possible **completing** words are `"abccdef"`, `"caaacab"`, and `"cbca"`.
Return *the shortest **completing** word in* `words`\*. It is guaranteed an answer exists. If there are multiple shortest **completing** words, return the **first** one that occurs in `words`.
### Examples
```
Input: licensePlate = "1s3 PSt", words = ["step","steps","stripe","stepple"]
Output: "steps"
Explanation: licensePlate contains letters 's', 'p', 's' (ignoring case), and 't'.
"step" contains 't' and 'p', but only contains 1 's'.
"steps" contains 't', 'p', and both 's' characters.
"stripe" is missing an 's'.
"stepple" is missing an 's'.
Since "steps" is the only word containing all the letters, that is the answer.
```
```
Input: licensePlate = "1s3 456", words = ["looks","pest","stew","show"]
Output: "pest"
Explanation: licensePlate only contains the letter 's'. All the words contain 's', but among these "pest", "stew", and "show" are shortest. The answer is "pest" because it is the word that appears earliest of the 3.
```
### Constraints
* 1 \<= licensePlate.length \<= 7
* licensePlate contains digits, letters (uppercase or lowercase), or space ' '.
* 1 \<= words.length \<= 1000
* 1 \<= words\[i].length \<= 15
* words\[i] consists of lower case English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_completing_word/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_completing_word/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n * (m + k)) - n words, m word length, k <= 7 plate letters
# Space: O(1) - at most 26 letters per counter
def shortest_completing_word(self, license_plate: str, words: list[str]) -> str:
need = Counter(c for c in license_plate.lower() if c.isalpha())
best: str | None = None
for word in words:
count = Counter(word)
if all(count[ch] >= k for ch, k in need.items()) and (
best is None or len(word) < len(best)
):
best = word
return best or ""
```
## Complexity
| Time | Space |
| --------------------------------------------------------------- | ------------------------------------- |
| O(n \* (m + k)) - n words, m word length, k \<= 7 plate letters | O(1) - at most 26 letters per counter |
## Tags
# Shortest Distance After Road Addition Queries
Source: https://leetcode-py.wisl.dev/problems/shortest-distance-after-queries-i
Tested Python solution for LeetCode 3243 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 3243, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory). [View on LeetCode](https://leetcode.com/problems/shortest-distance-after-queries-i/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3243 # by problem number
lcpy gen -s shortest_distance_after_queries_i # by problem name
```
## Problem
You are given an integer \n\ and a 2D integer array \queries\.
There are \n\ cities numbered from \0\ to \n - 1\. Initially, there is a \unidirectional\ road from city \i\ to city \i + 1\ for all \0 \<= i \< n - 1\.
\queries\[i] = \[u\i\, v\i\]\ represents the addition of a new \unidirectional\ road from city \u\i\\ to city \v\i\\. After each query, you need to find the \length\ of the \shortest path\ from city \0\ to city \n - 1\.
Return an array \answer\ where for each \i\ in the range \\[0, queries.length - 1]\, \answer\[i]\ is the length of the shortest path from city \0\ to city \n - 1\ after processing the \first\ \i + 1\ queries.
### Examples

```
Input: n = 5, queries = [[2,4],[0,2],[0,4]]
Output: [3,2,1]
Explanation:
After the addition of the road from 2 to 4, the length of the shortest path from 0 to 4 is 3.
```

After the addition of the road from 0 to 2, the length of the shortest path from 0 to 4 is 2.

After the addition of the road from 0 to 4, the length of the shortest path from 0 to 4 is 1.

```
Input: n = 4, queries = [[0,3],[0,2]]
Output: [1,1]
Explanation:
After the addition of the road from 0 to 3, the length of the shortest path from 0 to 3 is 1.
```

After the addition of the road from 0 to 2, the length of the shortest path remains 1.
### Constraints
* \3 \<= n \<= 500\
* \1 \<= queries.length \<= 500\
* \queries\[i].length == 2\
* \0 \<= queries\[i]\[0] \< queries\[i]\[1] \< n\
* \1 \< queries\[i]\[1] - queries\[i]\[0]\
* There are no repeated roads among the queries.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_distance_after_queries_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_distance_after_queries_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n + q * k) where k is the number of distance decreases, q = len(queries)
# Space: O(n + q)
def shortest_distance_after_queries(self, n: int, queries: list[list[int]]) -> list[int]:
adj: list[list[int]] = [[i + 1] for i in range(n - 1)]
adj.append([])
dist = list(range(n))
result: list[int] = []
for u, v in queries:
adj[u].append(v)
if dist[u] + 1 >= dist[v]:
result.append(dist[n - 1])
continue
dist[v] = dist[u] + 1
queue: deque[int] = deque([v])
while queue:
cur = queue.popleft()
for nxt in adj[cur]:
if dist[cur] + 1 < dist[nxt]:
dist[nxt] = dist[cur] + 1
queue.append(nxt)
result.append(dist[n - 1])
return result
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------------- | -------- |
| O(n + q \* k) where k is the number of distance decreases, q = len(queries) | O(n + q) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Distance from All Buildings
Source: https://leetcode-py.wisl.dev/problems/shortest-distance-from-all-buildings
Tested Python solution for LeetCode 317 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 317, [Hard](/catalog/hard). Topics: [Breadth-First Search](/catalog/topics/breadth-first-search), [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/shortest-distance-from-all-buildings/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 317 # by problem number
lcpy gen -s shortest_distance_from_all_buildings # by problem name
```
## Problem
You are given an `m x n` grid `grid` of values `0`, `1`, or `2`, where:
* each `0` marks **an empty land** that you can pass by freely,
* each `1` marks **a building** that you cannot pass through, and
* each `2` marks **an obstacle** that you cannot pass through.
You want to build a house on an empty land that reaches all buildings in the **shortest total travel** distance. You can only move up, down, left, and right.
Return *the **shortest travel distance** for such a house*. If it is not possible to build such a house according to the above rules, return `-1`.
The **total travel distance** is the sum of the distances between the houses of the friends and the meeting point.
### Examples

```
Input: grid = [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]
Output: 7
Explanation: Given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2).
The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal.
So return 7.
```
```
Input: grid = [[1,0]]
Output: 1
```
```
Input: grid = [[1]]
Output: -1
```
### Constraints
* `m == grid.length`
* `n == grid[i].length`
* `1 <= m, n <= 50`
* `grid[i][j]` is either `0`, `1`, or `2`.
* There will be **at least one** building in the `grid`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_distance_from_all_buildings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_distance_from_all_buildings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(b * m * n) — one BFS per building (b = building count)
# Space: O(m * n)
def shortest_distance(self, grid: list[list[int]]) -> int:
m, n = len(grid), len(grid[0])
total = [[0] * n for _ in range(m)]
reach = [[0] * n for _ in range(m)]
building_count = sum(row.count(1) for row in grid)
for i in range(m):
for j in range(n):
if grid[i][j] != 1:
continue
distance = [[-1] * n for _ in range(m)]
distance[i][j] = 0
queue: deque[tuple[int, int]] = deque([(i, j)])
while queue:
r, c = queue.popleft()
for x, y in ((r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)):
if 0 <= x < m and 0 <= y < n and grid[x][y] == 0 and distance[x][y] < 0:
distance[x][y] = distance[r][c] + 1
queue.append((x, y))
for r in range(m):
for c in range(n):
if distance[r][c] >= 0:
total[r][c] += distance[r][c]
reach[r][c] += 1
best = -1
for i in range(m):
for j in range(n):
if (
grid[i][j] == 0
and reach[i][j] == building_count
and (best < 0 or total[i][j] < best)
):
best = total[i][j]
return best
```
## Complexity
| Time | Space |
| ---------------------------------------------------------- | --------- |
| O(b \* m \* n) — one BFS per building (b = building count) | O(m \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Distance to a Character
Source: https://leetcode-py.wisl.dev/problems/shortest-distance-to-a-character
Tested Python solution for LeetCode 821 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 821, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/shortest-distance-to-a-character/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 821 # by problem number
lcpy gen -s shortest_distance_to_a_character # by problem name
```
## Problem
Given a string `s` and a character `c` that occurs in `s`, return an array of integers `answer` where `answer.length == s.length` and `answer[i]` is the distance from index `i` to the closest occurrence of character `c` in `s`.
The distance between two indices `i` and `j` is `abs(i - j)`, where `abs` is the absolute value function.
### Examples
```
Input: s = "loveleetcode", c = "e"
Output: [3,2,1,0,1,0,0,1,2,2,1,0]
```
**Explanation:** The character 'e' appears at indices 3, 5, 6, and 11 (0-indexed). The closest occurrence of 'e' for index 0 is at index 3, so the distance is abs(0 - 3) = 3. For index 4, there is a tie between the 'e' at index 3 and the 'e' at index 5, but the distance is still the same: abs(4 - 3) == abs(4 - 5) = 1.
```
Input: s = "aaab", c = "b"
Output: [3,2,1,0]
```
### Constraints
* 1 \<= s.length \<= 10^4
* s\[i] and c are lowercase English letters.
* It is guaranteed that c occurs at least once in s.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_distance_to_a_character/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_distance_to_a_character/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n) for the output array
def shortest_to_char(self, s: str, c: str) -> list[int]:
n = len(s)
answer = [n] * n
prev = -n
for i, char in enumerate(s):
if char == c:
prev = i
answer[i] = i - prev
prev = 2 * n
for i in range(n - 1, -1, -1):
if s[i] == c:
prev = i
answer[i] = min(answer[i], prev - i)
return answer
```
## Complexity
| Time | Space |
| ---- | ------------------------- |
| O(n) | O(n) for the output array |
## Tags
# Shortest Palindrome Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/shortest-palindrome
Tested Python solution for LeetCode 214 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 214, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), Rolling Hash, [String Matching](/catalog/topics/string-matching), [Hash Function](/catalog/topics/hash-function), Manacher, Z Algorithm, Knuth-Morris-Pratt Algorithm. [View on LeetCode](https://leetcode.com/problems/shortest-palindrome/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 214 # by problem number
lcpy gen -s shortest_palindrome # by problem name
```
## Problem
You are given a string `s`. You can convert `s` to a palindrome by adding characters in front of it.
Return the shortest palindrome you can find by performing this transformation.
### Examples
```
Input: s = "aacecaaa"
Output: "aaacecaaa"
```
```
Input: s = "abcd"
Output: "dcbabcd"
```
### Constraints
* 0 \<= s.length \<= 5 \* 10^4
* s consists of lowercase English letters only.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_palindrome/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_palindrome/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def shortest_palindrome(self, s: str) -> str:
if not s:
return s
rev = s[::-1]
combined = s + "#" + rev
n = len(combined)
pi = [0] * n
for i in range(1, n):
j = pi[i - 1]
while j > 0 and combined[i] != combined[j]:
j = pi[j - 1]
if combined[i] == combined[j]:
j += 1
pi[i] = j
longest = pi[-1]
return rev[: len(s) - longest] + s
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Path in Binary Matrix Python Solution
Source: https://leetcode-py.wisl.dev/problems/shortest-path-in-binary-matrix
Tested Python solution for LeetCode 1091 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 1091, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/shortest-path-in-binary-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1091 # by problem number
lcpy gen -s shortest_path_in_binary_matrix # by problem name
```
## Problem
Given an `n x n` binary matrix `grid`, return *the length of the shortest **clear path*** in the matrix. If there is no clear path, return `-1`.
A **clear path** in a binary matrix is a path from the top-left cell (i.e., `(0, 0)`) to the bottom-right cell (i.e., `(n - 1, n - 1)`) such that:
* All the visited cells of the path are `0`.
* All the adjacent cells of the path are **8-directionally** connected (i.e., they are different and they share an edge or a corner).
The length of a clear path is the number of visited cells of this path.
### Examples
```
Input: grid = [[0,1],[1,0]]
Output: 2
```
```
Input: grid = [[0,0,0],[1,1,0],[1,1,0]]
Output: 4
```
```
Input: grid = [[1,0,0],[1,1,0],[1,1,0]]
Output: -1
```
### Constraints
* `n == grid.length`
* `n == grid[i].length`
* `1 <= n <= 100`
* `grid[i][j] is 0 or 1`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_in_binary_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_in_binary_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def shortest_path_binary_matrix(self, grid: list[list[int]]) -> int:
if grid[0][0] == 1 or grid[-1][-1] == 1:
return -1
n = len(grid)
if n == 1:
return 1
directions = [
(-1, -1),
(-1, 0),
(-1, 1),
(0, -1),
(0, 1),
(1, -1),
(1, 0),
(1, 1),
]
queue: deque[tuple[int, int]] = deque([(0, 0)])
grid[0][0] = 1
while queue:
row, col = queue.popleft()
distance = grid[row][col]
for dr, dc in directions:
nr, nc = row + dr, col + dc
if nr == n - 1 and nc == n - 1:
return distance + 1
if 0 <= nr < n and 0 <= nc < n and grid[nr][nc] == 0:
grid[nr][nc] = distance + 1
queue.append((nr, nc))
return -1
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Path to Get All Keys Python Solution
Source: https://leetcode-py.wisl.dev/problems/shortest-path-to-get-all-keys
Tested Python solution for LeetCode 864 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 864, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/shortest-path-to-get-all-keys/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 864 # by problem number
lcpy gen -s shortest_path_to_get_all_keys # by problem name
```
## Problem
You are given an `m x n` grid `grid` where:
* `'.'` is an empty cell.
* `'#'` is a wall.
* `'@'` is the starting point.
* Lowercase letters represent keys.
* Uppercase letters represent locks.
You start at the starting point and one move consists of walking one space in one of the four cardinal directions. You cannot walk outside the grid, or walk into a wall.
If you walk over a key, you can pick it up and you cannot walk over a lock unless you have its corresponding key.
For some `1 <= k <= 6`, there is exactly one lowercase and one uppercase letter of the first `k` letters of the English alphabet in the grid. This means that there is exactly one key for each lock, and one lock for each key; and also that the letters used to represent the keys and locks were chosen in the same order as the English alphabet.
Return the lowest number of moves to acquire all keys. If it is impossible, return `-1`.
### Examples
```
Input: grid = ["@.a..","###.#","b.A.B"]
Output: 8
Explanation: Note that the goal is to obtain all the keys not to open all the locks.
```
```
Input: grid = ["@..aA","..B#.","....b"]
Output: 6
```
```
Input: grid = ["@Aa"]
Output: -1
```
### Constraints
* `m == grid.length`
* `n == grid[i].length`
* `1 <= m, n <= 30`
* `grid[i][j]` is a letter, `'.'`, `'#'`, or `'@'`.
* There is exactly one `'@'` in the grid.
* The number of keys in the grid is in the range `[1, 6]`.
* Each key in the grid is unique.
* Each key in the grid has a matching lock.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_to_get_all_keys/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_to_get_all_keys/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(m * n * 2^k)
# Space: O(m * n * 2^k)
def shortest_path_all_keys(self, grid: list[str]) -> int:
m, n = len(grid), len(grid[0])
keys = 0
start_r = start_c = 0
for r in range(m):
for c in range(n):
ch = grid[r][c]
if ch == "@":
start_r, start_c = r, c
elif ch.islower():
keys |= 1 << (ord(ch) - ord("a"))
queue: deque[tuple[int, int, int]] = deque([(start_r, start_c, 0)])
seen = {(start_r, start_c, 0)}
moves = 0
while queue:
for _ in range(len(queue)):
r, c, held = queue.popleft()
if held == keys:
return moves
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if not (0 <= nr < m and 0 <= nc < n):
continue
ch = grid[nr][nc]
if ch == "#":
continue
if ch.isupper() and not held & (1 << (ord(ch.lower()) - ord("a"))):
continue
nxt = held | (1 << (ord(ch) - ord("a"))) if ch.islower() else held
state = (nr, nc, nxt)
if state not in seen:
seen.add(state)
queue.append(state)
moves += 1
return -1
```
## Complexity
| Time | Space |
| ---------------- | ---------------- |
| O(m \* n \* 2^k) | O(m \* n \* 2^k) |
## Tags
# Shortest Path to Get Food Python Solution
Source: https://leetcode-py.wisl.dev/problems/shortest-path-to-get-food
Tested Python solution for LeetCode 1730 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 1730, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/shortest-path-to-get-food/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1730 # by problem number
lcpy gen -s shortest_path_to_get_food # by problem name
```
## Problem
You are starving and you want to eat food as quickly as possible. You want to find the shortest path to arrive at any food cell.
You are given an `m x n` character matrix, `grid`, of these different types of cells:
* `'*'` is your location. There is exactly one `'*'` cell.
* `'#'` is a food cell. There may be multiple food cells.
* `'O'` is free space, and you can travel through these cells.
* `'X'` is an obstacle, and you cannot travel through these cells.
You can travel to any adjacent cell north, east, south, or west of your current location if there is not an obstacle.
Return the length of the shortest path for you to reach any food cell. If there is no path for you to reach food, return `-1`.
### Examples
```
Input: grid = [["X","X","X","X","X","X"],["X","*","O","O","O","X"],["X","O","O","#","O","X"],["X","X","X","X","X","X"]]
Output: 3
Explanation: It takes 3 steps to reach the food.
```
```
Input: grid = [["X","X","X","X","X"],["X","*","X","O","X"],["X","O","X","#","X"],["X","X","X","X","X"]]
Output: -1
Explanation: It is not possible to reach the food.
```
```
Input: grid = [["X","X","X","X","X","X","X","X"],["X","*","O","X","O","#","O","X"],["X","O","O","X","O","O","X","X"],["X","O","O","O","O","#","O","X"],["X","X","X","X","X","X","X","X"]]
Output: 6
Explanation: There can be multiple food cells. It only takes 6 steps to reach the bottom food.
```
```
Input: grid = [["O","*"],["#","O"]]
Output: 2
```
### Constraints
* `m == grid.length`
* `n == grid[i].length`
* `1 <= m, n <= 200`
* `grid[row][col]` is `'*'`, `'X'`, `'O'`, or `'#'`.
* The `grid` contains exactly one `'*'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_to_get_food/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_to_get_food/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def get_food(self, grid: list[list[str]]) -> int:
rows, cols = len(grid), len(grid[0])
start = next((r, c) for r in range(rows) for c in range(cols) if grid[r][c] == "*")
queue: deque[tuple[tuple[int, int], int]] = deque([(start, 0)])
visited = {start}
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
while queue:
(r, c), steps = queue.popleft()
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and (nr, nc) not in visited:
if grid[nr][nc] == "#":
return steps + 1
if grid[nr][nc] == "O":
visited.add((nr, nc))
queue.append(((nr, nc), steps + 1))
return -1
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[Grind](/catalog/grind).
# Shortest Path Visiting All Nodes
Source: https://leetcode-py.wisl.dev/problems/shortest-path-visiting-all-nodes
Tested Python solution for LeetCode 847 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 847, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Bit Manipulation](/catalog/topics/bit-manipulation), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph Theory](/catalog/topics/graph-theory), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/shortest-path-visiting-all-nodes/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 847 # by problem number
lcpy gen -s shortest_path_visiting_all_nodes # by problem name
```
## Problem
You have an undirected, connected graph of `n` nodes labeled from `0` to `n - 1`. You are given an array `graph` where `graph[i]` is a list of all the nodes connected with node `i` by an edge.
Return *the length of the shortest path that visits every node*. You may start and stop at any node, you may revisit nodes multiple times, and you may reuse edges.
### Examples

```
Input: graph = [[1,2,3],[0],[0],[0]]
Output: 4
Explanation: One possible path is [1,0,2,0,3]
```

```
Input: graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
Output: 4
Explanation: One possible path is [0,1,4,2,3]
```
### Constraints
* n == graph.length
* 1 \<= n \<= 12
* 0 \<= graph\[i].length \< n
* graph\[i] does not contain i.
* If graph\[a] contains b, then graph\[b] contains a.
* The input graph is always connected.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_visiting_all_nodes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_visiting_all_nodes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n * 2^n * n) = O(n^2 * 2^n) - each state dequeued once, n edges per state
# Space: O(n * 2^n) for the visited-state set
def shortest_path_length(self, graph: list[list[int]]) -> int:
n = len(graph)
full = (1 << n) - 1
queue: deque[tuple[int, int]] = deque((node, 1 << node) for node in range(n))
seen = {(node, 1 << node) for node in range(n)}
steps = 0
while queue:
for _ in range(len(queue)):
node, mask = queue.popleft()
if mask == full:
return steps
for neighbor in graph[node]:
state = (neighbor, mask | (1 << neighbor))
if state not in seen:
seen.add(state)
queue.append(state)
steps += 1
return steps
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------------------ | ------------------------------------- |
| O(n \* 2^n \* n) = O(n^2 \* 2^n) - each state dequeued once, n edges per state | O(n \* 2^n) for the visited-state set |
## Tags
# Shortest Path with Alternating Colors
Source: https://leetcode-py.wisl.dev/problems/shortest-path-with-alternating-colors
Tested Python solution for LeetCode 1129 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 1129, [Medium](/catalog/medium). Topics: [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph](/catalog/topics/graph). [View on LeetCode](https://leetcode.com/problems/shortest-path-with-alternating-colors/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1129 # by problem number
lcpy gen -s shortest_path_with_alternating_colors # by problem name
```
## Problem
You are given an integer \n\, the number of nodes in a directed graph where the nodes are labeled from \0\ to \n - 1\. Each edge is red or blue in this graph, and there could be self-edges and parallel edges.
You are given two arrays \redEdges\ and \blueEdges\ where:
* \redEdges\[i] = \[a\i\, b\i\]\ indicates that there is a directed red edge from node \a\i\\ to node \b\i\\ in the graph, and
* \blueEdges\[j] = \[u\j\, v\j\]\ indicates that there is a directed blue edge from node \u\j\\ to node \v\j\\ in the graph.
Return an array \answer\ of length \n\, where each \answer\[x]\ is the length of the shortest path from node \0\ to node \x\ such that the edge colors alternate along the path, or \-1\ if such a path does not exist.
### Examples
```
Input: n = 3, redEdges = [[0,1],[1,2]], blueEdges = []
Output: [0,1,-1]
```
```
Input: n = 3, redEdges = [[0,1]], blueEdges = [[2,1]]
Output: [0,1,-1]
```
### Constraints
* \1 \<= n \<= 100\
* \0 \<= redEdges.length, blueEdges.length \<= 400\
* \redEdges\[i].length == blueEdges\[j].length == 2\
* \0 \<= a\i\, b\i\, u\j\, v\j\ \< n\
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_with_alternating_colors/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_path_with_alternating_colors/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(n + e)
# Space: O(n + e)
def shortest_alternating_paths(
self, n: int, red_edges: list[list[int]], blue_edges: list[list[int]]
) -> list[int]:
adj: list[dict[str, list[int]]] = [{"r": [], "b": []} for _ in range(n)]
for a, b in red_edges:
adj[a]["r"].append(b)
for a, b in blue_edges:
adj[a]["b"].append(b)
ans = [-1] * n
dist: dict[tuple[int, str], int] = {(0, "r"): 0, (0, "b"): 0}
queue: deque[tuple[int, str]] = deque([(0, "r"), (0, "b")])
while queue:
node, color = queue.popleft()
if ans[node] == -1:
ans[node] = dist[(node, color)]
nxt = "b" if color == "r" else "r"
for nb in adj[node][nxt]:
if (nb, nxt) not in dist:
dist[(nb, nxt)] = dist[(node, color)] + 1
queue.append((nb, nxt))
return ans
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(n + e) | O(n + e) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Subarray to be Removed to Make Array
Source: https://leetcode-py.wisl.dev/problems/shortest-subarray-to-be-removed-to-make-array-sorted
Tested Python solution for LeetCode 1574 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1574, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/shortest-subarray-to-be-removed-to-make-array-sorted/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1574 # by problem number
lcpy gen -s shortest_subarray_to_be_removed_to_make_array_sorted # by problem name
```
## Problem
Given an integer array `arr`, remove a subarray (can be empty) from `arr` such that the remaining elements in `arr` are **non-decreasing**.
Return the length of the shortest subarray to remove.
A **subarray** is a contiguous subsequence of the array.
### Examples
```
Input: arr = [1,2,3,10,4,2,3,5]
Output: 3
```
**Explanation:** The shortest subarray we can remove is \[10,4,2] of length 3. The remaining elements after that will be \[1,2,3,3,5] which are sorted. Another correct solution is to remove the subarray \[3,10,4].
```
Input: arr = [5,4,3,2,1]
Output: 4
```
**Explanation:** Since the array is strictly decreasing, we can only keep a single element. Therefore we need to remove a subarray of length 4, either \[5,4,3,2] or \[4,3,2,1].
```
Input: arr = [1,2,3]
Output: 0
```
**Explanation:** The array is already non-decreasing. We do not need to remove any elements.
### Constraints
* 1 \<= arr.length \<= 10^5
* 0 \<= arr\[i] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_subarray_to_be_removed_to_make_array_sorted/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_subarray_to_be_removed_to_make_array_sorted/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_length_of_shortest_subarray(self, arr: list[int]) -> int:
n = len(arr)
end = n - 1
while end > 0 and arr[end - 1] <= arr[end]:
end -= 1
result = end
start = 0
while start < end and (start == 0 or arr[start - 1] <= arr[start]):
while end < n and arr[end] < arr[start]:
end += 1
result = min(result, end - start - 1)
start += 1
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Shortest Subarray With OR at Least K II
Source: https://leetcode-py.wisl.dev/problems/shortest-subarray-with-or-at-least-k-ii
Tested Python solution for LeetCode 3097 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 3097, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/shortest-subarray-with-or-at-least-k-ii/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 3097 # by problem number
lcpy gen -s shortest_subarray_with_or_at_least_k_ii # by problem name
```
## Problem
You are given an array \nums\ of \non-negative\ integers and an integer \k\.\
\An array is called \special\ if the bitwise \OR\ of all of its elements is \at least\ \k\.\
Return \the length of the \shortest\ \special\ \non-empty\ \subarray\ of\ \nums\, \or return\ \-1\ \if no special subarray exists\.\
nums\ and an integer \k\, return \the length of the shortest non-empty \subarray\ of \\nums\\ with a sum of at least \\k\. If there is no such \subarray\, return \-1\.\
\A \subarray\ is a \contiguous\ part of an array. ### Examples ``` Input: nums = [1], k = 1 Output: 1 ``` ``` Input: nums = [1,2], k = 4 Output: -1 ``` ``` Input: nums = [2,-1,2], k = 3 Output: 3 ``` ### Constraints * 1 \<= nums.length \<= 10^5 * -10^5 \<= nums\[i] \<= 10^5 * 1 \<= k \<= 10^9 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_subarray_with_sum_at_least_k/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_subarray_with_sum_at_least_k/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(n) # Space: O(n) def shortest_subarray(self, nums: list[int], k: int) -> int: n = len(nums) prefix = [0] * (n + 1) for i, num in enumerate(nums): prefix[i + 1] = prefix[i] + num result = n + 1 queue: deque[int] = deque() for j in range(n + 1): while queue and prefix[j] - prefix[queue[0]] >= k: result = min(result, j - queue.popleft()) while queue and prefix[queue[-1]] >= prefix[j]: queue.pop() queue.append(j) return result if result <= n else -1 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Shortest Unsorted Continuous Subarray Source: https://leetcode-py.wisl.dev/problems/shortest-unsorted-continuous-subarray Tested Python solution for LeetCode 581 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 581, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 581 # by problem number lcpy gen -s shortest_unsorted_continuous_subarray # by problem name ``` ## Problem Given an integer array `nums`, you need to find one **continuous subarray** such that if you only sort this subarray in non-decreasing order, then the whole array will be sorted in non-decreasing order. Return *the shortest such subarray and output its length*. ### Examples ``` Input: nums = [2,6,4,8,10,9,15] Output: 5 ``` **Explanation:** You need to sort \[6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. ``` Input: nums = [1,2,3,4] Output: 0 ``` ``` Input: nums = [1] Output: 0 ``` ### Constraints * 1 \<= nums.length \<= 10^4 * -10^5 \<= nums\[i] \<= 10^5 **Follow up:** Can you solve it in `O(n)` time complexity? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_unsorted_continuous_subarray/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_unsorted_continuous_subarray/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def find_unsorted_subarray(self, nums: list[int]) -> int: n = len(nums) end = -2 max_seen = nums[0] for i in range(1, n): if nums[i] < max_seen: end = i else: max_seen = nums[i] if end == -2: return 0 start = 0 min_seen = nums[n - 1] for i in range(n - 2, -1, -1): if nums[i] > min_seen: start = i else: min_seen = nums[i] return end - start + 1 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Shortest Way to Form String Python Solution Source: https://leetcode-py.wisl.dev/problems/shortest-way-to-form-string Tested Python solution for LeetCode 1055 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 1055, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/shortest-way-to-form-string/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1055 # by problem number lcpy gen -s shortest_way_to_form_string # by problem name ``` ## Problem A **subsequence** of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., `"ace"` is a subsequence of `"abcde"` while `"aec"` is not). Given two strings `source` and `target`, return *the minimum number of subsequences of* `source` *such that their concatenation equals* `target`. If the task is impossible, return `-1`. ### Examples ``` Input: source = "abc", target = "abcbc" Output: 2 Explanation: The target "abcbc" can be formed by "abc" and "bc", which are subsequences of source "abc". ``` ``` Input: source = "abc", target = "acdbc" Output: -1 Explanation: The target string cannot be constructed from the subsequences of source string due to the character "d" in target string. ``` ``` Input: source = "xyz", target = "xzyxz" Output: 3 Explanation: The target string can be constructed as follows "xz" + "y" + "xz". ``` ### Constraints * 1 \<= source.length, target.length \<= 1000 * source and target consist of lowercase English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_way_to_form_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_way_to_form_string/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) # Space: O(1) def shortest_way(self, source: str, target: str) -> int: m, n = len(source), len(target) ans = j = 0 while j < n: i, k = 0, j while i < m and k < n: if source[i] == target[k]: k += 1 i += 1 if k == j: return -1 j = k ans += 1 return ans ``` ## Complexity | Time | Space | | --------- | ----- | | O(m \* n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Shortest Word Distance Python Solution Source: https://leetcode-py.wisl.dev/problems/shortest-word-distance Tested Python solution for LeetCode 243 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 243, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/shortest-word-distance/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 243 # by problem number lcpy gen -s shortest_word_distance # by problem name ``` ## Problem Given an array of strings `wordsDict` and two different strings that already exist in the array `word1` and `word2`, return *the shortest distance between these two words in the list*. ### Examples ``` Input: wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "coding", word2 = "practice" Output: 3 ``` ``` Input: wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "makes", word2 = "coding" Output: 1 ``` ### Constraints * `2 <= wordsDict.length <= 3 * 10^4` * `1 <= wordsDict[i].length <= 10` * `wordsDict[i]` consists of lowercase English letters. * `word1` and `word2` are in `wordsDict`. * `word1 != word2` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_word_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_word_distance/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def shortest_distance(self, words_dict: list[str], word1: str, word2: str) -> int: index1 = -1 index2 = -1 shortest = len(words_dict) for i, word in enumerate(words_dict): if word == word1: index1 = i if word == word2: index2 = i if index1 != -1 and index2 != -1: shortest = min(shortest, abs(index1 - index2)) return shortest ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Shortest Word Distance II Python Solution Source: https://leetcode-py.wisl.dev/problems/shortest-word-distance-ii Tested Python solution for LeetCode 244 with 13 pytest cases. Generate a practice environment with lcpy. LeetCode 244, [Medium](/catalog/medium). Topics: [Design](/catalog/topics/design), [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/shortest-word-distance-ii/description/). Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 244 # by problem number lcpy gen -s shortest_word_distance_ii # by problem name ``` ## Problem Design a data structure that will be initialized with a string array, and then it should answer queries of the shortest distance between two different strings from the array. Implement the `WordDistance` class: * `WordDistance(String[] wordsDict)` initializes the object with the strings array `wordsDict`. * `int shortest(String word1, String word2)` returns the shortest distance between `word1` and `word2` in the array `wordsDict`. ### Examples ``` Input ["WordDistance", "shortest", "shortest"] [[["practice", "makes", "perfect", "coding", "makes"]], ["coding", "practice"], ["makes", "coding"]] Output [null, 3, 1] Explanation WordDistance wordDistance = new WordDistance(["practice", "makes", "perfect", "coding", "makes"]); wordDistance.shortest("coding", "practice"); // return 3 wordDistance.shortest("makes", "coding"); // return 1 ``` ### Constraints * `1 <= wordsDict.length <= 3 * 10^4` * `1 <= wordsDict[i].length <= 10` * `wordsDict[i]` consists of lowercase English letters. * `word1` and `word2` are in `wordsDict`. * `word1 != word2` * At most `5000` calls will be made to `shortest`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_word_distance_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_word_distance_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import defaultdict class WordDistance: # Time: O(n) for __init__, O(k + m) per shortest call # Space: O(n) def __init__(self, words_dict: list[str]) -> None: self.indices: defaultdict[str, list[int]] = defaultdict(list) for i, word in enumerate(words_dict): self.indices[word].append(i) def shortest(self, word1: str, word2: str) -> int: positions1 = self.indices[word1] positions2 = self.indices[word2] shortest = 10**9 i = 0 j = 0 while i < len(positions1) and j < len(positions2): shortest = min(shortest, abs(positions1[i] - positions2[j])) if positions1[i] <= positions2[j]: i += 1 else: j += 1 return shortest ``` ## Complexity | Time | Space | | --------------------------------------------- | ----- | | O(n) for **init**, O(k + m) per shortest call | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Shortest Word Distance III Python Solution Source: https://leetcode-py.wisl.dev/problems/shortest-word-distance-iii Tested Python solution for LeetCode 245 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 245, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/shortest-word-distance-iii/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 245 # by problem number lcpy gen -s shortest_word_distance_iii # by problem name ``` ## Problem Given an array of strings `wordsDict` and two strings that already exist in the array `word1` and `word2`, return *the shortest distance between the occurrence of these two words in the list*. **Note** that `word1` and `word2` may be the same. It is guaranteed that they represent **two individual words** in the list. ### Examples ``` Input: wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "makes", word2 = "coding" Output: 1 ``` ``` Input: wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "makes", word2 = "makes" Output: 3 ``` ### Constraints * `1 <= wordsDict.length <= 10^5` * `1 <= wordsDict[i].length <= 10` * `wordsDict[i]` consists of lowercase English letters. * `word1` and `word2` are in `wordsDict`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_word_distance_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shortest_word_distance_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def shortest_word_distance(self, words_dict: list[str], word1: str, word2: str) -> int: n = len(words_dict) ans = n if word1 == word2: prev = -1 for i, w in enumerate(words_dict): if w == word1: if prev != -1: ans = min(ans, i - prev) prev = i else: i = j = -1 for k, w in enumerate(words_dict): if w == word1: i = k if w == word2: j = k if i != -1 and j != -1: ans = min(ans, abs(i - j)) return ans ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Shuffle an Array Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/shuffle-an-array Tested Python solution for LeetCode 384 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 384, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Design](/catalog/topics/design), Randomized. [View on LeetCode](https://leetcode.com/problems/shuffle-an-array/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 384 # by problem number lcpy gen -s shuffle_an_array # by problem name ``` ## Problem Given an integer array `nums`, design an algorithm to randomly shuffle the array. All permutations of the array should be **equally likely** as a result of the shuffling. Implement the `Solution` class: * `Solution(int[] nums)` Initializes the object with the integer array `nums`. * `int[] reset()` Resets the array to its original configuration and returns it. * `int[] shuffle()` Returns a random shuffling of the array. ### Examples ``` Input ["Solution", "shuffle", "reset", "shuffle"] [[[1, 2, 3]], [], [], []] Output [null, [3, 1, 2], [1, 2, 3], [1, 3, 2]] Explanation Solution solution = new Solution([1, 2, 3]); solution.shuffle(); // Shuffle the array [1,2,3] and return its result. // Any permutation of [1,2,3] must be equally likely to be returned. Example: return [3, 1, 2] solution.reset(); // Resets the array back to its original configuration [1,2,3]. Return [1, 2, 3] solution.shuffle(); // Returns the random shuffling of array [1,2,3]. Example: return [1, 3, 2] ``` ### Constraints * `1 <= nums.length <= 50` * `-10^6 <= nums[i] <= 10^6` * All the elements of `nums` are **unique**. * At most `10^4` calls in total will be made to `reset` and `shuffle`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shuffle_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/shuffle_an_array/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import random class Solution: # Time: O(n) for __init__, reset and shuffle # Space: O(n) def __init__(self, nums: list[int]) -> None: self.original = list(nums) self.array = list(nums) def reset(self) -> list[int]: self.array = list(self.original) return list(self.array) def shuffle(self) -> list[int]: shuffled = list(self.array) for i in range(len(shuffled) - 1, 0, -1): j = random.randrange(i + 1) shuffled[i], shuffled[j] = shuffled[j], shuffled[i] return shuffled # Your Solution object will be instantiated and called as such: # obj = Solution(nums) # param_1 = obj.reset() # param_2 = obj.shuffle() ``` ## Complexity | Time | Space | | ------------------------------------ | ----- | | O(n) for **init**, reset and shuffle | O(n) | ## Tags # Shuffle the Array Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/shuffle-the-array Tested Python solution for LeetCode 1470 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 1470, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/shuffle-the-array/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1470 # by problem number lcpy gen -s shuffle_the_array # by problem name ``` ## Problem Given the array `nums` consisting of `2n` elements in the form `[x1,x2,...,xn,y1,y2,...,yn]`. \
Return the array in the form \\[x\1\,y\1\,x\2\,y\2\,...,x\n\,y\n\]\.\
n x n\ integer matrix \board\ where the cells are labeled from \1\ to \n\2\\ in a \\Boustrophedon style\\ starting from the bottom left of the board (i.e. \board\[n - 1]\[0]\) and alternating direction each row.\
\You start on square \1\ of the board. In each move, starting from square \curr\, do the following:\
next\ with a label in the range \\[curr + 1, min(curr + 6, n\2\)]\.
\next\ has a snake or ladder, you \must\ move to the destination of that snake or ladder. Otherwise, you move to \next\.\n\2\\.\A board square on row \r\ and column \c\ has a snake or ladder if \board\[r]\[c] != -1\. The destination of that snake or ladder is \board\[r]\[c]\. Squares \1\ and \n\2\\ are not the starting points of a snake or ladder.\
Note that you only take a snake or ladder at most once per dice roll. If the destination to a snake or ladder is the start of another snake or ladder, you do \not\ follow the subsequent snake or ladder.\
\\[\[-1,4],\[-1,3]]\, and on the first move, your destination square is \2\. You follow the ladder at square \2\ to square \3\, but do \not\ follow the subsequent ladder at square \3\ to square \4\.\Return \the least number of dice rolls required to reach the square\ \n\2\\\. If it is not possible to reach the square, return\ \-1\.\
nums\, move all the even integers at the beginning of the array followed by all the odd integers.\
\Return \any array that satisfies this condition\.\
### Examples ``` Input: nums = [3,1,2,4] Output: [2,4,3,1] Explanation: The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted. ``` ``` Input: nums = [0] Output: [0] ``` ### Constraints * 1 \<= nums.length \<= 5000 * 0 \<= nums\[i] \<= 5000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_array_by_parity/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_array_by_parity/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(n) def sort_array_by_parity(self, nums: list[int]) -> list[int]: result = [num for num in nums if num % 2 == 0] result.extend(num for num in nums if num % 2 == 1) return result ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Sort Array By Parity II Python Solution Source: https://leetcode-py.wisl.dev/problems/sort-array-by-parity-ii Tested Python solution for LeetCode 922 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 922, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/sort-array-by-parity-ii/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 922 # by problem number lcpy gen -s sort_array_by_parity_ii # by problem name ``` ## Problem \Given an array of integers \nums\, half of the integers in \nums\ are \odd\, and the other half are \even\.\
Sort the array so that whenever \nums\[i]\ is odd, \i\ is \odd\, and whenever \nums\[i]\ is even, \i\ is \even\.\
Return \any answer array that satisfies this condition\.\
### Examples ``` Input: nums = [4,2,5,7] Output: [4,5,2,7] Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted. ``` ``` Input: nums = [2,3] Output: [2,3] ``` ### Constraints * 2 \<= nums.length \<= 2 \* 10^4 * nums.length is even. * Half of the integers in nums are even. * 0 \<= nums\[i] \<= 1000 **Follow up:** Could you solve it in-place? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_array_by_parity_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_array_by_parity_ii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def sort_array_by_parity_ii(self, nums: list[int]) -> list[int]: even = 0 odd = 1 while even < len(nums) and odd < len(nums): if nums[even] % 2 == 0: even += 2 elif nums[odd] % 2 == 1: odd += 2 else: nums[even], nums[odd] = nums[odd], nums[even] even += 2 odd += 2 return nums ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags # Sort Characters By Frequency Python Solution Source: https://leetcode-py.wisl.dev/problems/sort-characters-by-frequency Tested Python solution for LeetCode 451 with 14 pytest cases. Generate a practice environment with lcpy. LeetCode 451, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), Bucket Sort, [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/sort-characters-by-frequency/description/). Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 451 # by problem number lcpy gen -s sort_characters_by_frequency # by problem name ``` ## Problem 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. Return *the sorted string*. If there are multiple answers, return *any of them*. ### Examples ``` Input: s = "tree" Output: "eert" 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. ``` ``` Input: s = "cccaaa" Output: "aaaccc" 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. ``` ``` Input: s = "Aabb" Output: "bbAa" Explanation: "bbaA" is also a valid answer, but "Aabb" is incorrect. Note that 'A' and 'a' are treated as two different characters. ``` ### Constraints * `1 <= s.length <= 5 * 10^5` * `s` consists of uppercase and lowercase English letters and digits. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_characters_by_frequency/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_characters_by_frequency/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import Counter class Solution: # Time: O(n) # Space: O(n) def frequency_sort(self, s: str) -> str: counts = Counter(s) buckets: list[list[str]] = [[] for _ in range(len(s) + 1)] for char, freq in counts.items(): buckets[freq].append(char) parts: list[str] = [] for freq in range(len(s), 0, -1): for char in buckets[freq]: parts.append(char * freq) return "".join(parts) ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(n) | ## Tags [NeetCode All](/catalog/neetcode). # Sort Colors Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/sort-colors Tested Python solution for LeetCode 75 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 75, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/sort-colors/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 75 # by problem number lcpy gen -s sort_colors # by problem name ``` ## Problem Given an array `nums` with `n` objects colored red, white, or blue, sort them **in-place** so that objects of the same color are adjacent, with the colors in the order red, white, and blue. We will use the integers `0`, `1`, and `2` to represent the color red, white, and blue, respectively. You must solve this problem without using the library's sort function. ### Examples ``` Input: nums = [2,0,2,1,1,0] Output: [0,0,1,1,2,2] ``` ``` Input: nums = [2,0,1] Output: [0,1,2] ``` ### Constraints * `n == nums.length` * `1 <= n <= 300` * `nums[i]` is either `0`, `1`, or `2`. **Follow up:** Could you come up with a one-pass algorithm using only constant extra space? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_colors/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_colors/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Dutch National Flag Algorithm - partitions array into 3 regions using 2 pointers # Creates: [0s][1s][2s] with left/right boundaries, mid processes unvisited elements # Time: O(n) # Space: O(1) def sort_colors(self, nums: list[int]) -> None: left = mid = 0 right = len(nums) - 1 while mid <= right: if nums[mid] == 0: nums[left], nums[mid] = nums[mid], nums[left] left += 1 mid += 1 elif nums[mid] == 1: mid += 1 else: nums[mid], nums[right] = nums[right], nums[mid] right -= 1 ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Sort List Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/sort-list Tested Python solution for LeetCode 148 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 148, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers), [Divide and Conquer](/catalog/topics/divide-and-conquer), [Sorting](/catalog/topics/sorting), Merge Sort. [View on LeetCode](https://leetcode.com/problems/sort-list/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 148 # by problem number lcpy gen -s sort_list # by problem name ``` ## Problem Given the `head` of a linked list, return *the list after sorting it in ascending order*. ### Examples  ``` Input: head = [4,2,1,3] Output: [1,2,3,4] ```  ``` Input: head = [-1,5,3,4,0] Output: [-1,0,3,4,5] ``` ``` Input: head = [] Output: [] ``` ### Constraints * The number of nodes in the list is in the range \[0, 5 \* 10^4]. * -10^5 \<= Node.val \<= 10^5 **Follow up:** Can you sort the linked list in `O(n logn)` time and `O(1)` memory (i.e. constant space)? ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sort_list/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from leetcode_py import ListNode class Solution: # Time: O(n log n) — bottom-up merge sort, log n passes each O(n) # Space: O(1) — iterative, pointers only def sort_list(self, head: ListNode[int] | None) -> ListNode[int] | None: if not head or not head.next: return head # Find length length = 0 node = head while node: length += 1 node = node.next dummy: ListNode[int] = ListNode[int](0) dummy.next = head size = 1 while size < length: curr = dummy.next tail = dummy while curr: left = curr right = self._split(left, size) curr = self._split(right, size) if right else None tail = self._merge(left, right, tail) size *= 2 return dummy.next @staticmethod def _split(head: ListNode[int] | None, size: int) -> ListNode[int] | None: """Cut after `size` nodes; return the head of the second half.""" for _ in range(size - 1): if head is None or head.next is None: break head = head.next if head is None: return None nxt = head.next head.next = None return nxt @staticmethod def _merge( left: ListNode[int] | None, right: ListNode[int] | None, tail: ListNode[int] ) -> ListNode[int]: """Merge two sorted lists onto tail; return the new tail.""" while left and right: if left.val <= right.val: tail.next = left left = left.next else: tail.next = right right = right.next tail = tail.next tail.next = left if left else right while tail.next: assert tail.next is not None tail = tail.next return tail ``` ## Complexity | Time | Space | | --------------------------------------------------------- | ------------------------------- | | O(n log n) — bottom-up merge sort, log n passes each O(n) | O(1) — iterative, pointers only | ## Tags [Grind](/catalog/grind), [NeetCode All](/catalog/neetcode). # Sort the Jumbled Numbers Python Solution Source: https://leetcode-py.wisl.dev/problems/sort-the-jumbled-numbers Tested Python solution for LeetCode 2191 with 15 pytest cases. Generate a practice environment with lcpy. LeetCode 2191, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/sort-the-jumbled-numbers/description/). Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2191 # by problem number lcpy gen -s sort_the_jumbled_numbers # by problem name ``` ## Problem You are given a \0-indexed\ integer array \mapping\ which represents the mapping rule of a shuffled decimal system. \mapping\[i] = j\ means digit \i\ should be mapped to digit \j\ in this system.
The \mapped value\ of an integer is the new integer obtained by replacing each occurrence of digit \i\ in the integer with \mapping\[i]\ for all \0 \<= i \<= 9\.
You are also given another integer array \nums\. Return \the array \\nums\\ sorted in \non-decreasing\ order based on the \mapped values\ of its elements.\
\\Notes:\\
\nums\ should only be sorted based on their mapped values and \not be replaced\ by them.\
```
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
```
\
```
Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m, n \<= 10
* -100 \<= matrix\[i]\[j] \<= 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m*n)
# Space: O(1)
def spiral_order(self, matrix: list[list[int]]) -> list[int]:
if not matrix or not matrix[0]:
return []
# Check if all rows have same length
cols = len(matrix[0])
for row in matrix:
if len(row) != cols:
raise ValueError("Invalid matrix: all rows must have same length")
result = []
top, bottom = 0, len(matrix) - 1
left, right = 0, cols - 1
while top <= bottom and left <= right:
# Right
for c in range(left, right + 1):
result.append(matrix[top][c])
top += 1
# Down
for r in range(top, bottom + 1):
result.append(matrix[r][right])
right -= 1
# Left (if still valid row)
if top <= bottom:
for c in range(right, left - 1, -1):
result.append(matrix[bottom][c])
bottom -= 1
# Up (if still valid column)
if left <= right:
for r in range(bottom, top - 1, -1):
result.append(matrix[r][left])
left += 1
return result
```
## Complexity
| Time | Space |
| ------- | ----- |
| O(m\*n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Spiral Matrix II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/spiral-matrix-ii
Tested Python solution for LeetCode 59 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 59, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/spiral-matrix-ii/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 59 # by problem number
lcpy gen -s spiral_matrix_ii # by problem name
```
## Problem
Given a positive integer `n`, generate an `n x n` `matrix` filled with elements from `1` to `n^2` in spiral order.
### Examples
\
```
Input: n = 3
Output: [[1,2,3],[8,9,4],[7,6,5]]
```
```
Input: n = 1
Output: [[1]]
```
### Constraints
* 1 \<= n \<= 20
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(1) excluding the output matrix
def generate_matrix(self, n: int) -> list[list[int]]:
matrix = [[0] * n for _ in range(n)]
top, bottom = 0, n - 1
left, right = 0, n - 1
value = 1
while top <= bottom and left <= right:
# Move right along the top row
for col in range(left, right + 1):
matrix[top][col] = value
value += 1
top += 1
# Move down along the right column
for row in range(top, bottom + 1):
matrix[row][right] = value
value += 1
right -= 1
# Move left along the bottom row
if top <= bottom:
for col in range(right, left - 1, -1):
matrix[bottom][col] = value
value += 1
bottom -= 1
# Move up along the left column
if left <= right:
for row in range(bottom, top - 1, -1):
matrix[row][left] = value
value += 1
left += 1
return matrix
```
## Complexity
| Time | Space |
| ------ | -------------------------------- |
| O(n^2) | O(1) excluding the output matrix |
## Tags
[NeetCode All](/catalog/neetcode).
# Spiral Matrix III Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/spiral-matrix-iii
Tested Python solution for LeetCode 885 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 885, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/spiral-matrix-iii/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 885 # by problem number
lcpy gen -s spiral_matrix_iii # by problem name
```
## Problem
You start at the cell \(rStart, cStart)\ of an \rows x cols\ grid facing east. The northwest corner is at the first row and column in the grid, and the southeast corner is at the last row and column.\
\You will walk in a clockwise spiral shape to visit every position in this grid. Whenever you move outside the grid's boundary, we continue our walk outside the grid (but may return to the grid boundary later.). Eventually, we reach all \rows \* cols\ spaces of the grid.\
Return an array of coordinates representing the positions of the grid in the order you visited them.\
### Examples  ``` Input: rows = 5, cols = 6, rStart = 1, cStart = 4 Output: [[1,4],[1,5],[2,5],[2,4],[2,3],[1,3],[0,3],[0,4],[0,5],[3,5],[3,4],[3,3],[3,2],[2,2],[1,2],[0,2],[4,5],[4,4],[4,3],[4,2],[4,1],[3,1],[2,1],[1,1],[0,1],[4,0],[3,0],[2,0],[1,0],[0,0]] ```  ``` Input: rows = 1, cols = 4, rStart = 0, cStart = 0 Output: [[0,0],[0,1],[0,2],[0,3]] ``` ### Constraints * 1 \<= rows, cols \<= 100 * 0 \<= rStart \< rows * 0 \<= cStart \< cols ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix_iii/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(max(rows, cols)^2) # Space: O(1) excluding output def spiral_matrix_iii( self, rows: int, cols: int, r_start: int, c_start: int ) -> list[list[int]]: result = [[r_start, c_start]] r, c, steps, direction = r_start, c_start, 1, 0 directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] while len(result) < rows * cols: for _ in range(2): dr, dc = directions[direction] for _ in range(steps): r, c = r + dr, c + dc if 0 <= r < rows and 0 <= c < cols: result.append([r, c]) direction = (direction + 1) % 4 steps += 1 return result ``` ## Complexity | Time | Space | | -------------------- | --------------------- | | O(max(rows, cols)^2) | O(1) excluding output | ## Tags [NeetCode All](/catalog/neetcode). # Spiral Matrix IV Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/spiral-matrix-iv Tested Python solution for LeetCode 2326 with 21 pytest cases. Generate a practice environment with lcpy. LeetCode 2326, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Linked List](/catalog/topics/linked-list), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/spiral-matrix-iv/description/). Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 2326 # by problem number lcpy gen -s spiral_matrix_iv # by problem name ``` ## Problem You are given two integers \m\ and \n\, which represent the dimensions of a matrix.
You are also given the \head\ of a linked list of integers.
Generate an \m x n\ matrix that contains the integers in the linked list presented in \spiral\ order \(clockwise)\, starting from the \top-left\ of the matrix. If there are remaining empty spaces, fill them with \-1\.
Return \the generated matrix\.
### Examples

```
Input: m = 3, n = 5, head = [3,0,2,6,8,1,7,9,4,2,5,5,0]
Output: [[3,0,2,6,8],[5,0,-1,-1,1],[5,2,4,9,7]]
Explanation: The diagram above shows how the values are printed in the matrix.
Note that the remaining spaces in the matrix are filled with -1.
```

```
Input: m = 1, n = 4, head = [0,1,2]
Output: [[0,1,2,-1]]
Explanation: The diagram above shows how the values are printed from left to right in the matrix.
The last space in the matrix is set to -1.
```
### Constraints
* 1 \<= m, n \<= 10^5
* 1 \<= m \* n \<= 10^5
* The number of nodes in the list is in the range \[1, m \* n].
* 0 \<= Node.val \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix_iv/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/spiral_matrix_iv/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(m * n)
# Space: O(1) extra (output matrix excluded)
def spiral_matrix(self, m: int, n: int, head: ListNode[int] | None) -> list[list[int]]:
grid = [[-1] * n for _ in range(m)]
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
row = col = d = 0
node = head
while node is not None:
grid[row][col] = node.val
node = node.next
if node is None:
break
next_row, next_col = row + directions[d][0], col + directions[d][1]
if not (0 <= next_row < m and 0 <= next_col < n and grid[next_row][next_col] == -1):
d = (d + 1) % 4
next_row, next_col = row + directions[d][0], col + directions[d][1]
row, col = next_row, next_col
return grid
```
## Complexity
| Time | Space |
| --------- | ----------------------------------- |
| O(m \* n) | O(1) extra (output matrix excluded) |
## Tags
[NeetCode All](/catalog/neetcode).
# Split a String Into the Max Number of Unique
Source: https://leetcode-py.wisl.dev/problems/split-a-string-into-the-max-number-of-unique-substrings
Tested Python solution for LeetCode 1593 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1593, [Medium](/catalog/medium). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/split-a-string-into-the-max-number-of-unique-substrings/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1593 # by problem number
lcpy gen -s split_a_string_into_the_max_number_of_unique_substrings # by problem name
```
## Problem
Given a string `s`, return the maximum number of unique substrings that the given string can be split into.
You can split string `s` into any list of **non-empty substrings**, where the concatenation of the substrings forms the original string. However, you must split the substrings such that all of them are **unique**.
A **substring** is a contiguous sequence of characters within a string.
### Examples
```
Input: s = "ababccc"
Output: 5
Explanation: One way to split maximally is ['a', 'b', 'ab', 'c', 'cc']. Splitting like ['a', 'b', 'a', 'b', 'c', 'cc'] is not valid as you have 'a' and 'b' multiple times.
```
```
Input: s = "aba"
Output: 2
Explanation: One way to split maximally is ['a', 'ba'].
```
```
Input: s = "aa"
Output: 1
Explanation: It is impossible to split the string any further.
```
### Constraints
* `1 <= s.length <= 16`
* `s` contains only lower case English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_a_string_into_the_max_number_of_unique_substrings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_a_string_into_the_max_number_of_unique_substrings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * 2^n) worst case, pruned hard by the remaining-suffix bound
# Space: O(n) recursion depth plus the seen-set of at most n pieces
def max_unique_split(self, s: str) -> int:
n = len(s)
seen: set[str] = set()
def dfs(start: int, count: int) -> int:
best = count
for end in range(start + 1, n + 1):
piece = s[start:end]
# Even taking every remaining character as its own split cannot
# beat the best found so far.
if piece in seen or count + 1 + (n - end) <= best:
continue
seen.add(piece)
best = max(best, dfs(end, count + 1))
seen.remove(piece)
return best
return dfs(0, 0)
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------- | ---------------------------------------------------------- |
| O(n \* 2^n) worst case, pruned hard by the remaining-suffix bound | O(n) recursion depth plus the seen-set of at most n pieces |
## Tags
[NeetCode All](/catalog/neetcode).
# Split Array into Consecutive Subsequences
Source: https://leetcode-py.wisl.dev/problems/split-array-into-consecutive-subsequences
Tested Python solution for LeetCode 659 with 32 pytest cases. Generate a practice environment with lcpy.
LeetCode 659, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Greedy](/catalog/topics/greedy), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/split-array-into-consecutive-subsequences/description/).
Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 659 # by problem number
lcpy gen -s split_array_into_consecutive_subsequences # by problem name
```
## Problem
You are given an integer array `nums` that is sorted in non-decreasing order.
Determine if it is possible to split `nums` into one or more subsequences such that both of the following conditions are true:
* Each subsequence is a consecutive increasing sequence (i.e. each integer is exactly one more than the previous integer).
* All subsequences have a length of `3` or more.
Return `true` if you can split `nums` according to the above conditions, or `false` otherwise.
A subsequence of an array is a new array that is formed from the original array by deleting some (can be none) of the elements without disturbing the relative positions of the remaining elements. (i.e., `[1,3,5]` is a subsequence of `[1,2,3,4,5]` while `[1,3,2]` is not).
### Examples
```
Input: nums = [1,2,3,3,4,5]
Output: true
Explanation: nums can be split into the following subsequences:
[1,2,3,3,4,5] --> 1, 2, 3
[1,2,3,3,4,5] --> 3, 4, 5
```
```
Input: nums = [1,2,3,3,4,4,5,5]
Output: true
Explanation: nums can be split into the following subsequences:
[1,2,3,3,4,4,5,5] --> 1, 2, 3, 4, 5
[1,2,3,3,4,4,5,5] --> 3, 4, 5
```
```
Input: nums = [1,2,3,4,4,5]
Output: false
Explanation: It is impossible to split nums into consecutive increasing subsequences of length 3 or more.
```
### Constraints
* `1 <= nums.length <= 10^4`
* `-1000 <= nums[i] <= 1000`
* `nums` is sorted in non-decreasing order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_into_consecutive_subsequences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_into_consecutive_subsequences/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n log n)
# Space: O(n)
def is_possible(self, nums: list[int]) -> bool:
chains: list[tuple[int, int]] = []
for num in nums:
while chains and chains[0][0] < num - 1:
if heapq.heappop(chains)[1] < 3:
return False
if chains and chains[0][0] == num - 1:
_, length = heapq.heappop(chains)
heapq.heappush(chains, (num, length + 1))
else:
heapq.heappush(chains, (num, 1))
return all(length >= 3 for _, length in chains)
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(n) |
## Tags
# Split Array Largest Sum Python Solution
Source: https://leetcode-py.wisl.dev/problems/split-array-largest-sum
Tested Python solution for LeetCode 410 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 410, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming), [Greedy](/catalog/topics/greedy), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/split-array-largest-sum/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 410 # by problem number
lcpy gen -s split_array_largest_sum # by problem name
```
## Problem
Given an integer array `nums` and an integer `k`, split `nums` into `k` non-empty subarrays such that the largest sum of any subarray is **minimized**.
Return *the minimized largest sum of the split*.
A **subarray** is a contiguous part of the array.
### Examples
```
Input: nums = [7,2,5,10,8], k = 2
Output: 18
Explanation: There are four ways to split nums into two subarrays.
The best way is to split it into [7,2,5] and [10,8], where the largest sum among the two subarrays is only 18.
```
```
Input: nums = [1,2,3,4,5], k = 2
Output: 9
Explanation: There are four ways to split nums into two subarrays.
The best way is to split it into [1,2,3] and [4,5], where the largest sum among the two subarrays is only 9.
```
### Constraints
* 1 \<= nums.length \<= 1000
* 0 \<= nums\[i] \<= 10^6
* 1 \<= k \<= min(50, nums.length)
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_largest_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_largest_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * log(sum(nums))) binary search on the answer
# Space: O(1)
def split_array(self, nums: list[int], k: int) -> int:
# Lower bound: a single element must fit. Upper bound: sum of all elements.
low = max(nums)
high = sum(nums)
def count_subarrays(capacity: int) -> int:
"""Minimum subarrays needed so no subarray sum exceeds capacity."""
subarrays = 1
current = 0
for value in nums:
if current + value > capacity:
subarrays += 1
current = value
else:
current += value
return subarrays
# Binary search for smallest capacity that fits within k subarrays.
while low < high:
mid = (low + high) // 2
if count_subarrays(mid) <= k:
high = mid
else:
low = mid + 1
return low
```
## Complexity
| Time | Space |
| -------------------------------------------------- | ----- |
| O(n \* log(sum(nums))) binary search on the answer | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Split Array with Equal Sum Python Solution
Source: https://leetcode-py.wisl.dev/problems/split-array-with-equal-sum
Tested Python solution for LeetCode 548 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 548, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/split-array-with-equal-sum/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 548 # by problem number
lcpy gen -s split_array_with_equal_sum # by problem name
```
## Problem
Given an integer array `nums` of length `n`, return `true` if there is a triplet `(i, j, k)` which satisfies the following conditions:
* `0 < i, i + 1 < j, j + 1 < k < n - 1`
* The sum of subarrays `(0, i - 1)`, `(i + 1, j - 1)`, `(j + 1, k - 1)` and `(k + 1, n - 1)` is equal.
A subarray `(l, r)` represents a slice of the original array starting from the element indexed `l` to the element indexed `r`.
### Examples
```
Input: nums = [1,2,1,2,1,2,1]
Output: true
Explanation:
i = 1, j = 3, k = 5.
sum(0, i - 1) = sum(0, 0) = 1
sum(i + 1, j - 1) = sum(2, 2) = 1
sum(j + 1, k - 1) = sum(4, 4) = 1
sum(k + 1, n - 1) = sum(6, 6) = 1
```
```
Input: nums = [1,2,1,2,1,2,1,2]
Output: false
```
### Constraints
* `n == nums.length`
* `1 <= n <= 2000`
* `-10^6 <= nums[i] <= 10^6`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_with_equal_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_with_equal_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def split_array(self, nums: list[int]) -> bool:
n = len(nums)
prefix = [0] * (n + 1)
for i, value in enumerate(nums):
prefix[i + 1] = prefix[i] + value
for j in range(3, n - 3):
left_sums: set[int] = set()
for i in range(1, j - 1):
if prefix[i] == prefix[j] - prefix[i + 1]:
left_sums.add(prefix[i])
for k in range(j + 2, n - 1):
s3 = prefix[k] - prefix[j + 1]
s4 = prefix[n] - prefix[k + 1]
if s3 == s4 and s3 in left_sums:
return True
return False
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
# Split Array With Same Average Python Solution
Source: https://leetcode-py.wisl.dev/problems/split-array-with-same-average
Tested Python solution for LeetCode 805 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 805, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/split-array-with-same-average/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 805 # by problem number
lcpy gen -s split_array_with_same_average # by problem name
```
## Problem
You are given an integer array `nums`.
You should move each element of `nums` into one of the two arrays `A` and `B` such that `A` and `B` are non-empty, and `average(A) == average(B)`.
Return `true` if it is possible to achieve that and `false` otherwise.
**Note** that for an array `arr`, `average(arr)` is the sum of all the elements of `arr` over the length of `arr`.
### Examples
```
Input: nums = [1,2,3,4,5,6,7,8]
Output: true
Explanation: We can split the array into [1,4,5,8] and [2,3,6,7], and both of them have an average of 4.5.
```
```
Input: nums = [3,1]
Output: false
```
### Constraints
* 1 \<= nums.length \<= 30
* 0 \<= nums\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_with_same_average/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_array_with_same_average/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2 * total_sum) subset-sum over (size, sum) pairs
# Space: O(n * total_sum)
def split_array_same_average(self, nums: list[int]) -> bool:
n = len(nums)
total = sum(nums)
if n == 1:
return False
# avg(A) == avg(B) implies avg(A) == avg(nums); check each size k
# for a subset whose sum equals k * total / n
sums_by_size: list[set[int]] = [set() for _ in range(n + 1)]
sums_by_size[0].add(0)
for num in nums:
for k in range(n - 1, 0, -1):
for s in sums_by_size[k - 1]:
sums_by_size[k].add(s + num)
for k in range(1, n // 2 + 1):
if total * k % n == 0 and total * k // n in sums_by_size[k]:
return True
return False
```
## Complexity
| Time | Space |
| ------------------------------------------------------ | ------------------ |
| O(n^2 \* total\_sum) subset-sum over (size, sum) pairs | O(n \* total\_sum) |
## Tags
[NeetCode All](/catalog/neetcode).
# Split BST Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/split-bst
Tested Python solution for LeetCode 776 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 776, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/split-bst/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 776 # by problem number
lcpy gen -s split_bst # by problem name
```
## Problem
Given the root of a binary search tree (BST) and an integer target, split the tree into two subtrees where one subtree has nodes that are all smaller or equal to the target value, while the other subtree has all nodes that are greater than the target value. It is not necessarily the case that the tree contains a node with the value target.
Additionally, most of the structure of the original tree should remain. Formally, for any child c with parent p in the original tree, if they are both in the same subtree after the split, then node c should still have the parent p.
Return an array of the two roots \[smaller, larger] of the two subtrees.
### Examples

```
Input: root = [4,2,6,1,3,5,7], target = 2
Output: [[2,1],[4,3,6,null,null,5,7]]
```
```
Input: root = [1], target = 1
Output: [[1],[]]
```
### Constraints
* The number of nodes in the tree is in the range \[1, 50].
* 0 \<= Node.val, target \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_bst/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_bst/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(log n) average, O(n) worst case (one node per tree level)
# Space: O(log n) average, O(n) worst case (recursion stack)
def split_bst(self, root: TreeNode[int] | None, target: int) -> list[TreeNode[int] | None]:
if root is None:
return [None, None]
if root.val <= target:
smaller, larger = self.split_bst(root.right, target)
root.right = smaller
return [root, larger]
smaller, larger = self.split_bst(root.left, target)
root.left = larger
return [smaller, root]
```
## Complexity
| Time | Space |
| ----------------------------------------------------------- | --------------------------------------------------- |
| O(log n) average, O(n) worst case (one node per tree level) | O(log n) average, O(n) worst case (recursion stack) |
## Tags
# Split Concatenated Strings Python Solution
Source: https://leetcode-py.wisl.dev/problems/split-concatenated-strings
Tested Python solution for LeetCode 555 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 555, [Medium](/catalog/medium). Topics: [Greedy](/catalog/topics/greedy), [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/split-concatenated-strings/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 555 # by problem number
lcpy gen -s split_concatenated_strings # by problem name
```
## Problem
You are given an array of strings `strs`. You could concatenate these strings together into a loop, where for each string, you could choose to reverse it or not. Among all the possible loops
Return the lexicographically largest string after cutting the loop, which will make the looped string into a regular one.
Specifically, to find the lexicographically largest string, you need to experience two phases:
1. Concatenate all the strings into a loop, where you can reverse some strings or not and connect them in the same order as given.
2. Cut and make one breakpoint in any place of the loop, which will make the looped string into a regular one starting from the character at the cutpoint.
And your job is to find the lexicographically largest one among all the possible regular strings.
### Examples
```
Input: strs = ["abc","xyz"]
Output: "zyxcba"
Explanation: You can get the looped string "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-", where '-' represents the looped status. The answer string came from the fourth looped one, where you could cut from the middle character 'a' and get "zyxcba".
```
```
Input: strs = ["abc"]
Output: "cba"
```
### Constraints
* `1 <= strs.length <= 1000`
* `1 <= strs[i].length <= 1000`
* `1 <= sum(strs[i].length) <= 1000`
* `strs[i]` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_concatenated_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_concatenated_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(total length^2) worst case from cut-point candidates
# Space: O(total length)
def split_looping_string(self, strs: list[str]) -> str:
n = len(strs)
best_parts = [max(s, s[::-1]) for s in strs]
best = ""
for i in range(n):
left = "".join(best_parts[:i])
right = "".join(best_parts[i + 1 :])
for t in (strs[i], strs[i][::-1]):
for k in range(len(t)):
cand = t[k:] + right + left + t[:k]
if cand > best:
best = cand
return best
```
## Complexity
| Time | Space |
| ------------------------------------------------------ | --------------- |
| O(total length^2) worst case from cut-point candidates | O(total length) |
## Tags
[NeetCode All](/catalog/neetcode).
# Split Array into Fibonacci Sequence
Source: https://leetcode-py.wisl.dev/problems/split-into-fibonacci-sequence
Tested Python solution for LeetCode 842 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 842, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/split-into-fibonacci-sequence/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 842 # by problem number
lcpy gen -s split_into_fibonacci_sequence # by problem name
```
## Problem
You are given a string of digits `num`, such as `"123456579"`. We can split it into a Fibonacci-like sequence `[123, 456, 579]`.
Formally, a **Fibonacci-like** sequence is a list `f` of non-negative integers such that:
* `0 <= f[i] < 2^31`, (that is, each integer fits in a **32-bit** signed integer type),
* `f.length >= 3`, and
* `f[i] + f[i + 1] == f[i + 2]` for all `0 <= i < f.length - 2`.
Note that when splitting the string into pieces, each piece must not have extra leading zeroes, except if the piece is the number `0` itself.
Return any Fibonacci-like sequence split from `num`, or return `[]` if it cannot be done.
### Examples
```
Input: num = "1101111"
Output: [11,0,11,11]
Explanation: The output [110, 1, 111] would also be accepted.
```
```
Input: num = "112358130"
Output: []
Explanation: The task is impossible.
```
```
Input: num = "0123"
Output: []
Explanation: Leading zeroes are not allowed, so "01", "2", "3" is not valid.
```
### Constraints
* `1 <= num.length <= 200`
* `num` contains only digits.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_into_fibonacci_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_into_fibonacci_sequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(10^2 * n) piece starts are bounded by 10 digits each
# Space: O(n) for the sequence and recursion
def split_into_fibonacci(self, num: str) -> list[int]:
limit = 2**31
n = len(num)
for i in range(1, min(n, 10) + 1):
if num[0] == "0" and i > 1:
break
first = int(num[:i])
if first >= limit:
break
for j in range(1, min(n - i, 10) + 1):
if num[i] == "0" and j > 1:
break
second = int(num[i : i + j])
if second >= limit:
break
seq = [first, second]
k = i + j
while k < n:
nxt = seq[-1] + seq[-2]
if nxt >= limit or not num.startswith(str(nxt), k):
break
seq.append(nxt)
k += len(str(nxt))
if k == n and len(seq) >= 3:
return seq
return []
```
## Complexity
| Time | Space |
| ------------------------------------------------------- | ----------------------------------- |
| O(10^2 \* n) piece starts are bounded by 10 digits each | O(n) for the sequence and recursion |
## Tags
# Split Linked List in Parts Python Solution
Source: https://leetcode-py.wisl.dev/problems/split-linked-list-in-parts
Tested Python solution for LeetCode 725 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 725, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list). [View on LeetCode](https://leetcode.com/problems/split-linked-list-in-parts/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 725 # by problem number
lcpy gen -s split_linked_list_in_parts # by problem name
```
## Problem
Given the head of a singly linked list and an integer `k`, split the linked list into `k` consecutive linked list parts.
The length of each part should be as equal as possible: no two parts should have a size differing by more than one. This may lead to some parts being null.
The parts should be in the order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal to parts occurring later.
Return an array of the `k` parts.
### Examples
```
Input: head = [1,2,3], k = 5
Output: [[1],[2],[3],[],[]]
Explanation: The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but its string representation as a ListNode is [].
```
```
Input: head = [1,2,3,4,5,6,7,8,9,10], k = 3
Output: [[1,2,3,4],[5,6,7],[8,9,10]]
Explanation: The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.
```
### Constraints
* The number of nodes in the list is in the range \[0, 1000].
* 0 \<= Node.val \<= 1000
* 1 \<= k \<= 50
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_linked_list_in_parts/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/split_linked_list_in_parts/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n + k)
# Space: O(k)
def split_list_to_parts(self, head: ListNode[int] | None, k: int) -> list[ListNode[int] | None]:
length = 0
node = head
while node is not None:
length += 1
node = node.next
width, remainder = divmod(length, k)
parts: list[ListNode[int] | None] = []
node = head
for i in range(k):
parts.append(node)
if node is None:
continue
part_size = width + (1 if i < remainder else 0)
for _ in range(part_size - 1):
if node.next is not None:
node = node.next
next_head = node.next
node.next = None
node = next_head
return parts
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + k) | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Splitting a String Into Descending
Source: https://leetcode-py.wisl.dev/problems/splitting-a-string-into-descending-consecutive-values
Tested Python solution for LeetCode 1849 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1849, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/splitting-a-string-into-descending-consecutive-values/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1849 # by problem number
lcpy gen -s splitting_a_string_into_descending_consecutive_values # by problem name
```
## Problem
You are given a string `s` that consists of only digits.
Check if we can split `s` into **two or more non-empty substrings** such that the **numerical values** of the substrings are in **descending order** and the **difference** between numerical values of every two **adjacent** **substrings** is equal to `1`.
For example, the string `s = "0090089"` can be split into `["0090", "089"]` with numerical values `[90,89]`. The values are in descending order and adjacent values differ by `1`, so this way is valid.
Another example, the string `s = "001"` can be split into `["0", "01"]`, `["00", "1"]`, or `["0", "0", "1"]`. However all the ways are invalid because they have numerical values `[0,1]`, `[0,1]`, and `[0,0,1]` respectively, all of which are not in descending order.
Return `true` if it is possible to split `s` as described above, or `false` otherwise.
A **substring** is a contiguous sequence of characters in a string.
### Examples
```
Input: s = "1234"
Output: false
Explanation: There is no valid way to split s.
```
```
Input: s = "050043"
Output: true
Explanation: s can be split into ["05", "004", "3"] with numerical values [5,4,3].
The values are in descending order with adjacent values differing by 1.
```
```
Input: s = "9080701"
Output: false
Explanation: There is no valid way to split s.
```
### Constraints
* 1 \<= s.length \<= 20
* s only consists of digits.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/splitting_a_string_into_descending_consecutive_values/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/splitting_a_string_into_descending_consecutive_values/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cache
class Solution:
# Time: O(n^2) states explored via DFS over cut positions
# Space: O(n) for recursion depth and memoization
def split_string(self, s: str) -> bool:
n = len(s)
@cache
def dfs(i: int, prev: int) -> bool:
if i == n:
return True
for j in range(i + 1, n + 1):
val = int(s[i:j])
if prev - val == 1 and dfs(j, val):
return True
return False
# The first piece must leave at least one character for a second piece.
return any(dfs(j, int(s[:j])) for j in range(1, n))
```
## Complexity
| Time | Space |
| ------------------------------------------------- | ---------------------------------------- |
| O(n^2) states explored via DFS over cut positions | O(n) for recursion depth and memoization |
## Tags
[NeetCode All](/catalog/neetcode).
# Sqrt(x) Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/sqrtx
Tested Python solution for LeetCode 69 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 69, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/sqrtx/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 69 # by problem number
lcpy gen -s sqrtx # by problem name
```
## Problem
Given a non-negative integer `x`, return *the square root of* `x` *rounded down to the nearest integer*. The returned integer should be **non-negative** as well.
You **must not use** any built-in exponent function or operator.
* For example, do not use `pow(x, 0.5)` in c++ or `x ** 0.5` in python.
### Examples
```
Input: x = 4
Output: 2
```
**Explanation:** The square root of 4 is 2, so we return 2.
```
Input: x = 8
Output: 2
```
**Explanation:** The square root of 8 is 2.82842..., and since we round it down to the nearest integer, 2 is returned.
### Constraints
* 0 \<= x \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sqrtx/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sqrtx/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log x)
# Space: O(1)
def my_sqrt(self, x: int) -> int:
if x < 2:
return x
left = 0
right = x
while left < right:
mid = (left + right) // 2
if mid * mid <= x < (mid + 1) * (mid + 1):
return mid
elif mid * mid > x:
right = mid
else:
left = mid + 1
return left
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(log x) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Squares of a Sorted Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/squares-of-a-sorted-array
Tested Python solution for LeetCode 977 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 977, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/squares-of-a-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 977 # by problem number
lcpy gen -s squares_of_a_sorted_array # by problem name
```
## Problem
Given an integer array `nums` sorted in non-decreasing order, return *an array of the squares of each number* sorted in non-decreasing order.
### Examples
```
Input: nums = [-4,-1,0,3,10]
Output: [0,1,9,16,100]
Explanation: After squaring, the array becomes [16,1,0,9,100].
After sorting, it becomes [0,1,9,16,100].
```
```
Input: nums = [-7,-3,2,3,11]
Output: [4,9,9,49,121]
```
### Constraints
* `1 <= nums.length <= 10^4`
* `-10^4 <= nums[i] <= 10^4`
* `nums` is sorted in non-decreasing order.
**Follow up:** Squaring each element and sorting the new array is very trivial, could you find an `O(n)` solution using a different approach?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/squares_of_a_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/squares_of_a_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def sorted_squares(self, nums: list[int]) -> list[int]:
result: list[int] = [0] * len(nums)
left, right = 0, len(nums) - 1
index = len(nums) - 1
while left <= right:
if abs(nums[left]) > abs(nums[right]):
result[index] = nums[left] * nums[left]
left += 1
else:
result[index] = nums[right] * nums[right]
right -= 1
index -= 1
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Squirrel Simulation Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/squirrel-simulation
Tested Python solution for LeetCode 573 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 573, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math). [View on LeetCode](https://leetcode.com/problems/squirrel-simulation/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 573 # by problem number
lcpy gen -s squirrel_simulation # by problem name
```
## Problem
You are given two integers `height` and `width` representing a garden of size `height x width`. You are also given:
* an array `tree` where `tree = [tree_r, tree_c]` is the position of the tree in the garden,
* an array `squirrel` where `squirrel = [squirrel_r, squirrel_c]` is the position of the squirrel in the garden,
* and an array `nuts` where `nuts[i] = [nut_i_r, nut_i_c]` is the position of the `i^th` nut in the garden.
The squirrel can only take at most one nut at one time and can move in four directions: up, down, left, and right, to the adjacent cell.
Return *the **minimal distance** for the squirrel to collect all the nuts and put them under the tree one by one*.
The **distance** is the number of moves.
### Examples

```
Input: height = 5, width = 7, tree = [2,2], squirrel = [4,4], nuts = [[3,0], [2,5]]
Output: 12
```
**Explanation:** The squirrel should go to the nut at \[2, 5] first to achieve a minimal distance.

```
Input: height = 1, width = 3, tree = [0,1], squirrel = [0,0], nuts = [[0,2]]
Output: 3
```
### Constraints
* `1 <= height, width <= 100`
* `tree.length == 2`
* `squirrel.length == 2`
* `1 <= nuts.length <= 5000`
* `nuts[i].length == 2`
* `0 <= tree_r, squirrel_r, nut_i_r <= height`
* `0 <= tree_c, squirrel_c, nut_i_c <= width`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/squirrel_simulation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/squirrel_simulation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def min_distance(
self, height: int, width: int, tree: list[int], squirrel: list[int], nuts: list[list[int]]
) -> int:
tr, tc = tree
sr, sc = squirrel
to_tree = [abs(r - tr) + abs(c - tc) for r, c in nuts]
total = 2 * sum(to_tree)
return min(
total - a + abs(r - sr) + abs(c - sc) for a, (r, c) in zip(to_tree, nuts, strict=True)
)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Stamping The Sequence Python Solution
Source: https://leetcode-py.wisl.dev/problems/stamping-the-sequence
Tested Python solution for LeetCode 936 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 936, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy), [Queue](/catalog/topics/queue). [View on LeetCode](https://leetcode.com/problems/stamping-the-sequence/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 936 # by problem number
lcpy gen -s stamping_the_sequence # by problem name
```
## Problem
You are given two strings `stamp` and `target`. Initially, there is a string `s` of length `target.length` with all `s[i] == '?'`.
In one turn, you can place `stamp` over `s` and replace every letter in the `s` with the corresponding letter from `stamp`.
* For example, if `stamp = "abc"` and `target = "abcba"`, then `s` is `"?????"` initially. In one turn you can:
* place `stamp` at index `0` of `s` to obtain `"abc??"`,
* place `stamp` at index `1` of `s` to obtain `"?abc?"`, or
* place `stamp` at index `2` of `s` to obtain `"??abc"`.
Note that `stamp` must be fully contained in the boundaries of `s` in order to stamp (i.e., you cannot place `stamp` at index `3` of `s`).
We want to convert `s` to `target` using **at most** `10 * target.length` turns.
Return *an array of the index of the left-most letter being stamped at each turn*. If we cannot obtain `target` from `s` within `10 * target.length` turns, return an empty array.
### Examples
```
Input: stamp = "abc", target = "ababc"
Output: [0,2]
Explanation: Initially s = "?????".
- Place stamp at index 0 to get "abc??".
- Place stamp at index 2 to get "ababc".
[1,0,2] would also be accepted as an answer, as well as some other answers.
```
```
Input: stamp = "abca", target = "aabcaca"
Output: [3,0,1]
Explanation: Initially s = "???????".
- Place stamp at index 3 to get "???abca".
- Place stamp at index 0 to get "abcabca".
- Place stamp at index 1 to get "aabcaca".
```
### Constraints
* `1 <= stamp.length <= target.length <= 1000`
* `stamp` and `target` consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stamping_the_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stamping_the_sequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2 * m) worst case, where n = len(target) and m = len(stamp); each
# stamp erases at least one letter, so there are at most n stamps per pass.
# Space: O(n) for the working copy of target.
def moves_to_stamp(self, stamp: str, target: str) -> list[int]:
chars = list(target)
stamp_len = len(stamp)
target_len = len(chars)
moves: list[int] = []
done = 0
# [left, right) is the region still holding letters from target; every
# useful stamp window must intersect it, otherwise it only writes over '?'.
left, right = 0, target_len
while done < target_len:
placed_at = -1
low = max(0, left - stamp_len + 1)
high = min(right, target_len - stamp_len + 1)
for start in range(low, high):
covered = 0
for offset, char in enumerate(stamp):
current = chars[start + offset]
if current == "?":
continue
if current != char:
break
covered += 1
else:
if covered:
placed_at = start
break
if placed_at < 0:
return []
for offset in range(stamp_len):
if chars[placed_at + offset] != "?":
chars[placed_at + offset] = "?"
done += 1
moves.append(placed_at)
while left < target_len and chars[left] == "?":
left += 1
while right > left and chars[right - 1] == "?":
right -= 1
moves.reverse()
return moves
```
## Complexity
| Time | Space |
| ---------------------------------------------------------------------- | ------------------------------------ |
| O(n^2 \* m) worst case, where n = len(target) and m = len(stamp); each | O(n) for the working copy of target. |
## Tags
# Step-By-Step Directions From a Binary Tree
Source: https://leetcode-py.wisl.dev/problems/step-by-step-directions-from-a-binary-tree-node-to-another
Tested Python solution for LeetCode 2096 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2096, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree), Binary Lifting, Lowest Common Ancestor. [View on LeetCode](https://leetcode.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2096 # by problem number
lcpy gen -s step_by_step_directions_from_a_binary_tree_node_to_another # by problem name
```
## Problem
You are given the `root` of a binary tree with `n` nodes. Each node is uniquely assigned a value from `1` to `n`. You are also given an integer `startValue` representing the value of the start node `s`, and a different integer `destValue` representing the value of the destination node `t`.
Find the shortest path starting from node `s` and ending at node `t`. Generate step-by-step directions of such path as a string consisting of only the uppercase letters `'L'`, `'R'`, and `'U'`. Each letter indicates a specific direction:
* `'L'` means to go from a node to its **left child** node.
* `'R'` means to go from a node to its **right child** node.
* `'U'` means to go from a node to its **parent** node.
Return the step-by-step directions of the shortest path from node `s` to node `t`.
### Examples

```
Input: root = [5,1,2,3,null,6,4], startValue = 3, destValue = 6
Output: "UURL"
Explanation: The shortest path is: 3 -> 1 -> 5 -> 2 -> 6.
```

```
Input: root = [2,1], startValue = 2, destValue = 1
Output: "L"
Explanation: The shortest path is: 2 -> 1.
```
### Constraints
* The number of nodes in the tree is n
* 2 \<= n \<= 10^5
* 1 \<= Node.val \<= n
* All the values in the tree are unique
* 1 \<= startValue, destValue \<= n
* startValue != destValue
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/step_by_step_directions_from_a_binary_tree_node_to_another/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/step_by_step_directions_from_a_binary_tree_node_to_another/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def get_directions(self, root: TreeNode[int] | None, start_value: int, dest_value: int) -> str:
def find(node: TreeNode[int] | None, target: int, path: list[str]) -> list[str] | None:
if node is None:
return None
if node.val == target:
return list(path)
path.append("L")
found = find(node.left, target, path)
if found is not None:
return found
path[-1] = "R"
found = find(node.right, target, path)
if found is not None:
return found
path.pop()
return None
if root is None:
return ""
start_path = find(root, start_value, [])
dest_path = find(root, dest_value, [])
if start_path is None or dest_path is None:
return ""
shared = 0
while (
shared < len(start_path)
and shared < len(dest_path)
and start_path[shared] == dest_path[shared]
):
shared += 1
return "U" * (len(start_path) - shared) + "".join(dest_path[shared:])
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Stepping Numbers Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/stepping-numbers
Tested Python solution for LeetCode 1215 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 1215, [Medium](/catalog/medium). Topics: [Breadth-First Search](/catalog/topics/breadth-first-search), [Math](/catalog/topics/math), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/stepping-numbers/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1215 # by problem number
lcpy gen -s stepping_numbers # by problem name
```
## Problem
A **stepping number** is an integer such that all of its adjacent digits have an absolute difference of exactly `1`.
* For example, `321` is a **stepping number** while `421` is not.
Given two integers `low` and `high`, return *a sorted list of all the **stepping numbers** in the inclusive range* `[low, high]`.
### Examples
```
Input: low = 0, high = 21
Output: [0,1,2,3,4,5,6,7,8,9,10,12,21]
```
```
Input: low = 10, high = 15
Output: [10,12]
```
### Constraints
* `0 <= low <= high <= 2 * 10^9`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stepping_numbers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stepping_numbers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(2^log(high)) - at most ~10k stepping numbers below 2 * 10^9
# Space: O(2^log(high)) for the queue
def count_stepping_numbers(self, low: int, high: int) -> list[int]:
ans: list[int] = []
if low == 0:
ans.append(0)
q: deque[int] = deque(range(1, 10))
while q:
v = q.popleft()
if v > high:
break
if v >= low:
ans.append(v)
last = v % 10
if last > 0:
q.append(v * 10 + last - 1)
if last < 9:
q.append(v * 10 + last + 1)
return ans
```
## Complexity
| Time | Space |
| --------------------------------------------------------------- | ---------------------------- |
| O(2^log(high)) - at most \~10k stepping numbers below 2 \* 10^9 | O(2^log(high)) for the queue |
## Tags
# Stickers to Spell Word Python Solution
Source: https://leetcode-py.wisl.dev/problems/stickers-to-spell-word
Tested Python solution for LeetCode 691 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 691, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), [Bitmask](/catalog/topics/bitmask). [View on LeetCode](https://leetcode.com/problems/stickers-to-spell-word/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 691 # by problem number
lcpy gen -s stickers_to_spell_word # by problem name
```
## Problem
We are given `n` different types of stickers. Each sticker has a lowercase English word on it.
You would like to spell out the given string `target` by cutting individual letters from your collection of stickers and rearranging them. You can use each sticker more than once if you want, and you have infinite quantities of each sticker.
Return the minimum number of stickers that you need to spell out `target`. If the task is impossible, return `-1`.
Note: In all test cases, all words were chosen randomly from the 1000 most common US English words, and target was chosen as a concatenation of two random words.
### Examples
```
Input: stickers = ["with","example","science"], target = "thehat"
Output: 3
Explanation: We can use 2 "with" stickers, and 1 "example" sticker.
After cutting and rearrange the letters of those stickers, we can form the target "thehat".
Also, this is the minimum number of stickers necessary to form the target string.
```
```
Input: stickers = ["notice","possible"], target = "basicbasic"
Output: -1
Explanation: We cannot form the target "basicbasic" from cutting letters from the given stickers.
```
### Constraints
* n == stickers.length
* 1 \<= n \<= 50
* 1 \<= stickers\[i].length \<= 10
* 1 \<= target.length \<= 15
* stickers\[i] and target consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stickers_to_spell_word/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stickers_to_spell_word/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cache
class Solution:
# Time: O(2^m * n * m) where m = len(target), n = len(stickers)
# Space: O(2^m)
def min_stickers(self, stickers: list[str], target: str) -> int:
m = len(target)
full = (1 << m) - 1
sticker_counts: list[list[int]] = []
for sticker in stickers:
counts = [0] * 26
for ch in sticker:
counts[ord(ch) - ord("a")] += 1
sticker_counts.append(counts)
@cache
def dp(mask: int) -> int:
if mask == full:
return 0
# A usable sticker covers at least one letter, so m is an upper bound
best = m + 1
for counts in sticker_counts:
remaining = counts[:]
new_mask = mask
for i in range(m):
pos = ord(target[i]) - ord("a")
if not mask >> i & 1 and remaining[pos]:
remaining[pos] -= 1
new_mask |= 1 << i
if new_mask != mask:
best = min(best, 1 + dp(new_mask))
return best
result = dp(0)
return result if result <= m else -1
```
## Complexity
| Time | Space |
| --------------------------------------------------------- | ------ |
| O(2^m \* n \* m) where m = len(target), n = len(stickers) | O(2^m) |
## Tags
[NeetCode All](/catalog/neetcode).
# Stone Game Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/stone-game
Tested Python solution for LeetCode 877 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 877, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/stone-game/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 877 # by problem number
lcpy gen -s stone_game # by problem name
```
## Problem
Alice and Bob play a game with piles of stones. There are an **even** number of piles arranged in a row, and each pile has a **positive** integer number of stones `piles[i]`.
The objective of the game is to end with the most stones. The **total** number of stones across all the piles is **odd**, so there are no ties.
Alice and Bob take turns, with **Alice starting first**. Each turn, a player takes the entire pile of stones either from the **beginning** or from the **end** of the row. This continues until there are no more piles left, at which point the person with the **most stones wins**.
Assuming Alice and Bob play optimally, return `true` if Alice wins the game, or `false` if Bob wins.
### Examples
```
Input: piles = [5,3,4,5]
Output: true
Explanation:
Alice starts first, and can only take the first 5 or the last 5.
Say she takes the first 5, so that the row becomes [3, 4, 5].
If Bob takes 3, then the board is [4, 5], and Alice takes 5 to win with 10 points.
If Bob takes the last 5, then the board is [3, 4], and Alice takes 4 to win with 9 points.
This demonstrated that taking the first 5 was a winning move for Alice, so we return true.
```
```
Input: piles = [3,7,2,3]
Output: true
```
### Constraints
* 2 \<= piles.length \<= 500
* `piles.length` is even.
* 1 \<= piles\[i] \<= 500
* `sum(piles[i])` is odd.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stone_game/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stone_game/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def stone_game(self, piles: list[int]) -> bool:
n = len(piles)
# dp[i][j] = max net advantage current player can secure from piles[i..j]
dp = [[0] * n for _ in range(n)]
for i in range(n):
dp[i][i] = piles[i]
for length in range(2, n + 1):
for i in range(n - length + 1):
j = i + length - 1
pick_left = piles[i] - dp[i + 1][j]
pick_right = piles[j] - dp[i][j - 1]
dp[i][j] = max(pick_left, pick_right)
return dp[0][n - 1] > 0
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Stone Game II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/stone-game-ii
Tested Python solution for LeetCode 1140 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 1140, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Prefix Sum](/catalog/topics/prefix-sum), [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/stone-game-ii/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1140 # by problem number
lcpy gen -s stone_game_ii # by problem name
```
## Problem
Alice and Bob continue their games with piles of stones. There are a number of piles **arranged in a row**, and each pile has a positive integer number of stones `piles[i]`. The objective of the game is to end with the most stones.
Alice and Bob take turns, with Alice starting first.
On each player's turn, that player can take **all the stones** in the **first** `X` remaining piles, where `1 <= X <= 2M`. Then, we set `M = max(M, X)`. Initially, M = 1.
The game continues until all the stones have been taken.
Assuming Alice and Bob play optimally, return the maximum number of stones Alice can get.
### Examples
```
Input: piles = [2,7,9,4,4]
Output: 10
Explanation:
If Alice takes one pile at the beginning, Bob takes two piles, then Alice takes 2 piles again. Alice can get 2 + 4 + 4 = 10 stones in total.
If Alice takes two piles at the beginning, then Bob can take all three piles left. In this case, Alice get 2 + 7 = 9 stones in total.
So we return 10 since it's larger.
```
```
Input: piles = [1,2,3,4,5,100]
Output: 104
```
### Constraints
* `1 <= piles.length <= 100`
* `1 <= piles[i] <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stone_game_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stone_game_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^3) — n start indexes, n M values, up to 2M=2n X picks
# Space: O(n^2) memo
def stone_game_ii(self, piles: list[int]) -> int:
n = len(piles)
# suffix[i] = total stones in piles[i:]; lets the current player value
# a move as suffix[i] - opponent_best_from_remaining.
suffix = [0] * (n + 1)
for i in range(n - 1, -1, -1):
suffix[i] = suffix[i + 1] + piles[i]
memo: dict[tuple[int, int], int] = {}
def best_from(i: int, m: int) -> int:
# Max stones the player to move can collect from piles[i:] with bound M=m.
if i >= n:
return 0
# Can take all remaining piles in one move.
if i + 2 * m >= n:
return suffix[i]
if (i, m) in memo:
return memo[(i, m)]
best = 0
for x in range(1, 2 * m + 1):
if i + x > n:
break
taken = suffix[i] - suffix[i + x]
opponent = best_from(i + x, max(m, x))
best = max(best, taken + (suffix[i + x] - opponent))
memo[(i, m)] = best
return best
return best_from(0, 1)
```
## Complexity
| Time | Space |
| --------------------------------------------------------- | ----------- |
| O(n^3) — n start indexes, n M values, up to 2M=2n X picks | O(n^2) memo |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Stone Game III Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/stone-game-iii
Tested Python solution for LeetCode 1406 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1406, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Game Theory](/catalog/topics/game-theory). [View on LeetCode](https://leetcode.com/problems/stone-game-iii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1406 # by problem number
lcpy gen -s stone_game_iii # by problem name
```
## Problem
Alice and Bob continue their games with piles of stones. There are several stones **arranged in a row**, and each stone has an associated value which is an integer given in the array `stoneValue`.
Alice and Bob take turns, with Alice starting first. On each player's turn, that player can take `1`, `2`, or `3` stones from the **first** remaining stones in the row.
The score of each player is the sum of the values of the stones taken. The score of each player is `0` initially.
The objective of the game is to end with the highest score, and the winner is the player with the highest score and there could be a tie. The game continues until all the stones have been taken.
Assume Alice and Bob **play optimally**.
Return `"Alice"` if Alice will win, `"Bob"` if Bob will win, or `"Tie"` if they will end the game with the same score.
### Examples
```
Input: stoneValue = [1,2,3,7]
Output: "Bob"
Explanation: Alice will always lose. Her best move will be to take three piles and the score become 6. Now the score of Bob is 7 and Bob wins.
```
```
Input: stoneValue = [1,2,3,-9]
Output: "Alice"
Explanation: Alice must choose all the three piles at the first move to win and leave Bob with negative score.
```
```
Input: stoneValue = [1,2,3,6]
Output: "Tie"
Explanation: Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise she will lose.
```
### Constraints
* `1 <= stoneValue.length <= 5 * 10^4`
* `-1000 <= stoneValue[i] <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stone_game_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/stone_game_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def stone_game_iii(self, stone_value: list[int]) -> str:
n = len(stone_value)
# dp[i] = best score advantage the player to move can build over the
# opponent from stone_value[i:] (positive => current player leads).
dp = [0] * (n + 1)
for i in range(n - 1, -1, -1):
best = -(10**18)
taken = 0
for x in range(i, min(i + 3, n)):
taken += stone_value[x]
# Current pockets `taken`, then opponent enjoys dp[x + 1].
best = max(best, taken - dp[x + 1])
dp[i] = best
if dp[0] > 0:
return "Alice"
if dp[0] < 0:
return "Bob"
return "Tie"
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Strange Printer Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/strange-printer
Tested Python solution for LeetCode 664 with 26 pytest cases. Generate a practice environment with lcpy.
LeetCode 664, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/strange-printer/description/).
Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 664 # by problem number
lcpy gen -s strange_printer # by problem name
```
## Problem
There is a strange printer with the following two special properties:
* The printer can only print a sequence of **the same character** each time.
* At each turn, the printer can print new characters starting from and ending at any place and will cover the original existing characters.
Given a string `s`, return *the minimum number of turns the printer needed to print it*.
### Examples
```
Input: s = "aaabbb"
Output: 2
Explanation: Print "aaa" first and then print "bbb".
```
```
Input: s = "aba"
Output: 2
Explanation: Print "aaa" first and then print "b" from the second place of the string, which will cover the existing character 'a'.
```
### Constraints
* `1 <= s.length <= 100`
* `s` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strange_printer/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strange_printer/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^3)
# Space: O(n^2)
def strange_printer(self, s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
dp[i][i] = 1
for j in range(i + 1, n):
best = dp[i][j - 1] + 1
for k in range(i, j):
if s[k] == s[j]:
mid = dp[k + 1][j - 1] if k + 1 <= j - 1 else 0
best = min(best, dp[i][k] + mid)
dp[i][j] = best
return dp[0][n - 1]
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^3) | O(n^2) |
## Tags
# String Compression Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/string-compression
Tested Python solution for LeetCode 443 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 443, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/string-compression/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 443 # by problem number
lcpy gen -s string_compression # by problem name
```
## Problem
Given an array of characters `chars`, compress it using the following algorithm:
Begin with an empty string `s`. For each group of **consecutive repeating characters** in `chars`:
* If the group's length is `1`, append the character to `s`.
* Otherwise, append the character followed by the group's length.
The compressed string `s` **should not be returned separately**, but instead, be stored **in the input character array `chars`**. Note that group lengths that are `10` or longer will be split into multiple characters in `chars`.
After you are done **modifying the input array,** return *the new length of the array*.
You must write an algorithm that uses only constant extra space.
**Note:** The characters in the array beyond the returned length do not matter and should be ignored.
### Examples
```
Input: chars = ["a","a","b","b","c","c","c"]
Output: 6
Explanation: The groups are "aa", "bb", and "ccc". This compresses to "a2b2c3".
After modifying the input array in-place, the first 6 characters of chars should be ["a","2","b","2","c","3"].
```
```
Input: chars = ["a"]
Output: 1
Explanation: The only group is "a", which remains uncompressed since it is a single character.
After modifying the input array in-place, the first character of chars should be ["a"].
```
```
Input: chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
Output: 4
Explanation: The groups are "a" and "bbbbbbbbbbbb". This compresses to "ab12".
After modifying the input array in-place, the first 4 characters of chars should be ["a","b","1","2"].
```
### Constraints
* `1 <= chars.length <= 2000`
* `chars[i]` is a lowercase English letter, uppercase English letter, digit, or symbol.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_compression/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_compression/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def compress(self, chars: list[str]) -> int:
write = 0
read = 0
n = len(chars)
while read < n:
ch = chars[read]
run_start = read
while read < n and chars[read] == ch:
read += 1
run_length = read - run_start
chars[write] = ch
write += 1
if run_length > 1:
for digit in str(run_length):
chars[write] = digit
write += 1
return write
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# String Compression II Python Solution
Source: https://leetcode-py.wisl.dev/problems/string-compression-ii
Tested Python solution for LeetCode 1531 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1531, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/string-compression-ii/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1531 # by problem number
lcpy gen -s string_compression_ii # by problem name
```
## Problem
\Run-length](http://en.wikipedia.org/wiki/Run-length_encoding">Run-length) encoding\ is a string compression method that works by replacing consecutive identical characters (repeated 2 or more times) with the concatenation of the character and the number marking the count of the characters (length of the run). For example, to compress the string \"aabccc"\ we replace \"aa"\ by \"a2"\ and replace \"ccc"\ by \"c3"\. Thus the compressed string becomes \"a2bc3"\.
Notice that in this problem, we are not adding \'1'\ after single characters.
Given a string \s\ and an integer \k\. You need to delete \at most\ \k\ characters from \s\ such that the run-length encoded version of \s\ has minimum length.
Find the \minimum length of the run-length encoded version of \\s\\ after deleting at most \\k\\ characters\.
### Examples
```
Input: s = "aaabcccd", k = 2
Output: 4
Explanation: Compressing s without deleting anything will give us "a3bc3d" of length 6. Deleting any of the characters 'a' or 'c' would at most decrease the length of the compressed string to 5, for instance delete 2 'a' then we will have s = "abcccd" which compressed is abc3d. Therefore, the optimal way is to delete 'b' and 'd', then the compressed version of s will be "a3c3" of length 4.
```
```
Input: s = "aabbaa", k = 2
Output: 2
Explanation: If we delete both 'b' characters, the resulting compressed string would be "a4" of length 2.
```
```
Input: s = "aaaaaaaaaaa", k = 0
Output: 3
Explanation: Since k is zero, we cannot delete anything. The compressed string is "a11" of length 3.
```
### Constraints
* `1 <= s.length <= 100`
* `0 <= k <= s.length`
* `s` contains only lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_compression_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_compression_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from functools import cache
class Solution:
# Time: O(n^2 * k)
# Space: O(n^2 * k)
def get_length_of_optimal_compression(self, s: str, k: int) -> int:
n = len(s)
@cache
def dp(i: int, remaining: int) -> int:
if remaining < 0:
return n + 1
if i >= n or n - i <= remaining:
return 0
best = dp(i + 1, remaining - 1)
count = 0
for j in range(i, n):
if s[j] == s[i]:
count += 1
cost = 1 if count == 1 else 1 + len(str(count))
deleted = j - i + 1 - count
best = min(best, cost + dp(j + 1, remaining - deleted))
return best
return dp(0, k)
```
## Complexity
| Time | Space |
| ----------- | ----------- |
| O(n^2 \* k) | O(n^2 \* k) |
## Tags
[NeetCode All](/catalog/neetcode).
# String Matching in an Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/string-matching-in-an-array
Tested Python solution for LeetCode 1408 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 1408, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [String Matching](/catalog/topics/string-matching). [View on LeetCode](https://leetcode.com/problems/string-matching-in-an-array/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1408 # by problem number
lcpy gen -s string_matching_in_an_array # by problem name
```
## Problem
Given an array of string `words`, return all strings in `words` that are a substring of another word. You can return the answer in **any order**.
### Examples
```
Input: words = ["mass","as","hero","superhero"]
Output: ["as","hero"]
Explanation: "as" is substring of "mass" and "hero" is substring of "superhero".
["hero","as"] is also a valid answer.
```
```
Input: words = ["leetcode","et","code"]
Output: ["et","code"]
Explanation: "et", "code" are substring of "leetcode".
```
```
Input: words = ["blue","green","bu"]
Output: []
Explanation: No string of words is substring of another string.
```
### Constraints
* `1 <= words.length <= 100`
* `1 <= words[i].length <= 30`
* `words[i]` contains only lowercase English letters.
* All the strings of `words` are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_matching_in_an_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_matching_in_an_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2 * m) where n = len(words), m = max word length
# Space: O(1) excluding the output list
def string_matching(self, words: list[str]) -> list[str]:
result: list[str] = []
for i, word in enumerate(words):
for j, other in enumerate(words):
if i != j and word in other:
result.append(word)
break
return result
```
## Complexity
| Time | Space |
| ----------------------------------------------------- | ------------------------------ |
| O(n^2 \* m) where n = len(words), m = max word length | O(1) excluding the output list |
## Tags
[NeetCode All](/catalog/neetcode).
# String to Integer (atoi) Python Solution
Source: https://leetcode-py.wisl.dev/problems/string-to-integer-atoi
Tested Python solution for LeetCode 8 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 8, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/string-to-integer-atoi/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 8 # by problem number
lcpy gen -s string_to_integer_atoi # by problem name
```
## Problem
Implement the `my_atoi(string s)` function, which converts a string to a 32-bit signed integer.
The algorithm for `my_atoi(string s)` is as follows:
1. **Whitespace**: Ignore any leading whitespace (` `).
2. **Signedness**: Determine the sign by checking if the next character is `-` or `+`, assuming positivity if neither present.
3. **Conversion**: Read the integer by skipping leading zeros until a non-digit character is encountered or the end of the string is reached. If no digits were read, then the result is 0.
4. **Rounding**: If the integer is out of the 32-bit signed integer range `[-2^31, 2^31 - 1]`, then round the integer to remain in the range. Specifically, integers less than `-2^31` should be rounded to `-2^31`, and integers greater than `2^31 - 1` should be rounded to `2^31 - 1`.
Return the integer as the final result.
### Examples
```
Input: s = "42"
Output: 42
```
**Explanation:**
```
The underlined characters are what is read in and the caret is the current reader position.
Step 1: "42" (no characters read because there is no leading whitespace)
^
Step 2: "42" (no characters read because there is neither a '-' nor '+')
^
Step 3: "42" ("42" is read in)
^
```
```
Input: s = " -042"
Output: -42
```
**Explanation:**
```
Step 1: " -042" (leading whitespace is read and ignored)
^
Step 2: " -042" ('-' is read, so the result should be negative)
^
Step 3: " -042" ("042" is read in, leading zeros ignored in the result)
^
```
```
Input: s = "1337c0d3"
Output: 1337
```
**Explanation:**
```
Step 1: "1337c0d3" (no characters read because there is no leading whitespace)
^
Step 2: "1337c0d3" (no characters read because there is neither a '-' nor '+')
^
Step 3: "1337c0d3" ("1337" is read in; reading stops because the next character is a non-digit)
^
```
```
Input: s = "0-1"
Output: 0
```
**Explanation:**
```
Step 1: "0-1" (no characters read because there is no leading whitespace)
^
Step 2: "0-1" (no characters read because there is neither a '-' nor '+')
^
Step 3: "0-1" ("0" is read in; reading stops because the next character is a non-digit)
^
```
```
Input: s = "words and 987"
Output: 0
```
**Explanation:** Reading stops at the first non-digit character 'w'.
### Constraints
* `0 <= s.length <= 200`
* `s` consists of English letters (lower-case and upper-case), digits (0-9), ` `, `+`, `-`, and `.`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_to_integer_atoi/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_to_integer_atoi/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def my_atoi(self, s: str) -> int:
i = 0
n = len(s)
# Skip whitespace
while i < n and s[i] == " ":
i += 1
if i == n:
return 0
# Check sign
sign = 1
if s[i] in {"+", "-"}:
sign = -1 if s[i] == "-" else 1
i += 1
# Convert digits
result = 0
while i < n and s[i].isdigit():
result = result * 10 + int(s[i])
i += 1
result *= sign
# Clamp to 32-bit range
return max(-(2**31), min(2**31 - 1, result))
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind).
# String Without AAA or BBB Python Solution
Source: https://leetcode-py.wisl.dev/problems/string-without-aaa-or-bbb
Tested Python solution for LeetCode 984 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 984, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/string-without-aaa-or-bbb/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 984 # by problem number
lcpy gen -s string_without_aaa_or_bbb # by problem name
```
## Problem
Given two integers `a` and `b`, return **any** string `s` such that:
* `s` has length `a + b` and contains exactly `a` `'a'` letters, and exactly `b` `'b'` letters,
* The substring `'aaa'` does not occur in `s`, and
* The substring `'bbb'` does not occur in `s`.
### Examples
```
Input: a = 1, b = 2
Output: "abb"
Explanation: "abb", "bab" and "bba" are all correct answers.
```
```
Input: a = 4, b = 1
Output: "aabaa"
```
### Constraints
* `0 <= a, b <= 100`
* It is guaranteed such an `s` exists for the given `a` and `b`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_without_aaa_or_bbb/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/string_without_aaa_or_bbb/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(a + b)
# Space: O(a + b)
def str_without3a3b(self, a: int, b: int) -> str:
result: list[str] = []
while a > 0 or b > 0:
# Two identical letters in a row: the other letter is forced.
# Otherwise extend with the letter that is still more plentiful
forced = len(result) >= 2 and result[-1] == result[-2]
write_a = result[-1] == "b" if forced else a >= b
if write_a:
result.append("a")
a -= 1
else:
result.append("b")
b -= 1
return "".join(result)
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(a + b) | O(a + b) |
## Tags
# Strobogrammatic Number Python Solution
Source: https://leetcode-py.wisl.dev/problems/strobogrammatic-number
Tested Python solution for LeetCode 246 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 246, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/strobogrammatic-number/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 246 # by problem number
lcpy gen -s strobogrammatic_number # by problem name
```
## Problem
Given a string `num` which represents an integer, return `true` *if* `num` *is a **strobogrammatic number***.
A **strobogrammatic number** is a number that looks the same when rotated `180` degrees (looked at upside down).
### Examples
```
Input: num = "69"
Output: true
```
```
Input: num = "88"
Output: true
```
```
Input: num = "962"
Output: false
```
### Constraints
* `1 <= num.length <= 50`
* `num` consists of only digits.
* `num` does not contain any leading zeros except for zero itself.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strobogrammatic_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strobogrammatic_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def is_strobogrammatic(self, num: str) -> bool:
rotated = {"0": "0", "1": "1", "8": "8", "6": "9", "9": "6"}
left = 0
right = len(num) - 1
while left <= right:
if num[left] not in rotated or rotated[num[left]] != num[right]:
return False
left += 1
right -= 1
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Strobogrammatic Number II Python Solution
Source: https://leetcode-py.wisl.dev/problems/strobogrammatic-number-ii
Tested Python solution for LeetCode 247 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 247, [Medium](/catalog/medium). Topics: [Recursion](/catalog/topics/recursion), [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/strobogrammatic-number-ii/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 247 # by problem number
lcpy gen -s strobogrammatic_number_ii # by problem name
```
## Problem
Given an integer `n`, return all the **strobogrammatic numbers** that are of length `n`. You may return the answer in **any order**.
A **strobogrammatic number** is a number that looks the same when rotated `180` degrees (looked at upside down).
### Examples
```
Input: n = 2
Output: ["11","69","88","96"]
```
```
Input: n = 1
Output: ["0","1","8"]
```
### Constraints
* `1 <= n <= 14`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strobogrammatic_number_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strobogrammatic_number_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^n)
# Space: O(2^n)
def find_strobogrammatic(self, n: int) -> list[str]:
def build(length: int) -> list[str]:
if length == 0:
return [""]
if length == 1:
return ["0", "1", "8"]
results: list[str] = []
for middle in build(length - 2):
for left, right in ("11", "88", "69", "96"):
results.append(left + middle + right)
if length != n:
results.append("0" + middle + "0")
return results
return build(n)
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(2^n) | O(2^n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Strobogrammatic Number III Python Solution
Source: https://leetcode-py.wisl.dev/problems/strobogrammatic-number-iii
Tested Python solution for LeetCode 248 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 248, [Hard](/catalog/hard). Topics: [Recursion](/catalog/topics/recursion), [Array](/catalog/topics/array), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/strobogrammatic-number-iii/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 248 # by problem number
lcpy gen -s strobogrammatic_number_iii # by problem name
```
## Problem
Given two strings low and high that represent two integers `low` and `high` where `low <= high`, return *the number of **strobogrammatic numbers** in the range* `[low, high]`.
A **strobogrammatic number** is a number that looks the same when rotated `180` degrees (looked at upside down).
### Examples
```
Input: low = "50", high = "100"
Output: 3
```
```
Input: low = "0", high = "0"
Output: 1
```
### Constraints
* `1 <= low.length, high.length <= 15`
* `low` and `high` consist of only digits.
* `low <= high`
* `low` and `high` do not contain any leading zeros except for zero itself.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strobogrammatic_number_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strobogrammatic_number_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^n * n)
# Space: O(2^n)
def strobogrammatic_in_range(self, low: str, high: str) -> int:
def build(length: int, outermost: bool) -> list[str]:
if length == 0:
return [""]
if length == 1:
return ["0", "1", "8"]
results: list[str] = []
for middle in build(length - 2, False):
for left, right in ("11", "88", "69", "96"):
results.append(left + middle + right)
if not outermost:
results.append("0" + middle + "0")
return results
count = 0
for length in range(len(low), len(high) + 1):
for candidate in build(length, True):
if int(low) <= int(candidate) <= int(high):
count += 1
return count
```
## Complexity
| Time | Space |
| ----------- | ------ |
| O(2^n \* n) | O(2^n) |
## Tags
# Strong Password Checker Python Solution
Source: https://leetcode-py.wisl.dev/problems/strong-password-checker
Tested Python solution for LeetCode 420 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 420, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue). [View on LeetCode](https://leetcode.com/problems/strong-password-checker/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 420 # by problem number
lcpy gen -s strong_password_checker # by problem name
```
## Problem
A password is considered strong if the below conditions are all met:
* It has at least `6` characters and at most `20` characters.
* It contains at least **one lowercase** letter, at least **one uppercase** letter, and at least **one digit**.
* It does not contain three repeating characters in a row (i.e., `"B**aaa**bb0"` is weak, but `"B**aa**b**a**0"` is strong).
Given a string `password`, return *the minimum number of steps required to make `password` strong. if `password` is already strong, return `0`.*
In one step, you can:
* Insert one character to `password`,
* Delete one character from `password`, or
* Replace one character of `password` with another character.
### Examples
```
Input: password = "a"
Output: 5
```
```
Input: password = "aA1"
Output: 3
```
```
Input: password = "1337C0d3"
Output: 0
```
### Constraints
* 1 \<= password.length \<= 50
* password consists of letters, digits, dot '.' or exclamation mark '!'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strong_password_checker/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/strong_password_checker/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def strong_password_checker(self, password: str) -> int:
n = len(password)
missing = 3 - (
any(c.islower() for c in password)
+ any(c.isupper() for c in password)
+ any(c.isdigit() for c in password)
)
runs: list[int] = []
i = 0
while i < n:
j = i
while j < n and password[j] == password[i]:
j += 1
runs.append(j - i)
i = j
if n < 6:
# Insertions cover both the length gap and the missing types.
return max(6 - n, missing)
replace = sum(run // 3 for run in runs)
if n <= 20:
# A replacement fixes a missing type and breaks a repeat at once.
return max(missing, replace)
# Length must shrink to 20; spend deletions where they save a replacement.
delete = n - 20
lengths = runs[:]
remaining = delete
for mod in (0, 1):
for idx, run in enumerate(lengths):
if remaining <= 0:
break
if run >= 3 and run % 3 == mod:
spent = min(remaining, mod + 1)
lengths[idx] -= spent
remaining -= spent
if remaining <= 0:
break
replace_left = sum(run // 3 for run in lengths)
# Leftover deletions still help: every 3 of them shorten a run past one repeat.
return delete + max(missing, replace_left - remaining // 3)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
# Student Attendance Record I Python Solution
Source: https://leetcode-py.wisl.dev/problems/student-attendance-record-i
Tested Python solution for LeetCode 551 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 551, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/student-attendance-record-i/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 551 # by problem number
lcpy gen -s student_attendance_record_i # by problem name
```
## Problem
You are given a string `s` representing an attendance record for a student where each character signifies whether the student was absent, late, or present on that day.
The record only contains the following three characters:
* `'A'`: Absent.
* `'L'`: Late.
* `'P'`: Present.
The student is eligible for an attendance award if they meet **both** of the following criteria:
* The student was absent (`'A'`) for **strictly** fewer than 2 days **total**.
* The student was **never** late (`'L'`) for 3 or more **consecutive** days.
Return `true` if the student is eligible for an attendance award, or `false` otherwise.
### Examples
```
Input: s = "PPALLP"
Output: true
Explanation: The student has fewer than 2 absences and was never late 3 or more consecutive days.
```
```
Input: s = "PPALLL"
Output: false
Explanation: The student was late 3 consecutive days in the last 3 days, so is not eligible for the award.
```
### Constraints
* 1 \<= s.length \<= 1000
* s\[i] is either 'A', 'L', or 'P'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/student_attendance_record_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/student_attendance_record_i/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def check_record(self, s: str) -> bool:
absent = 0
late_run = 0
for c in s:
if c == "A":
absent += 1
if absent >= 2:
return False
late_run = 0
elif c == "L":
late_run += 1
if late_run >= 3:
return False
else:
late_run = 0
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Student Attendance Record II Python Solution
Source: https://leetcode-py.wisl.dev/problems/student-attendance-record-ii
Tested Python solution for LeetCode 552 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 552, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/student-attendance-record-ii/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 552 # by problem number
lcpy gen -s student_attendance_record_ii # by problem name
```
## Problem
An attendance record for a student can be represented as a string where each character signifies whether the student was absent, late, or present on that day. The record only contains the following three characters:
* `'A'`: Absent.
* `'L'`: Late.
* `'P'`: Present.
Any student is eligible for an attendance award if they meet **both** of the following criteria:
* The student was absent (`'A'`) for **strictly** fewer than 2 days **total**.
* The student was **never** late (`'L'`) for 3 or more **consecutive** days.
Given an integer `n`, return *the **number** of possible attendance records of length* `n` *that make a student eligible for an attendance award*. The answer may be very large, so return it **modulo** `10^9 + 7`.
### Examples
```
Input: n = 2
Output: 8
Explanation: There are 8 records with length 2 that are eligible for an award:
"PP", "AP", "PA", "LP", "PL", "AL", "LA", "LL"
Only "AA" is not eligible because there are 2 absences (there need to be fewer than 2).
```
```
Input: n = 1
Output: 3
```
```
Input: n = 10101
Output: 183236316
```
### Constraints
* 1 \<= n \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/student_attendance_record_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/student_attendance_record_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def check_record(self, n: int) -> int:
mod = 1_000_000_007
# dp[a][l]: records ending with `a` total absences and `l` trailing
# consecutive lates.
dp = [[0] * 3 for _ in range(2)]
dp[0][0] = 1
for _ in range(n):
no_absent = sum(dp[0]) % mod
with_absent = sum(dp[1]) % mod
nxt = [
# append 'P' (late streak resets); 'A' starts the streak anew
[no_absent, dp[0][0], dp[0][1]],
[(no_absent + with_absent) % mod, dp[1][0], dp[1][1]],
]
dp = nxt
return (sum(dp[0]) + sum(dp[1])) % mod
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Subarray Product Less Than K Python Solution
Source: https://leetcode-py.wisl.dev/problems/subarray-product-less-than-k
Tested Python solution for LeetCode 713 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 713, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/subarray-product-less-than-k/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 713 # by problem number
lcpy gen -s subarray_product_less_than_k # by problem name
```
## Problem
Given an array of integers `nums` and an integer `k`, return the number of contiguous subarrays where the product of all the elements in the subarray is strictly less than `k`.
### Examples
```
Input: nums = [10,5,2,6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are:
[10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.
```
```
Input: nums = [1,2,3], k = 0
Output: 0
```
### Constraints
* 1 \<= nums.length \<= 3 \* 10^4
* 1 \<= nums\[i] \<= 1000
* 0 \<= k \<= 10^6
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarray_product_less_than_k/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarray_product_less_than_k/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def num_subarray_product_less_than_k(self, nums: list[int], k: int) -> int:
if k <= 1:
return 0
product = 1
left = 0
count = 0
for right, val in enumerate(nums):
product *= val
while product >= k:
product //= nums[left]
left += 1
count += right - left + 1
return count
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Subarray Sum Equals K Python Solution
Source: https://leetcode-py.wisl.dev/problems/subarray-sum-equals-k
Tested Python solution for LeetCode 560 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 560, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/subarray-sum-equals-k/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 560 # by problem number
lcpy gen -s subarray_sum_equals_k # by problem name
```
## Problem
Given an array of integers `nums` and an integer `k`, return *the total number of subarrays whose sum equals to* `k`.
A **subarray** is a contiguous **non-empty** sequence of elements within an array.
### Examples
```
Input: nums = [1,1,1], k = 2
Output: 2
```
```
Input: nums = [1,2,3], k = 3
Output: 2
```
### Constraints
* 1 \<= nums.length \<= 2 \* 10^4
* -1000 \<= nums\[i] \<= 1000
* -10^7 \<= k \<= 10^7
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarray_sum_equals_k/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarray_sum_equals_k/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
class Solution:
# Time: O(n)
# Space: O(n)
def subarray_sum(self, nums: list[int], k: int) -> int:
prefix_sum_counts = defaultdict(int)
prefix_sum_counts[0] = 1
current_sum = 0
count = 0
for num in nums:
current_sum += num
if current_sum - k in prefix_sum_counts:
count += prefix_sum_counts[current_sum - k]
prefix_sum_counts[current_sum] += 1
return count
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind](/catalog/grind), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Subarray Sums Divisible by K Python Solution
Source: https://leetcode-py.wisl.dev/problems/subarray-sums-divisible-by-k
Tested Python solution for LeetCode 974 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 974, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/subarray-sums-divisible-by-k/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 974 # by problem number
lcpy gen -s subarray_sums_divisible_by_k # by problem name
```
## Problem
Given an integer array `nums` and an integer `k`, return *the number of non-empty subarrays that have a sum divisible by* `k`.
A subarray is a contiguous part of an array.
### Examples
```
Input: nums = [4,5,0,-2,-3,1], k = 5
Output: 7
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]
```
```
Input: nums = [5], k = 9
Output: 0
```
### Constraints
* `1 <= nums.length <= 3 * 10^4`
* `-10^4 <= nums[i] <= 10^4`
* `2 <= k <= 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarray_sums_divisible_by_k/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarray_sums_divisible_by_k/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(k)
def subarrays_div_by_k(self, nums: list[int], k: int) -> int:
mod_count: dict[int, int] = {0: 1}
prefix_mod = 0
count = 0
for num in nums:
prefix_mod = (prefix_mod + num) % k
count += mod_count.get(prefix_mod, 0)
mod_count[prefix_mod] = mod_count.get(prefix_mod, 0) + 1
return count
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(k) |
## Tags
[NeetCode All](/catalog/neetcode).
# Subarrays with K Different Integers
Source: https://leetcode-py.wisl.dev/problems/subarrays-with-k-different-integers
Tested Python solution for LeetCode 992 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 992, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Sliding Window](/catalog/topics/sliding-window), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/subarrays-with-k-different-integers/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 992 # by problem number
lcpy gen -s subarrays_with_k_different_integers # by problem name
```
## Problem
Given an integer array `nums` and an integer `k`, return *the number of good subarrays of* `nums`.
A good array is an array where the number of different integers in that array is exactly `k`.
* For example, `[1,2,3,1,2]` has `3` different integers: `1`, `2`, and `3`.
A subarray is a contiguous part of an array.
### Examples
```
Input: nums = [1,2,1,2,3], k = 2
Output: 7
Explanation: Subarrays formed with exactly 2 different integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]
```
```
Input: nums = [1,2,1,3,4], k = 3
Output: 3
Explanation: Subarrays formed with exactly 3 different integers: [1,2,1,3], [2,1,3], [1,3,4].
```
### Constraints
* `1 <= nums.length <= 2 * 10^4`
* `1 <= nums[i], k <= nums.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarrays_with_k_different_integers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subarrays_with_k_different_integers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def subarrays_with_k_distinct(self, nums: list[int], k: int) -> int:
def at_most(target: int) -> int:
if target < 0:
return 0
count: dict[int, int] = {}
left = 0
total = 0
for right, num in enumerate(nums):
count[num] = count.get(num, 0) + 1
while len(count) > target:
count[nums[left]] -= 1
if count[nums[left]] == 0:
del count[nums[left]]
left += 1
total += right - left + 1
return total
return at_most(k) - at_most(k - 1)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Subdomain Visit Count Python Solution
Source: https://leetcode-py.wisl.dev/problems/subdomain-visit-count
Tested Python solution for LeetCode 811 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 811, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/subdomain-visit-count/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 811 # by problem number
lcpy gen -s subdomain_visit_count # by problem name
```
## Problem
A website domain `"discuss.leetcode.com"` consists of various subdomains. At the top level, we have `"com"`, at the next level, we have `"leetcode.com"` and at the lowest level, `"discuss.leetcode.com"`. When we visit a domain like `"discuss.leetcode.com"`, we will also visit the parent domains `"leetcode.com"` and `"com"` implicitly.
A \count-paired domain\ is a domain that has one of the two formats `"rep d1.d2.d3"` or `"rep d1.d2"` where `rep` is the number of visits to the domain and `d1.d2.d3` is the domain itself.
* For example, `"9001 discuss.leetcode.com"` is a \count-paired domain\ that indicates that \discuss.leetcode.com\ was visited `9001` times.
Given an array of \count-paired domains\ \cpdomains\, return \an array of the \count-paired domains\ of each subdomain in the input\. You may return the answer in \any order\.
### Examples
```
Input: cpdomains = ["9001 discuss.leetcode.com"]
Output: ["9001 leetcode.com","9001 discuss.leetcode.com","9001 com"]
```
Explanation: We only have one website domain: `"discuss.leetcode.com"`.
As discussed above, the subdomains `"leetcode.com"` and `"com"` will also be visited. So they will all be visited 9001 times.
```
Input: cpdomains = ["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"]
Output: ["901 mail.com","50 yahoo.com","900 google.mail.com","5 wiki.org","5 org","1 intel.mail.com","951 com"]
```
Explanation: We will visit `"google.mail.com"` 900 times, `"yahoo.com"` 50 times, `"intel.mail.com"` once and `"wiki.org"` 5 times.
For the subdomains, we will visit `"mail.com"` 900 + 1 = 901 times, `"com"` 900 + 50 + 1 = 951 times, and `"org"` 5 times.
### Constraints
* 1 \<= cpdomains.length \<= 100
* 1 \<= cpdomains\[i].length \<= 100
* cpdomains\[i] follows either the "rep\i\ d1\i\.d2\i\.d3\i\" format or the "rep\i\ d1\i\.d2\i\" format.
* rep\i\ is an integer in the range \[1, 10\4\].
* d1\i\, d2\i\, and d3\i\ consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subdomain_visit_count/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subdomain_visit_count/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n * m) where n is the number of domains and m is the label count
# Space: O(n * m) for the counter of subdomains
def subdomain_visits(self, cpdomains: list[str]) -> list[str]:
counts: Counter[str] = Counter()
for entry in cpdomains:
rep_str, domain = entry.split(" ")
labels = domain.split(".")
for i in range(len(labels)):
counts[".".join(labels[i:])] += int(rep_str)
return [f"{rep} {domain}" for domain, rep in counts.items()]
```
## Complexity
| Time | Space |
| ------------------------------------------------------------------- | --------------------------------------- |
| O(n \* m) where n is the number of domains and m is the label count | O(n \* m) for the counter of subdomains |
## Tags
# Subsets Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/subsets
Tested Python solution for LeetCode 78 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 78, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/subsets/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 78 # by problem number
lcpy gen -s subsets # by problem name
```
## Problem
Given an integer array `nums` of **unique** elements, return *all possible* subsets (the power set).
The solution set **must not** contain duplicate subsets. Return the solution in **any order**.
### Examples
```
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
```
```
Input: nums = [0]
Output: [[],[0]]
```
### Constraints
* 1 \<= nums.length \<= 10
* -10 \<= nums\[i] \<= 10
* All the numbers of nums are unique.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subsets/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subsets/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(2^n)
# Space: O(2^n)
def subsets(self, nums: list[int]) -> list[list[int]]:
result = []
def backtrack(start: int, path: list[int]) -> None:
result.append(path[:])
for i in range(start, len(nums)):
path.append(nums[i])
backtrack(i + 1, path)
path.pop()
backtrack(0, [])
return result
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(2^n) | O(2^n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Subsets II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/subsets-ii
Tested Python solution for LeetCode 90 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 90, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/subsets-ii/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 90 # by problem number
lcpy gen -s subsets_ii # by problem name
```
## Problem
Given an integer array `nums` that may contain duplicates, return *all possible subsets (the power set)*.
The solution set **must not** contain duplicate subsets. Return the solution in **any order**.
### Examples
```
Input: nums = [1,2,2]
Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
```
```
Input: nums = [0]
Output: [[],[0]]
```
### Constraints
* 1 \<= nums.length \<= 10
* -10 \<= nums\[i] \<= 10
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subsets_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subsets_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * 2^n)
# Space: O(n) recursion stack
def subsets_with_dup(self, nums: list[int]) -> list[list[int]]:
nums.sort()
result: list[list[int]] = []
subset: list[int] = []
def backtrack(start: int) -> None:
result.append(list(subset))
for i in range(start, len(nums)):
# Skip duplicates at the same depth to avoid duplicate subsets
if i > start and nums[i] == nums[i - 1]:
continue
subset.append(nums[i])
backtrack(i + 1)
subset.pop()
backtrack(0)
return result
```
## Complexity
| Time | Space |
| ----------- | -------------------- |
| O(n \* 2^n) | O(n) recursion stack |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Substring with Concatenation of All Words
Source: https://leetcode-py.wisl.dev/problems/substring-with-concatenation-of-all-words
Tested Python solution for LeetCode 30 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 30, [Hard](/catalog/hard). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sliding Window](/catalog/topics/sliding-window). [View on LeetCode](https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 30 # by problem number
lcpy gen -s substring_with_concatenation_of_all_words # by problem name
```
## Problem
You are given a string `s` and an array of strings `words`. All the strings of `words` are of **the same length**.
A **concatenated string** is a string that exactly contains all the strings of any permutation of `words` concatenated.
* For example, if `words = ["ab","cd","ef"]`, then `"abcdef"`, `"abefcd"`, `"cdabef"`, `"cdefab"`, `"efabcd"`, and `"efcdab"` are all concatenated strings. `"acdbef"` is not a concatenated string because it is not the concatenation of any permutation of `words`.
### Examples
```
Input: s = "barfoothefoobarman", words = ["foo","bar"]
Output: [0,9]
```
**Explanation:**
The substring starting at 0 is "barfoo". It is the concatenation of \["bar","foo"] which is a permutation of `words`.
The substring starting at 9 is "foobar". It is the concatenation of \["foo","bar"] which is a permutation of `words`.
```
Input: s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
Output: []
```
**Explanation:**
There is no concatenated substring.
```
Input: s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
Output: [6,9,12]
```
**Explanation:**
The substring starting at 6 is "foobarthe". It is the concatenation of \["foo","bar","the"].
The substring starting at 9 is "barthefoo". It is the concatenation of \["bar","the","foo"].
The substring starting at 12 is "thefoobar". It is the concatenation of \["the","foo","bar"].
### Constraints
* 1 \<= s.length \<= 10^4
* 1 \<= words.length \<= 5000
* 1 \<= words\[i].length \<= 30
* s and words\[i] consist of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/substring_with_concatenation_of_all_words/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/substring_with_concatenation_of_all_words/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(word_len * len(s)) - each index enters the window at most once per offset
# Space: O(len(words)) for the two counters
def find_substring(self, s: str, words: list[str]) -> list[int]:
if not s or not words:
return []
word_len = len(words[0])
word_total = len(words)
concat_len = word_len * word_total
target = Counter(words)
result: list[int] = []
for offset in range(word_len):
left = offset
window: Counter[str] = Counter()
for right in range(offset, len(s) - word_len + 1, word_len):
word = s[right : right + word_len]
window[word] += 1
while window[word] > target[word]:
window[s[left : left + word_len]] -= 1
left += word_len
if right + word_len - left == concat_len:
result.append(left)
return result
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------------------- | ---------------------------------- |
| O(word\_len \* len(s)) - each index enters the window at most once per offset | O(len(words)) for the two counters |
## Tags
# Subtree of Another Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/subtree-of-another-tree
Tested Python solution for LeetCode 572 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 572, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [String Matching](/catalog/topics/string-matching), [Binary Tree](/catalog/topics/binary-tree), [Hash Function](/catalog/topics/hash-function). [View on LeetCode](https://leetcode.com/problems/subtree-of-another-tree/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 572 # by problem number
lcpy gen -s subtree_of_another_tree # by problem name
```
## Problem
Given the roots of two binary trees root and subRoot, return true if there is a subtree of root with the same structure and node values of subRoot and false otherwise.
A subtree of a binary tree tree is a tree that consists of a node in tree and all of this node's descendants. The tree tree could also be considered as a subtree of itself.
### Examples

```
Input: root = [3,4,5,1,2], subRoot = [4,1,2]
Output: true
```

```
Input: root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
Output: false
```
### Constraints
The number of nodes in the root tree is in the range \[1, 2000].
The number of nodes in the subRoot tree is in the range \[1, 1000].
-10^4 \<= root.val \<= 10^4
-10^4 \<= subRoot.val \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subtree_of_another_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/subtree_of_another_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(m * n) - where m is nodes in root, n is nodes in sub_root
# Space: O(h) - where h is height of root tree (recursion stack)
def is_subtree(self, root: TreeNode[int] | None, sub_root: TreeNode[int] | None) -> bool:
"""
Check if sub_root is a subtree of root.
Uses DFS to check every node in root as potential subtree root.
"""
if not sub_root:
return True
if not root:
return False
# Check if current root matches sub_root
if self._is_same_tree(root, sub_root):
return True
# Recursively check left and right subtrees
return self.is_subtree(root.left, sub_root) or self.is_subtree(root.right, sub_root)
def _is_same_tree(self, p: TreeNode[int] | None, q: TreeNode[int] | None) -> bool:
"""Helper method to check if two trees are identical."""
if not p and not q:
return True
if not p or not q:
return False
if p.val != q.val:
return False
return self._is_same_tree(p.left, q.left) and self._is_same_tree(p.right, q.right)
```
## Complexity
| Time | Space |
| ------------------------------------------------------------- | ------------------------------------------------------- |
| O(m \* n) - where m is nodes in root, n is nodes in sub\_root | O(h) - where h is height of root tree (recursion stack) |
## Tags
[Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Successful Pairs of Spells and Potions
Source: https://leetcode-py.wisl.dev/problems/successful-pairs-of-spells-and-potions
Tested Python solution for LeetCode 2300 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2300, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/successful-pairs-of-spells-and-potions/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2300 # by problem number
lcpy gen -s successful_pairs_of_spells_and_potions # by problem name
```
## Problem
You are given two positive integer arrays `spells` and `potions`, of length `n` and `m` respectively, where `spells[i]` represents the strength of the `i`th spell and `potions[j]` represents the strength of the `j`th potion.
You are also given an integer `success`. A spell and potion pair is considered **successful** if the **product** of their strengths is **at least** `success`.
Return *an integer array* `pairs` *of length* `n` *where* `pairs[i]` *is the number of **potions** that will form a successful pair with the* `i`th *spell.*
### Examples
```
Input: spells = [5,1,3], potions = [1,2,3,4,5], success = 7
Output: [4,0,3]
Explanation:
- 0th spell: 5 * [1,2,3,4,5] = [5,10,15,20,25]. 4 pairs are successful.
- 1st spell: 1 * [1,2,3,4,5] = [1,2,3,4,5]. 0 pairs are successful.
- 2nd spell: 3 * [1,2,3,4,5] = [3,6,9,12,15]. 3 pairs are successful.
Thus, [4,0,3] is returned.
```
```
Input: spells = [3,1,2], potions = [8,5,8], success = 16
Output: [2,0,2]
Explanation:
- 0th spell: 3 * [8,5,8] = [24,15,24]. 2 pairs are successful.
- 1st spell: 1 * [8,5,8] = [8,5,8]. 0 pairs are successful.
- 2nd spell: 2 * [8,5,8] = [16,10,16]. 2 pairs are successful.
Thus, [2,0,2] is returned.
```
### Constraints
* n == spells.length
* m == potions.length
* 1 \<= n, m \<= 10^5
* 1 \<= spells\[i], potions\[i] \<= 10^5
* 1 \<= success \<= 10^10
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/successful_pairs_of_spells_and_potions/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/successful_pairs_of_spells_and_potions/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O((n + m) log m) - sorting potions plus a binary search per spell
# Space: O(m) - sorted copy of the potions
def successful_pairs(self, spells: list[int], potions: list[int], success: int) -> list[int]:
potions.sort()
n = len(potions)
pairs: list[int] = []
for spell in spells:
lo, hi = 0, n
while lo < hi:
mid = (lo + hi) // 2
if spell * potions[mid] >= success:
hi = mid
else:
lo = mid + 1
pairs.append(n - lo)
return pairs
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------- | --------------------------------- |
| O((n + m) log m) - sorting potions plus a binary search per spell | O(m) - sorted copy of the potions |
## Tags
[NeetCode All](/catalog/neetcode).
# Sudoku Solver Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/sudoku-solver
Tested Python solution for LeetCode 37 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 37, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Backtracking](/catalog/topics/backtracking), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/sudoku-solver/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 37 # by problem number
lcpy gen -s sudoku_solver # by problem name
```
## Problem
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy **all of the following rules**:
1. Each of the digits `1-9` must occur exactly once in each row.
2. Each of the digits `1-9` must occur exactly once in each column.
3. Each of the digits `1-9` must occur exactly once in each of the 9 `3x3` sub-boxes of the grid.
The `'.'` character indicates empty cells.
### Examples

```
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"]]
Output: [["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
Explanation: The input board is shown above and the only valid solution is shown below:

```
### Constraints
* board.length == 9
* board\[i].length == 9
* board\[i]\[j] is a digit or '.'.
* It is guaranteed that the input board has only one solution.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sudoku_solver/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sudoku_solver/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(9^(n)) where n = number of empty cells, pruned heavily by validity checks
# Space: O(n) recursion stack + O(1) bookkeeping sets
def solve_sudoku(self, board: list[list[str]]) -> None:
rows = [set[str]() for _ in range(9)]
cols = [set[str]() for _ in range(9)]
boxes = [set[str]() for _ in range(9)]
empties: list[tuple[int, int]] = []
for r in range(9):
for c in range(9):
ch = board[r][c]
if ch == ".":
empties.append((r, c))
else:
rows[r].add(ch)
cols[c].add(ch)
boxes[(r // 3) * 3 + c // 3].add(ch)
def backtrack(idx: int) -> bool:
if idx == len(empties):
return True
r, c = empties[idx]
b = (r // 3) * 3 + c // 3
for d in map(str, range(1, 10)):
if d in rows[r] or d in cols[c] or d in boxes[b]:
continue
board[r][c] = d
rows[r].add(d)
cols[c].add(d)
boxes[b].add(d)
if backtrack(idx + 1):
return True
board[r][c] = "."
rows[r].discard(d)
cols[c].discard(d)
boxes[b].discard(d)
return False
backtrack(0)
```
## Complexity
| Time | Space |
| --------------------------------------------------------------------------- | -------------------------------------------- |
| O(9^(n)) where n = number of empty cells, pruned heavily by validity checks | O(n) recursion stack + O(1) bookkeeping sets |
## Tags
[Grind](/catalog/grind).
# Sum of Even Numbers After Queries
Source: https://leetcode-py.wisl.dev/problems/sum-even-after-queries
Tested Python solution for LeetCode 985 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 985, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/sum-even-after-queries/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 985 # by problem number
lcpy gen -s sum_even_after_queries # by problem name
```
## Problem
You are given an integer array `nums` and an array `queries` where `queries[i] = [val_i, index_i]`.
For each query `i`, first, apply `nums[index_i] = nums[index_i] + val_i`, then print the sum of the even values of `nums`.
Return an integer array `answer` where `answer[i]` is the answer to the `i-th` query.
### Examples
```
Input: nums = [1,2,3,4], queries = [[1,0],[-3,1],[-4,0],[2,3]]
Output: [8,6,2,4]
Explanation: At the beginning, the array is [1,2,3,4].
After adding 1 to nums[0], the array is [2,2,3,4], and the sum of even values is 2 + 2 + 4 = 8.
After adding -3 to nums[1], the array is [2,-1,3,4], and the sum of even values is 2 + 4 = 6.
After adding -4 to nums[0], the array is [-2,-1,3,4], and the sum of even values is -2 + 4 = 2.
After adding 2 to nums[3], the array is [-2,-1,3,6], and the sum of even values is -2 + 6 = 4.
```
```
Input: nums = [1], queries = [[4,0]]
Output: [0]
```
### Constraints
* 1 \<= nums.length \<= 10^4
* -10^4 \<= nums\[i] \<= 10^4
* 1 \<= queries.length \<= 10^4
* -10^4 \<= val\_i \<= 10^4
* 0 \<= index\_i \< nums.length
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_even_after_queries/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_even_after_queries/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n + q)
# Space: O(q)
def sum_even_after_queries(self, nums: list[int], queries: list[list[int]]) -> list[int]:
even_sum = sum(num for num in nums if num % 2 == 0)
result: list[int] = []
for val, index in queries:
if nums[index] % 2 == 0:
even_sum -= nums[index]
nums[index] += val
if nums[index] % 2 == 0:
even_sum += nums[index]
result.append(even_sum)
return result
```
## Complexity
| Time | Space |
| -------- | ----- |
| O(n + q) | O(q) |
## Tags
# Sum of Absolute Differences in a Sorted Array
Source: https://leetcode-py.wisl.dev/problems/sum-of-absolute-differences-in-a-sorted-array
Tested Python solution for LeetCode 1685 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1685, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/sum-of-absolute-differences-in-a-sorted-array/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1685 # by problem number
lcpy gen -s sum_of_absolute_differences_in_a_sorted_array # by problem name
```
## Problem
You are given an integer array `nums` sorted in **non-decreasing** order.
Build and return *an integer array* `result` *with the same length as* `nums` *such that* `result[i]` *is equal to the* ***summation of absolute differences*** *between* `nums[i]` *and all the other elements in the array.*
In other words, `result[i]` is equal to `sum(|nums[i]-nums[j]|)` where `0 <= j < nums.length` and `j != i` (**0-indexed**).
### Examples
```
Input: nums = [2,3,5]
Output: [4,3,5]
Explanation: Assuming the arrays are 0-indexed, then
result[0] = |2-2| + |2-3| + |2-5| = 0 + 1 + 3 = 4,
result[1] = |3-2| + |3-3| + |3-5| = 1 + 0 + 2 = 3,
result[2] = |5-2| + |5-3| + |5-5| = 3 + 2 + 0 = 5.
```
```
Input: nums = [1,4,6,8,10]
Output: [24,15,13,15,21]
```
### Constraints
* 2 \<= nums.length \<= 10^5
* 1 \<= nums\[i] \<= nums\[i + 1] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_absolute_differences_in_a_sorted_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_absolute_differences_in_a_sorted_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def get_sum_absolute_differences(self, nums: list[int]) -> list[int]:
n = len(nums)
prefix = [0] * (n + 1)
for i, value in enumerate(nums):
prefix[i + 1] = prefix[i] + value
total = prefix[n]
result = []
for i, value in enumerate(nums):
left_sum = i * value - prefix[i]
right_sum = (total - prefix[i + 1]) - (n - i - 1) * value
result.append(left_sum + right_sum)
return result
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sum of All Subset XOR Totals Python Solution
Source: https://leetcode-py.wisl.dev/problems/sum-of-all-subset-xor-totals
Tested Python solution for LeetCode 1863 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1863, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Backtracking](/catalog/topics/backtracking), [Bit Manipulation](/catalog/topics/bit-manipulation), Combinatorics, [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/sum-of-all-subset-xor-totals/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1863 # by problem number
lcpy gen -s sum_of_all_subset_xor_totals # by problem name
```
## Problem
The **XOR total** of an array is defined as the bitwise `XOR` of **all its elements**, or `0` if the array is **empty**.
* For example, the **XOR total** of the array `[2,5,6]` is `2 XOR 5 XOR 6 = 1`.
Given an array `nums`, return *the **sum** of all **XOR totals** for every **subset** of* `nums`.
**Note:** Subsets with the **same** elements should be counted **multiple** times.
An array `a` is a **subset** of an array `b` if `a` can be obtained from `b` by deleting some (possibly zero) elements of `b`.
### Examples
```
Input: nums = [1,3]
Output: 6
Explanation: The 4 subsets of [1,3] are:
- The empty subset has an XOR total of 0.
- [1] has an XOR total of 1.
- [3] has an XOR total of 3.
- [1,3] has an XOR total of 1 XOR 3 = 2.
0 + 1 + 3 + 2 = 6
```
```
Input: nums = [5,1,6]
Output: 28
Explanation: The 8 subsets of [5,1,6] are:
- The empty subset has an XOR total of 0.
- [5] has an XOR total of 5.
- [1] has an XOR total of 1.
- [6] has an XOR total of 6.
- [5,1] has an XOR total of 5 XOR 1 = 4.
- [5,6] has an XOR total of 5 XOR 6 = 3.
- [1,6] has an XOR total of 1 XOR 6 = 7.
- [5,1,6] has an XOR total of 5 XOR 1 XOR 6 = 2.
0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28
```
```
Input: nums = [3,4,5,6,7,8]
Output: 480
Explanation: The sum of all XOR totals for every subset is 480.
```
### Constraints
* 1 \<= nums.length \<= 12
* 1 \<= nums\[i] \<= 20
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_all_subset_xor_totals/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_all_subset_xor_totals/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * 2^n)
# Space: O(n)
def subset_xor_sum(self, nums: list[int]) -> int:
def backtrack(index: int, current_xor: int) -> int:
if index == len(nums):
return current_xor
include = backtrack(index + 1, current_xor ^ nums[index])
exclude = backtrack(index + 1, current_xor)
return include + exclude
return backtrack(0, 0)
```
## Complexity
| Time | Space |
| ----------- | ----- |
| O(n \* 2^n) | O(n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Sum of Distances in Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/sum-of-distances-in-tree
Tested Python solution for LeetCode 834 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 834, [Hard](/catalog/hard). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Graph Theory](/catalog/topics/graph-theory), DP on Trees. [View on LeetCode](https://leetcode.com/problems/sum-of-distances-in-tree/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 834 # by problem number
lcpy gen -s sum_of_distances_in_tree # by problem name
```
## Problem
There is an undirected connected tree with `n` nodes labeled from `0` to `n - 1` and `n - 1` edges.
You are given the integer `n` and the array `edges` where `edges[i] = [ai, bi]` indicates that there is an edge between nodes `ai` and `bi` in the tree.
Return an array `answer` of length `n` where `answer[i]` is the sum of the distances between the `ith` node in the tree and all other nodes.
### Examples

```
Input: n = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]]
Output: [8,12,6,10,10,10]
Explanation: The tree is shown above.
We can see that dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5)
equals 1 + 1 + 2 + 2 + 2 = 8.
Hence, answer[0] = 8, and so on.
```

```
Input: n = 1, edges = []
Output: [0]
```

```
Input: n = 2, edges = [[1,0]]
Output: [1,1]
```
### Constraints
* 1 \<= n \<= 3 \* 10^4
* edges.length == n - 1
* edges\[i].length == 2
* 0 \<= a\i\, b\i\ \< n
* a\i\ != b\i\
* The given input represents a valid tree.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_distances_in_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_distances_in_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) build + two O(n) traversals
# Space: O(n) adjacency, subtree counts and output
def sum_of_distances_in_tree(self, n: int, edges: list[list[int]]) -> list[int]:
graph: list[list[int]] = [[] for _ in range(n)]
for a, b in edges:
graph[a].append(b)
graph[b].append(a)
subtree_size = [1] * n
answer = [0] * n
# Post-order from root 0: count descendants and sum depths below each node.
stack: list[tuple[int, int, bool]] = [(0, -1, False)]
while stack:
node, parent, processed = stack.pop()
if not processed:
stack.append((node, parent, True))
for child in graph[node]:
if child != parent:
stack.append((child, node, False))
else:
for child in graph[node]:
if child != parent:
subtree_size[node] += subtree_size[child]
answer[node] += answer[child] + subtree_size[child]
# Pre-order reroot: moving the root from parent to child shifts the sum by
# size(child) closer minus (n - size(child)) farther.
reroot_stack: list[tuple[int, int]] = [(0, -1)]
while reroot_stack:
node, parent = reroot_stack.pop()
for child in graph[node]:
if child != parent:
answer[child] = answer[node] + n - 2 * subtree_size[child]
reroot_stack.append((child, node))
return answer
```
## Complexity
| Time | Space |
| -------------------------------- | ----------------------------------------- |
| O(n) build + two O(n) traversals | O(n) adjacency, subtree counts and output |
## Tags
# Sum of Left Leaves Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/sum-of-left-leaves
Tested Python solution for LeetCode 404 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 404, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/sum-of-left-leaves/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 404 # by problem number
lcpy gen -s sum_of_left_leaves # by problem name
```
## Problem
Given the `root` of a binary tree, return *the sum of all left leaves*.
A **leaf** is a node with no children. A **left leaf** is a leaf that is the left child of another node.
### Examples

```
Input: root = [3,9,20,null,null,15,7]
Output: 24
Explanation: There are two left leaves in the binary tree, with values 9 and 15 respectively.
```
```
Input: root = [1]
Output: 0
```
### Constraints
* The number of nodes in the tree is in the range \[1, 1000]
* -1000 \<= Node.val \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_left_leaves/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_left_leaves/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def sum_of_left_leaves(self, root: TreeNode[int] | None) -> int:
if root is None:
return 0
if root.left is not None and root.left.left is None and root.left.right is None:
return root.left.val + self.sum_of_left_leaves(root.right)
return self.sum_of_left_leaves(root.left) + self.sum_of_left_leaves(root.right)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
# Sum of Prefix Scores of Strings
Source: https://leetcode-py.wisl.dev/problems/sum-of-prefix-scores-of-strings
Tested Python solution for LeetCode 2416 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 2416, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [String](/catalog/topics/string), [Trie](/catalog/topics/trie), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/sum-of-prefix-scores-of-strings/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 2416 # by problem number
lcpy gen -s sum_of_prefix_scores_of_strings # by problem name
```
## Problem
You are given an array `words` of size `n` consisting of non-empty strings.
We define the **score** of a string `term` as the **number** of strings `words[i]` such that `term` is a **prefix** of `words[i]`.
* For example, if `words = ["a", "ab", "abc", "cab"]`, then the score of `"ab"` is `2`, since `"ab"` is a prefix of both `"ab"` and `"abc"`.
Return *an array* `answer` *of size* `n` *where* `answer[i]` *is the **sum** of scores of every **non-empty** prefix of* `words[i]`.
**Note** that a string is considered as a prefix of itself.
### Examples
```
Input: words = ["abc","ab","bc","b"]
Output: [5,4,3,2]
Explanation: The answer for each string is the following:
- "abc" has 3 prefixes: "a", "ab", and "abc".
- There are 2 strings with the prefix "a", 2 strings with the prefix "ab", and 1 string with the prefix "abc".
The total is answer[0] = 2 + 2 + 1 = 5.
- "ab" has 2 prefixes: "a" and "ab".
- There are 2 strings with the prefix "a", and 2 strings with the prefix "ab".
The total is answer[1] = 2 + 2 = 4.
- "bc" has 2 prefixes: "b" and "bc".
- There are 2 strings with the prefix "b", and 1 string with the prefix "bc".
The total is answer[2] = 2 + 1 = 3.
- "b" has 1 prefix: "b".
- There are 2 strings with the prefix "b".
The total is answer[3] = 2.
```
```
Input: words = ["abcd"]
Output: [4]
Explanation:
"abcd" has 4 prefixes: "a", "ab", "abc", and "abcd".
Each prefix has a score of one, so the total is answer[0] = 1 + 1 + 1 + 1 = 4.
```
### Constraints
* 1 \<= words.length \<= 1000
* 1 \<= words\[i].length \<= 1000
* words\[i] consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_prefix_scores_of_strings/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_prefix_scores_of_strings/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(total characters across all words)
# Space: O(total characters) for the trie
def sum_prefix_scores(self, words: list[str]) -> list[int]:
children: list[dict[str, int]] = [{}]
counts: list[int] = [0]
for word in words:
node = 0
for ch in word:
nxt = children[node].get(ch)
if nxt is None:
nxt = len(children)
children[node][ch] = nxt
children.append({})
counts.append(0)
node = nxt
counts[node] += 1
answer: list[int] = []
for word in words:
node = 0
total = 0
for ch in word:
node = children[node][ch]
total += counts[node]
answer.append(total)
return answer
```
## Complexity
| Time | Space |
| ------------------------------------ | -------------------------------- |
| O(total characters across all words) | O(total characters) for the trie |
## Tags
[NeetCode All](/catalog/neetcode).
# Sum of Square Numbers Python Solution
Source: https://leetcode-py.wisl.dev/problems/sum-of-square-numbers
Tested Python solution for LeetCode 633 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 633, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/sum-of-square-numbers/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 633 # by problem number
lcpy gen -s sum_of_square_numbers # by problem name
```
## Problem
Given a non-negative integer `c`, decide whether there're two integers `a` and `b` such that `a^2 + b^2 = c`.
### Examples
```
Input: c = 5
Output: true
Explanation: 1 * 1 + 2 * 2 = 5
```
```
Input: c = 3
Output: false
```
### Constraints
* 0 \<= c \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_square_numbers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_square_numbers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from math import isqrt
class Solution:
# Time: O(sqrt(c))
# Space: O(1)
def judge_square_sum(self, c: int) -> bool:
left, right = 0, isqrt(c)
while left <= right:
total = left * left + right * right
if total == c:
return True
if total < c:
left += 1
else:
right -= 1
return False
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(sqrt(c)) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sum of Subarray Minimums Python Solution
Source: https://leetcode-py.wisl.dev/problems/sum-of-subarray-minimums
Tested Python solution for LeetCode 907 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 907, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/sum-of-subarray-minimums/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 907 # by problem number
lcpy gen -s sum_of_subarray_minimums # by problem name
```
## Problem
Given an array of integers \arr\, find the sum of \min(b)\, where \b\ ranges over every (contiguous) subarray of \arr\. Since the answer may be large, return the answer \modulo\ \10\9\ + 7\.
### Examples
```
Input: arr = [3,1,2,4]
Output: 17
Explanation:
Subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4].
Minimums are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1. Sum is 17.
```
```
Input: arr = [50]
Output: 50
```
### Constraints
* 1 \<= arr.length \<= 3 \* 10^4
* 1 \<= arr\[i] \<= 3 \* 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_subarray_minimums/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_subarray_minimums/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def sum_subarray_mins(self, arr: list[int]) -> int:
mod = 1_000_000_007
n = len(arr)
stack: list[int] = []
prev = [0] * n
for i, value in enumerate(arr):
while stack and arr[stack[-1]] >= value:
stack.pop()
prev[i] = stack[-1] if stack else -1
stack.append(i)
stack.clear()
next_ = [0] * n
for i in range(n - 1, -1, -1):
while stack and arr[stack[-1]] > arr[i]:
stack.pop()
next_[i] = stack[-1] if stack else n
stack.append(i)
return sum(value * (i - prev[i]) * (next_[i] - i) for i, value in enumerate(arr)) % mod
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Sum of Subsequence Widths Python Solution
Source: https://leetcode-py.wisl.dev/problems/sum-of-subseq-widths
Tested Python solution for LeetCode 891 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 891, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/sum-of-subseq-widths/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 891 # by problem number
lcpy gen -s sum_of_subseq_widths # by problem name
```
## Problem
The **width** of a sequence is the difference between the maximum and minimum elements in the sequence.
Given an array of integers `nums`, return *the sum of the* ***widths*** *of all the non-empty* ***subsequences*** *of* `nums`. Since the answer may be very large, return it **modulo** `10^9 + 7`.
A **subsequence** is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, `[3,6,2,7]` is a subsequence of the array `[0,3,1,6,2,2,7]`.
### Examples
```
Input: nums = [2,1,3]
Output: 6
Explanation: The subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3].
The corresponding widths are 0, 0, 0, 1, 1, 2, 2.
The sum of these widths is 6.
```
```
Input: nums = [2]
Output: 0
```
### Constraints
* `1 <= nums.length <= 10^5`
* `1 <= nums[i] <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_subseq_widths/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_subseq_widths/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(1)
def sum_subseq_widths(self, nums: list[int]) -> int:
mod = 10**9 + 7
ordered = sorted(nums)
total = 0
n = len(ordered)
pow2 = 1
for i, value in enumerate(ordered):
total += value * (pow2 - 1) - value * (pow(2, n - 1 - i, mod) - 1)
total %= mod
pow2 = pow2 * 2 % mod
return total
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(n log n) | O(1) |
## Tags
# Sum of Two Integers Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/sum-of-two-integers
Tested Python solution for LeetCode 371 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 371, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/sum-of-two-integers/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 371 # by problem number
lcpy gen -s sum_of_two_integers # by problem name
```
## Problem
Given two integers a and b, return the sum of the two integers without using the operators + and -.
### Examples
```
Input: a = 1, b = 2
Output: 3
```
```
Input: a = 2, b = 3
Output: 5
```
### Constraints
-1000 \<= a, b \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_two_integers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_of_two_integers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(1) - constant time bit operations
# Space: O(1) - no extra space used
def get_sum(self, a: int, b: int) -> int:
"""
Add two integers without using + or - operators.
Uses bit manipulation approach:
1. XOR gives us the sum without carry
2. AND + left shift gives us the carry
3. Repeat until no carry remains
"""
# Handle 32-bit signed integer overflow
mask = 0xFFFFFFFF
while b != 0:
# Calculate sum without carry
sum_without_carry = (a ^ b) & mask
# Calculate carry
carry = ((a & b) << 1) & mask
a = sum_without_carry
b = carry
# Handle negative result for 32-bit signed integer
if a > 0x7FFFFFFF:
a = ~(a ^ mask)
return a
```
## Complexity
| Time | Space |
| ----------------------------------- | -------------------------- |
| O(1) - constant time bit operations | O(1) - no extra space used |
## Tags
[Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Sum Root to Leaf Numbers Python Solution
Source: https://leetcode-py.wisl.dev/problems/sum-root-to-leaf-numbers
Tested Python solution for LeetCode 129 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 129, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/sum-root-to-leaf-numbers/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 129 # by problem number
lcpy gen -s sum_root_to_leaf_numbers # by problem name
```
## Problem
You are given the `root` of a binary tree containing digits from `0` to `9` only.
Each root-to-leaf path in the tree represents a number.
* For example, the root-to-leaf path `1 -> 2 -> 3` represents the number `123`.
Return *the total sum of all root-to-leaf numbers*. Test cases are generated so that the answer will fit in a **32-bit** integer.
A **leaf** node is a node with no children.
### Examples

```
Input: root = [1,2,3]
Output: 25
Explanation:
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Therefore, sum = 12 + 13 = 25.
```

```
Input: root = [4,9,0,5,1]
Output: 1026
Explanation:
The root-to-leaf path 4->9->5 represents the number 495.
The root-to-leaf path 4->9->1 represents the number 491.
The root-to-leaf path 4->0 represents the number 40.
Therefore, sum = 495 + 491 + 40 = 1026.
```
### Constraints
* The number of nodes in the tree is in the range \[1, 1000]
* 0 \<= Node.val \<= 9
* The depth of the tree will not exceed 10
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_root_to_leaf_numbers/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/sum_root_to_leaf_numbers/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def sum_numbers(self, root: TreeNode[int] | None) -> int:
def dfs(node: TreeNode[int] | None, path_value: int) -> int:
if node is None:
return 0
path_value = path_value * 10 + node.val
if node.left is None and node.right is None:
return path_value
return dfs(node.left, path_value) + dfs(node.right, path_value)
return dfs(root, 0)
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Summary Ranges Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/summary-ranges
Tested Python solution for LeetCode 228 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 228, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/summary-ranges/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 228 # by problem number
lcpy gen -s summary_ranges # by problem name
```
## Problem
You are given a **sorted unique** integer array `nums`.
A **range** `[a,b]` is the set of all integers from `a` to `b` (inclusive).
Return *the **smallest sorted** list of ranges that **cover all the numbers in the array exactly***. That is, each element of `nums` is covered by exactly one of the ranges, and there is no integer `x` such that `x` is in one of the ranges but not in `nums`.
Each range `[a,b]` in the list should be output as:
* `"a->b"` if `a != b`
* `"a"` if `a == b`
### Examples
```
Input: nums = [0,1,2,4,5,7]
Output: ["0->2","4->5","7"]
```
**Explanation:** The ranges are:
\[0,2] --> "0->2"
\[4,5] --> "4->5"
\[7,7] --> "7"
```
Input: nums = [0,2,3,4,6,8,9]
Output: ["0","2->4","6","8->9"]
```
**Explanation:** The ranges are:
\[0,0] --> "0"
\[2,4] --> "2->4"
\[6,6] --> "6"
\[8,9] --> "8->9"
### Constraints
* `0 <= nums.length <= 20`
* `-2^31 <= nums[i] <= 2^31 - 1`
* All the values of `nums` are **unique**.
* `nums` is sorted in ascending order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/summary_ranges/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/summary_ranges/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1) excluding output
def summary_ranges(self, nums: list[int]) -> list[str]:
result: list[str] = []
i = 0
while i < len(nums):
start = nums[i]
while i + 1 < len(nums) and nums[i + 1] == nums[i] + 1:
i += 1
if start == nums[i]:
result.append(str(start))
else:
result.append(f"{start}->{nums[i]}")
i += 1
return result
```
## Complexity
| Time | Space |
| ---- | --------------------- |
| O(n) | O(1) excluding output |
## Tags
# Super Egg Drop Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/super-egg-drop
Tested Python solution for LeetCode 887 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 887, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/super-egg-drop/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 887 # by problem number
lcpy gen -s super_egg_drop # by problem name
```
## Problem
You are given `k` identical eggs and you have access to a building with `n` floors labeled from `1` to `n`.
You know that there exists a floor `f` where `0 <= f <= n` such that any egg dropped at a floor **higher** than `f` will **break**, and any egg dropped **at or below** floor `f` will **not break**.
Each move, you may take an unbroken egg and drop it from any floor `x` (where `1 <= x <= n`). If the egg breaks, you can no longer use it. However, if the egg does not break, you may **reuse** it in future moves.
Return *the **minimum number of moves** that you need to determine **with certainty** what the value of* `f` *is*.
### Examples
```
Input: k = 1, n = 2
Output: 2
Explanation:
Drop the egg from floor 1. If it breaks, we know that f = 0.
Otherwise, drop the egg from floor 2. If it breaks, we know that f = 1.
If it does not break, then we know f = 2.
Hence, we need at minimum 2 moves to determine with certainty what the value of f is.
```
```
Input: k = 2, n = 6
Output: 3
```
```
Input: k = 3, n = 14
Output: 4
```
### Constraints
* 1 \<= k \<= 100
* 1 \<= n \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_egg_drop/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_egg_drop/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(k * moves) where moves is the answer (moves <= n)
# Space: O(k)
def super_egg_drop(self, k: int, n: int) -> int:
# coverage[i] = number of floors distinguishable with i eggs in the
# current number of moves: coverage[i] = coverage[i] + coverage[i-1] + 1
coverage = [0] * (k + 1)
moves = 0
while coverage[k] < n:
moves += 1
for eggs in range(k, 0, -1):
coverage[eggs] += coverage[eggs - 1] + 1
return moves
```
## Complexity
| Time | Space |
| ----------------------------------------------------- | ----- |
| O(k \* moves) where moves is the answer (moves \<= n) | O(k) |
## Tags
# Super Palindromes Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/super-palindromes
Tested Python solution for LeetCode 906 with 33 pytest cases. Generate a practice environment with lcpy.
LeetCode 906, [Hard](/catalog/hard). Topics: [Math](/catalog/topics/math), [String](/catalog/topics/string), [Enumeration](/catalog/topics/enumeration). [View on LeetCode](https://leetcode.com/problems/super-palindromes/description/).
Generate this problem as a practice environment: tested reference solution, 33 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 906 # by problem number
lcpy gen -s super_palindromes # by problem name
```
## Problem
Let's say a positive integer is a **super-palindrome** if it is a palindrome, and it is also the square of a palindrome.
Given two positive integers \left\ and \right\ represented as strings, return \the number of \super-palindromes\ integers in the inclusive range\ \\[left, right]\.
### Examples
```
Input: left = "4", right = "1000"
Output: 4
Explanation: 4, 9, 121, and 484 are superpalindromes.
Note that 676 is not a superpalindrome: 26 * 26 = 676, but 26 is not a palindrome.
```
```
Input: left = "1", right = "2"
Output: 1
```
### Constraints
* 1 \<= left.length, right.length \<= 18
* left and right consist of only digits.
* left and right cannot have leading zeros.
* left and right represent integers in the range \[1, 10\18\ - 1].
* left is less than or equal to right.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_palindromes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_palindromes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(R^0.5 * log R) where R = int(right), over ~2 * 10^(d/2) palindrome roots
# Space: O(1)
def super_palindromes_in_range(self, left: str, right: str) -> int:
lo, hi = int(left), int(right)
count = 0
# Palindromic roots with up to 9 digits: their squares cover up to 10^18 - 1.
# Roots are visited in increasing order, so we can stop once we pass hi.
for length in range(1, 10):
half_len = (length + 1) // 2
for half in range(10 ** (half_len - 1), 10**half_len):
digits = str(half)
if length % 2 == 0:
root = int(digits + digits[::-1])
else:
root = int(digits + digits[-2::-1])
square = root * root
if square > hi:
return count
if square >= lo and str(square) == str(square)[::-1]:
count += 1
return count
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------------------- | ----- |
| O(R^0.5 \* log R) where R = int(right), over \~2 \* 10^(d/2) palindrome roots | O(1) |
## Tags
# Super Pow Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/super-pow
Tested Python solution for LeetCode 372 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 372, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Divide and Conquer](/catalog/topics/divide-and-conquer). [View on LeetCode](https://leetcode.com/problems/super-pow/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 372 # by problem number
lcpy gen -s super_pow # by problem name
```
## Problem
Your task is to calculate a\b\ mod 1337 where `a` is a positive integer and `b` is an extremely large positive integer given in the form of an array.
### Examples
```
Input: a = 2, b = [3]
Output: 8
```
```
Input: a = 2, b = [1,0]
Output: 1024
```
```
Input: a = 1, b = [4,3,3,8,5,2]
Output: 1
```
### Constraints
* 1 \<= a \<= 2^31 - 1
* 1 \<= b.length \<= 2000
* 0 \<= b\[i] \<= 9
* `b` does not contain leading zeros.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_pow/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_pow/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n) where n = len(b)
# Space: O(1)
def super_pow(self, a: int, b: list[int]) -> int:
mod = 1337
result = 1
a %= mod
for digit in b:
result = (pow(result, 10, mod) * pow(a, digit, mod)) % mod
return result
```
## Complexity
| Time | Space |
| --------------------- | ----- |
| O(n) where n = len(b) | O(1) |
## Tags
# Super Ugly Number Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/super-ugly-number
Tested Python solution for LeetCode 313 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 313, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/super-ugly-number/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 313 # by problem number
lcpy gen -s super_ugly_number # by problem name
```
## Problem
A **super ugly number** is a positive integer whose prime factors are in the array `primes`.
Given an integer `n` and an array of integers `primes`, return *the* `nth` ***super ugly number***.
The `nth` **super ugly number** is guaranteed to fit in a 32-bit signed integer.
### Examples
```
Input: n = 12, primes = [2,7,13,19]
Output: 32
Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12 super ugly numbers given primes = [2,7,13,19].
```
```
Input: n = 1, primes = [2,3,5]
Output: 1
Explanation: 1 has no prime factors, therefore all of its prime factors are in the array primes = [2,3,5].
```
### Constraints
* 1 \<= n \<= 10^5
* 1 \<= primes.length \<= 100
* 2 \<= primes\[i] \<= 1000
* primes\[i] is guaranteed to be a prime number.
* All the values of primes are unique and sorted in ascending order.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_ugly_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_ugly_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * k) where k = len(primes)
# Space: O(n + k)
def nth_super_ugly_number(self, n: int, primes: list[int]) -> int:
ugly = [0] * n
ugly[0] = 1
idx = [0] * len(primes)
candidates = list(primes)
for i in range(1, n):
nxt = min(candidates)
ugly[i] = nxt
for j, prime in enumerate(primes):
if candidates[j] == nxt:
idx[j] += 1
candidates[j] = ugly[idx[j]] * prime
return ugly[n - 1]
```
## Complexity
| Time | Space |
| ------------------------------- | -------- |
| O(n \* k) where k = len(primes) | O(n + k) |
## Tags
# Super Washing Machines Python Solution
Source: https://leetcode-py.wisl.dev/problems/super-washing-machines
Tested Python solution for LeetCode 517 with 17 pytest cases. Generate a practice environment with lcpy.
LeetCode 517, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/super-washing-machines/description/).
Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 517 # by problem number
lcpy gen -s super_washing_machines # by problem name
```
## Problem
You have `n` super washing machines on a line. Initially, each washing machine has some dresses or is empty.
For each move, you could choose any `m` (`1 <= m <= n`) washing machines, and pass one dress of each washing machine to one of its adjacent washing machines at the same time.
Given an integer array `machines` representing the number of dresses in each washing machine from left to right on the line, return the minimum number of moves to make all the washing machines have the same number of dresses. If it is not possible to do it, return `-1`.
### Examples
```
Input: machines = [1,0,5]
Output: 3
Explanation:
1st move: 1 0 <-- 5 => 1 1 4
2nd move: 1 <-- 1 <-- 4 => 2 1 3
3rd move: 2 1 <-- 3 => 2 2 2
```
```
Input: machines = [0,3,0]
Output: 2
Explanation:
1st move: 0 <-- 3 0 => 1 2 0
2nd move: 1 2 --> 0 => 1 1 1
```
```
Input: machines = [0,2,0]
Output: -1
Explanation:
It's impossible to make all three washing machines have the same number of dresses.
```
### Constraints
* n == machines.length
* 1 \<= n \<= 10^4
* 0 \<= machines\[i] \<= 10^5
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_washing_machines/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/super_washing_machines/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def find_min_moves(self, machines: list[int]) -> int:
n = len(machines)
total = sum(machines)
if total % n != 0:
return -1
target = total // n
moves = 0
balance = 0
for count in machines:
diff = count - target
balance += diff
moves = max(moves, abs(balance), diff)
return moves
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Surface Area of 3D Shapes Python Solution
Source: https://leetcode-py.wisl.dev/problems/surface-area-of-3d-shapes
Tested Python solution for LeetCode 892 with 23 pytest cases. Generate a practice environment with lcpy.
LeetCode 892, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/surface-area-of-3d-shapes/description/).
Generate this problem as a practice environment: tested reference solution, 23 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 892 # by problem number
lcpy gen -s surface_area_of_3d_shapes # by problem name
```
## Problem
You are given an `n x n` `grid` where you have placed some `1 x 1 x 1` cubes. Each value `v = grid[i][j]` represents a tower of `v` cubes placed on top of cell `(i, j)`.
After placing these cubes, you have decided to glue any directly adjacent cubes to each other, forming several irregular 3D shapes.
Return the total surface area of the resulting shapes.
Note: The bottom face of each shape counts toward its surface area.
### Examples

```
Input: grid = [[1,2],[3,4]]
Output: 34
```

```
Input: grid = [[1,1,1],[1,0,1],[1,1,1]]
Output: 32
```

```
Input: grid = [[2,2,2],[2,1,2],[2,2,2]]
Output: 46
```
### Constraints
* n == grid.length == grid\[i].length
* 1 \<= n \<= 50
* 0 \<= grid\[i]\[j] \<= 50
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/surface_area_of_3d_shapes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/surface_area_of_3d_shapes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2) every cell inspected once with its four neighbours
# Space: O(1)
def surface_area(self, grid: list[list[int]]) -> int:
size = len(grid)
area = 0
for row in range(size):
for col in range(size):
height = grid[row][col]
if height == 0:
continue
# Top and bottom faces are always exposed for a non-empty tower.
area += 2
# Four side faces per cube, minus what a neighbour hides.
area += 4 * height
for d_row, d_col in ((-1, 0), (1, 0), (0, -1), (0, 1)):
n_row, n_col = row + d_row, col + d_col
if 0 <= n_row < size and 0 <= n_col < size:
area -= min(height, grid[n_row][n_col])
return area
```
## Complexity
| Time | Space |
| --------------------------------------------------------- | ----- |
| O(n^2) every cell inspected once with its four neighbours | O(1) |
## Tags
# Surrounded Regions Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/surrounded-regions
Tested Python solution for LeetCode 130 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 130, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/surrounded-regions/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 130 # by problem number
lcpy gen -s surrounded_regions # by problem name
```
## Problem
You are given an `m x n` matrix `board` containing letters `'X'` and `'O'`, capture regions that are surrounded:
* **Connect**: A cell is connected to adjacent cells horizontally or vertically.
* **Region**: To form a region connect every `'O'` cell.
* **Surround**: A region is surrounded if none of the `'O'` cells in the region are on the edge of the `board`. Such regions are completely enclosed by `'X'` cells.
To capture a surrounded region, replace all `'O'`s with `'X'`s **in-place** within the original `board`. You do not need to return anything.
### Examples

```
Input: board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
Output: [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
Explanation: Notice that an 'O' should not be flipped if it is on the border of the board.
```
```
Input: board = [["X"]]
Output: [["X"]]
```
### Constraints
* m == board.length
* n == board\[i].length
* 1 \<= m, n \<= 200
* board\[i]\[j] is 'X' or 'O'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/surrounded_regions/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/surrounded_regions/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import deque
class Solution:
# Time: O(m * n)
# Space: O(m * n) for the border-connected queue in the worst case
def solve(self, board: list[list[str]]) -> None:
if not board or not board[0]:
return
m, n = len(board), len(board[0])
queue: deque[tuple[int, int]] = deque()
def enqueue(i: int, j: int) -> None:
if board[i][j] == "O":
board[i][j] = "#"
queue.append((i, j))
# Seed from all border cells
for i in range(m):
enqueue(i, 0)
enqueue(i, n - 1)
for j in range(n):
enqueue(0, j)
enqueue(m - 1, j)
# BFS: mark every 'O' reachable from a border (cannot be captured)
while queue:
i, j = queue.popleft()
for di, dj in ((1, 0), (-1, 0), (0, 1), (0, -1)):
ni, nj = i + di, j + dj
if 0 <= ni < m and 0 <= nj < n and board[ni][nj] == "O":
board[ni][nj] = "#"
queue.append((ni, nj))
# '#' = safe border-connected 'O'; everything else enclosed gets captured
for i in range(m):
for j in range(n):
board[i][j] = "O" if board[i][j] == "#" else "X"
```
## Complexity
| Time | Space |
| --------- | ---------------------------------------------------------- |
| O(m \* n) | O(m \* n) for the border-connected queue in the worst case |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Swap Adjacent in LR String Python Solution
Source: https://leetcode-py.wisl.dev/problems/swap-adjacent-in-lr-string
Tested Python solution for LeetCode 777 with 31 pytest cases. Generate a practice environment with lcpy.
LeetCode 777, [Medium](/catalog/medium). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/swap-adjacent-in-lr-string/description/).
Generate this problem as a practice environment: tested reference solution, 31 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 777 # by problem number
lcpy gen -s swap_adjacent_in_lr_string # by problem name
```
## Problem
In a string composed of `'L'`, `'R'`, and `'X'` characters, like `"RXXLRXRXL"`, a move consists of either replacing one occurrence of `"XL"` with `"LX"`, or replacing one occurrence of `"RX"` with `"XR"`. Given the starting string `start` and the ending string `result`, return `True` if and only if there exists a sequence of moves to transform `start` to `result`.
### Examples
```
Input: start = "RXXLRXRXL", result = "XRLXXRRLX"
Output: true
Explanation: We can transform start to result following these steps:
RXXLRXRXL ->
XRXLRXRXL ->
XRLXRXRXL ->
XRLXXRRXL ->
XRLXXRRLX
```
```
Input: start = "X", result = "L"
Output: false
```
### Constraints
* `1 <= start.length <= 10^4`
* `start.length == result.length`
* Both `start` and `result` will only consist of characters in `'L'`, `'R'`, and `'X'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swap_adjacent_in_lr_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swap_adjacent_in_lr_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def can_transform(self, start: str, result: str) -> bool:
if len(start) != len(result):
return False
if start.replace("X", "") != result.replace("X", ""):
return False
i = 0
j = 0
n = len(start)
while i < n and j < n:
while i < n and start[i] == "X":
i += 1
while j < n and result[j] == "X":
j += 1
if i == n or j == n:
break
if start[i] != result[j]:
return False
# 'L' can only move left, 'R' can only move right
if (start[i] == "L" and i < j) or (start[i] == "R" and i > j):
return False
i += 1
j += 1
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Swap Nodes in Pairs Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/swap-nodes-in-pairs
Tested Python solution for LeetCode 24 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 24, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Recursion](/catalog/topics/recursion). [View on LeetCode](https://leetcode.com/problems/swap-nodes-in-pairs/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 24 # by problem number
lcpy gen -s swap_nodes_in_pairs # by problem name
```
## Problem
Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
### Examples

```
Input: head = [1,2,3,4]
Output: [2,1,4,3]
```
```
Input: head = []
Output: []
```
```
Input: head = [1]
Output: [1]
```
```
Input: head = [1,2,3]
Output: [2,1,3]
```
### Constraints
* The number of nodes in the list is in the range `[0, 100]`.
* `0 <= Node.val <= 100`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swap_nodes_in_pairs/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swap_nodes_in_pairs/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n) - traverse each node once
# Space: O(1) - constant extra space
def swap_pairs(self, head: ListNode[int] | None) -> ListNode[int] | None:
# Create dummy node to simplify edge cases
dummy = ListNode(0)
dummy.next = head
prev = dummy
# Process pairs while they exist
while prev.next and prev.next.next:
# Identify nodes to swap
first = prev.next
second = prev.next.next
# Perform swap: prev -> second -> first -> ...
prev.next = second
first.next = second.next
second.next = first
# Move prev to end of swapped pair
prev = first
return dummy.next
```
## Complexity
| Time | Space |
| ------------------------------ | --------------------------- |
| O(n) - traverse each node once | O(1) - constant extra space |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Swapping Nodes in a Linked List
Source: https://leetcode-py.wisl.dev/problems/swapping-nodes-in-a-linked-list
Tested Python solution for LeetCode 1721 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 1721, [Medium](/catalog/medium). Topics: [Linked List](/catalog/topics/linked-list), [Two Pointers](/catalog/topics/two-pointers). [View on LeetCode](https://leetcode.com/problems/swapping-nodes-in-a-linked-list/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1721 # by problem number
lcpy gen -s swapping_nodes_in_a_linked_list # by problem name
```
## Problem
You are given the `head` of a linked list, and an integer `k`.
Return *the head of the linked list after **swapping** the values of the `kth` node from the beginning and the `kth` node from the end (the list is **1-indexed**)*.
### Examples

```
Input: head = [1,2,3,4,5], k = 2
Output: [1,4,3,2,5]
```
```
Input: head = [7,9,6,6,7,8,3,0,9,5], k = 5
Output: [7,9,6,6,8,7,3,0,9,5]
```
### Constraints
* The number of nodes in the list is `n`.
* `1 <= k <= n <= 10^5`
* `0 <= Node.val <= 100`
**Follow up:** Could you do this in one pass?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swapping_nodes_in_a_linked_list/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swapping_nodes_in_a_linked_list/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import ListNode
class Solution:
# Time: O(n)
# Space: O(1)
def swap_nodes(self, head: ListNode[int] | None, k: int) -> ListNode[int] | None:
if head is None:
return head
n = 1
node = head
while node.next is not None:
node = node.next
n += 1
first = head
for _ in range(k - 1):
if first.next is None:
break
first = first.next
second = head
for _ in range(n - k):
if second.next is None:
break
second = second.next
first.val, second.val = second.val, first.val
return head
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Swim in Rising Water Python Solution
Source: https://leetcode-py.wisl.dev/problems/swim-in-rising-water
Tested Python solution for LeetCode 778 with 13 pytest cases. Generate a practice environment with lcpy.
LeetCode 778, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Binary Search](/catalog/topics/binary-search), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union-Find](/catalog/topics/union-find), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/swim-in-rising-water/description/).
Generate this problem as a practice environment: tested reference solution, 13 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 778 # by problem number
lcpy gen -s swim_in_rising_water # by problem name
```
## Problem
You are given an `n x n` integer matrix `grid` where each value `grid[i][j]` represents the elevation at that point `(i, j)`.
It starts raining, and water gradually rises over time. At time `t`, the water level is `t`, meaning **any** cell with elevation less than equal to `t` is submerged or reachable.
You can swim from a square to another 4-directionally adjacent square if and only if the elevation of both squares individually are at most `t`. You can swim infinite distances in zero time. Of course, you must stay within the boundaries of the grid during your swim.
Return *the minimum time until you can reach the bottom right square* `(n - 1, n - 1)` *if you start at the top left square* `(0, 0)`.
### Examples

```
Input: grid = [[0,2],[1,3]]
Output: 3
Explanation:
At time 0, you are in grid location (0, 0).
You cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t = 0.
You cannot reach point (1, 1) until time 3.
When the depth of water is 3, we can swim anywhere inside the grid.
```

```
Input: grid = [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
Output: 16
Explanation: The final route is shown.
We need to wait until time 16 so that (0, 0) and (4, 4) are connected.
```
### Constraints
* n == grid.length
* n == grid\[i].length
* 1 \<= n \<= 50
* 0 \<= grid\[i]\[j] \< n\2\
* Each value grid\[i]\[j] is **unique**.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swim_in_rising_water/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/swim_in_rising_water/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(n^2 log n)
# Space: O(n^2)
def swim_in_water(self, grid: list[list[int]]) -> int:
n = len(grid)
# Minimize the maximum elevation encountered along the path.
min_time: list[list[int | float]] = [[float("inf")] * n for _ in range(n)]
min_time[0][0] = grid[0][0]
# (cost, row, col) where cost = max elevation on path so far
min_heap: list[tuple[int, int, int]] = [(grid[0][0], 0, 0)]
while min_heap:
time, row, col = heapq.heappop(min_heap)
if row == n - 1 and col == n - 1:
return time
if time > min_time[row][col]:
continue
for delta_row, delta_col in ((0, 1), (0, -1), (1, 0), (-1, 0)):
next_row, next_col = row + delta_row, col + delta_col
if 0 <= next_row < n and 0 <= next_col < n:
arrival = max(time, grid[next_row][next_col])
if arrival < min_time[next_row][next_col]:
min_time[next_row][next_col] = arrival
heapq.heappush(min_heap, (arrival, next_row, next_col))
return -1
```
## Complexity
| Time | Space |
| ------------ | ------ |
| O(n^2 log n) | O(n^2) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Symmetric Tree Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/symmetric-tree
Tested Python solution for LeetCode 101 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 101, [Easy](/catalog/easy). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/symmetric-tree/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 101 # by problem number
lcpy gen -s symmetric_tree # by problem name
```
## Problem
Given the `root` of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).
### Examples

```
Input: root = [1,2,2,3,4,4,3]
Output: true
```

```
Input: root = [1,2,2,null,3,null,3]
Output: false
```
### Constraints
* The number of nodes in the tree is in the range \[1, 1000].
* -100 \<= Node.val \<= 100
**Follow up:** Could you solve it both recursively and iteratively?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/symmetric_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/symmetric_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n) — each node visited once
# Space: O(h) recursion stack, h = tree height
def is_symmetric(self, root: TreeNode[int] | None) -> bool:
def mirror(a: TreeNode[int] | None, b: TreeNode[int] | None) -> bool:
if a is None or b is None:
return a is b
return a.val == b.val and mirror(a.left, b.right) and mirror(a.right, b.left)
return mirror(root.left, root.right) if root else True
```
## Complexity
| Time | Space |
| ----------------------------- | ------------------------------------- |
| O(n) — each node visited once | O(h) recursion stack, h = tree height |
## Tags
[Grind](/catalog/grind), [NeetCode All](/catalog/neetcode).
# Synonymous Sentences Python Solution
Source: https://leetcode-py.wisl.dev/problems/synonymous-sentences
Tested Python solution for LeetCode 1258 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 1258, [Medium](/catalog/medium). Topics: Sort, [Union Find](/catalog/topics/union-find), [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Backtracking](/catalog/topics/backtracking). [View on LeetCode](https://leetcode.com/problems/synonymous-sentences/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1258 # by problem number
lcpy gen -s synonymous_sentences # by problem name
```
## Problem
You are given a list of equivalent string pairs `synonyms` where `synonyms[i] = [si, ti]` indicates that `si` and `ti` are equivalent strings. You are also given a sentence `text`.
Return all possible synonymous sentences **sorted lexicographically**.
### Examples
```
Input: synonyms = [["happy","joy"],["sad","sorrow"],["joy","cheerful"]], text = "I am happy today but was sad yesterday"
Output: ["I am cheerful today but was sad yesterday","I am cheerful today but was sorrow yesterday","I am happy today but was sad yesterday","I am happy today but was sorrow yesterday","I am joy today but was sad yesterday","I am joy today but was sorrow yesterday"]
Explanation: From the synonyms, happy, joy and cheerful are equivalent, and sad and sorrow are equivalent. Replacing each synonymous word independently gives 2 * 3 = 6 sentences.
```
```
Input: synonyms = [["happy","joy"],["cheerful","glad"]], text = "I am happy today but was sad yesterday"
Output: ["I am happy today but was sad yesterday","I am joy today but was sad yesterday"]
```
### Constraints
* `0 <= synonyms.length <= 10`
* `synonyms[i].length == 2`
* `1 <= si.length, ti.length <= 10`
* `si != ti`
* `text` consists of at most `10` words.
* All the pairs of `synonyms` are **unique**.
* The words of `text` are separated by single spaces.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/synonymous_sentences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/synonymous_sentences/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class UnionFind:
def __init__(self, n: int):
self.parent: list[int] = list(range(n))
self.size: list[int] = [1] * n
def find(self, x: int) -> int:
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, a: int, b: int) -> None:
root_a, root_b = self.find(a), self.find(b)
if root_a == root_b:
return
if self.size[root_a] < self.size[root_b]:
root_a, root_b = root_b, root_a
self.parent[root_b] = root_a
self.size[root_a] += self.size[root_b]
class Solution:
# Time: O((s + w) * n)
# Space: O(s + w)
def generate_sentences(self, synonyms: list[list[str]], text: str) -> list[str]:
words = sorted({word for pair in synonyms for word in pair})
index = {word: i for i, word in enumerate(words)}
uf = UnionFind(len(words))
for first, second in synonyms:
uf.union(index[first], index[second])
groups: dict[int, list[str]] = {}
for word in words:
groups.setdefault(uf.find(index[word]), []).append(word)
sentence = text.split()
result: list[str] = []
current: list[str] = []
def dfs(i: int) -> None:
if i == len(sentence):
result.append(" ".join(current))
return
word = sentence[i]
if word in index:
for alt in groups[uf.find(index[word])]:
current.append(alt)
dfs(i + 1)
current.pop()
else:
current.append(word)
dfs(i + 1)
current.pop()
dfs(0)
return sorted(result)
```
## Complexity
| Time | Space |
| --------------- | -------- |
| O((s + w) \* n) | O(s + w) |
## Tags
[NeetCode All](/catalog/neetcode).
# Tag Validator Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/tag-validator
Tested Python solution for LeetCode 591 with 30 pytest cases. Generate a practice environment with lcpy.
LeetCode 591, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/tag-validator/description/).
Generate this problem as a practice environment: tested reference solution, 30 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 591 # by problem number
lcpy gen -s tag_validator # by problem name
```
## Problem
Given a string representing a code snippet, implement a tag validator to parse the code and return whether it is valid.
A code snippet is valid if all the following rules hold:
1. The code must be wrapped in a **valid closed tag**. Otherwise, the code is invalid.
2. A **closed tag** (not necessarily valid) has exactly the following format : `n\ persons numbered from \0\ to \n - 1\ and a door. Each person can enter or exit through the door once, taking one second.\
\You are given a \non-decreasing\ integer array \arrival\ of size \n\, where \arrival\[i]\ is the arrival time of the \i\th\\ person at the door. You are also given an array \state\ of size \n\, where \state\[i]\ is \0\ if person \i\ wants to enter through the door or \1\ if they want to exit through the door.\
If two or more persons want to use the door at the \same\ time, they follow the following rules:\
\Return \an array \\answer\\ of size \\n\\ where \\answer\[i]\\ is the second at which the \i\th\\ person crosses the door\.\
\Note\ that:\
\nums\, return \the sum of \Hamming distances\ between all the pairs of the integers in\ \nums\.
### Examples
```
Input: nums = [4,14,2]
Output: 6
Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just
showing the four bits relevant in this case).
The answer will be:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.
```
```
Input: nums = [4,14,4]
Output: 4
```
### Constraints
* `1 <= nums.length <= 10^4`
* `0 <= nums[i] <= 10^9`
* The answer for the given input will fit in a **32-bit** integer.
**Follow up:** Could you solve this problem with a linear runtime?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/total_hamming_distance/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/total_hamming_distance/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n * b) where b is the number of bits (32)
# Space: O(1)
def total_hamming_distance(self, nums: list[int]) -> int:
total = 0
for bit in range(32):
ones = sum((num >> bit) & 1 for num in nums)
total += ones * (len(nums) - ones)
return total
```
## Complexity
| Time | Space |
| -------------------------------------------- | ----- |
| O(n \* b) where b is the number of bits (32) | O(1) |
## Tags
# Traffic Light Controlled Intersection
Source: https://leetcode-py.wisl.dev/problems/traffic-light-controlled-intersection
Tested Python solution for LeetCode 1279 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 1279, [Easy](/catalog/easy). Topics: Concurrency, [Design](/catalog/topics/design). [View on LeetCode](https://leetcode.com/problems/traffic-light-controlled-intersection/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1279 # by problem number
lcpy gen -s traffic_light_controlled_intersection # by problem name
```
## Problem
There is an intersection of two roads. First road is road A where cars travel from North to South in direction 1 and from South to North in direction 2. Second road is road B where cars travel from West to East in direction 3 and from East to West in direction 4.

There is a traffic light located on each road before the intersection. A traffic light can either be green or red.
* **Green** means cars can cross the intersection in both directions of the road.
* **Red** means cars in both directions cannot cross the intersection and must wait until the light turns green.
The traffic lights cannot be green on both roads at the same time. That means when the light is green on road A, it is red on road B and when the light is green on road B, it is red on road A.
Initially, the traffic light is **green** on road A and **red** on road B. When the light is green on one road, all cars can cross the intersection in both directions until the light becomes green on the other road. No two cars traveling on different roads should cross at the same time.
Design a deadlock-free traffic light controlled system at this intersection.
Implement the function `car_arrived(car_id, road_id, direction, turn_green, cross_car)` where:
* `car_id` is the id of the car that arrived.
* `road_id` is the id of the road that the car travels on. Can be 1 (road A) or 2 (road B).
* `direction` is the direction of the car.
* `turn_green` is a function you can call to turn the traffic light to green on the current road.
* `cross_car` is a function you can call to let the current car cross the intersection.
### Examples
```
Input: cars = [1,3,5,2,4], directions = [2,1,2,4,3], arrivalTimes = [10,20,30,40,50]
Output: [
"Car 1 Has Passed Road A In Direction 2", // Traffic light on road A is green, car 1 can cross the intersection.
"Car 3 Has Passed Road A In Direction 1", // Car 3 crosses the intersection as the light is still green.
"Car 5 Has Passed Road A In Direction 2", // Car 5 crosses the intersection as the light is still green.
"Traffic Light On Road B Is Green", // Car 2 requests green light for road B.
"Car 2 Has Passed Road B In Direction 4", // Car 2 crosses as the light is green on road B now.
"Car 4 Has Passed Road B In Direction 3" // Car 4 crosses the intersection as the light is still green.
]
```
```
Input: cars = [1,2,3,4,5], directions = [2,4,3,3,1], arrivalTimes = [10,20,30,40,40]
Output: [
"Car 1 Has Passed Road A In Direction 2",
"Traffic Light On Road B Is Green",
"Car 2 Has Passed Road B In Direction 4",
"Car 3 Has Passed Road B In Direction 3",
"Traffic Light On Road A Is Green",
"Car 5 Has Passed Road A In Direction 1",
"Traffic Light On Road B Is Green",
"Car 4 Has Passed Road B In Direction 3"
]
```
### Constraints
* `1 <= cars.length <= 20`
* `cars.length = directions.length`
* `cars.length = arrivalTimes.length`
* All values of `cars` are unique
* `1 <= directions[i] <= 4`
* `arrivalTimes` is non-decreasing
**Your answer is considered correct if it avoids cars deadlock in the intersection. Turning the light green on a road when it was already green is considered a wrong answer.**
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/traffic_light_controlled_intersection/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/traffic_light_controlled_intersection/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections.abc import Callable
from threading import Lock
class TrafficLight:
# Time: O(1) per car
# Space: O(1)
def __init__(self) -> None:
self.lock = Lock()
self.road = 1
def car_arrived(
self,
car_id: int,
road_id: int,
direction: int,
turn_green: Callable[[], None],
cross_car: Callable[[], None],
) -> None:
with self.lock:
if self.road != road_id:
turn_green()
self.road = road_id
cross_car()
```
## Complexity
| Time | Space |
| ------------ | ----- |
| O(1) per car | O(1) |
## Tags
# Transform to Chessboard Python Solution
Source: https://leetcode-py.wisl.dev/problems/transform-to-chessboard
Tested Python solution for LeetCode 782 with 27 pytest cases. Generate a practice environment with lcpy.
LeetCode 782, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/transform-to-chessboard/description/).
Generate this problem as a practice environment: tested reference solution, 27 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 782 # by problem number
lcpy gen -s transform_to_chessboard # by problem name
```
## Problem
You are given an `n x n` binary grid `board`. In each move, you can swap any two rows with each other, or any two columns with each other.
Return the minimum number of moves to transform the board into a chessboard board. If the task is impossible, return `-1`.
A chessboard board is a board where no `0`'s and no `1`'s are 4-directionally adjacent.
### Examples

```
Input: board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]]
Output: 2
Explanation: One potential sequence of moves is shown.
The first move swaps the first and second column.
The second move swaps the second and third row.
```

```
Input: board = [[0,1],[1,0]]
Output: 0
Explanation: Also note that the board with 0 in the top left corner, is also a valid chessboard.
```

```
Input: board = [[1,0],[1,0]]
Output: -1
Explanation: No matter what sequence of moves you make, you cannot end with a valid chessboard.
```
### Constraints
* n == board.length
* n == board\[i].length
* 2 \<= n \<= 30
* board\[i]\[j] is either 0 or 1.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/transform_to_chessboard/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/transform_to_chessboard/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def _line_swaps(masks: list[int], n: int) -> int:
"""Min swaps to make one axis alternate, or -1 if that axis cannot."""
full = (1 << n) - 1
first = masks[0]
if set(masks) != {first, full ^ first}:
return -1
ones = bin(first).count("1")
if ones * 2 not in (n - 1, n, n + 1):
return -1
count_first = masks.count(first)
if abs(count_first - (n - count_first)) > 1:
return -1
need_even = (n + 1) // 2
best = -1
for even_mask in (first, full ^ first):
if masks.count(even_mask) != need_even:
continue
target = [even_mask if i % 2 == 0 else full ^ even_mask for i in range(n)]
misplaced = sum(1 for i in range(n) if masks[i] != target[i])
swaps = misplaced // 2
best = swaps if best < 0 else min(best, swaps)
return best
class Solution:
# Time: O(n^2)
# Space: O(n)
def moves_to_chessboard(self, board: list[list[int]]) -> int:
n = len(board)
rows = [sum(cell << j for j, cell in enumerate(row)) for row in board]
cols = [sum(board[i][j] << i for i in range(n)) for j in range(n)]
total = 0
for masks in (rows, cols):
swaps = _line_swaps(masks, n)
if swaps < 0:
return -1
total += swaps
return total
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
# Transpose Matrix Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/transpose-matrix
Tested Python solution for LeetCode 867 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 867, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/transpose-matrix/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 867 # by problem number
lcpy gen -s transpose_matrix # by problem name
```
## Problem
Given a 2D integer array `matrix`, return *the **transpose** of* `matrix`.
The **transpose** of a matrix is the matrix flipped over its main diagonal, switching the matrix's row and column indices.
### Examples

```
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[1,4,7],[2,5,8],[3,6,9]]
```
```
Input: matrix = [[1,2,3],[4,5,6]]
Output: [[1,4],[2,5],[3,6]]
```
### Constraints
* m == matrix.length
* n == matrix\[i].length
* 1 \<= m, n \<= 1000
* 1 \<= m \* n \<= 10^5
* -10^9 \<= matrix\[i]\[j] \<= 10^9
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/transpose_matrix/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/transpose_matrix/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(m * n)
def transpose(self, matrix: list[list[int]]) -> list[list[int]]:
rows = len(matrix)
cols = len(matrix[0])
return [[matrix[row][col] for row in range(rows)] for col in range(cols)]
```
## Complexity
| Time | Space |
| --------- | --------- |
| O(m \* n) | O(m \* n) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Trapping Rain Water Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/trapping-rain-water
Tested Python solution for LeetCode 42 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 42, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Dynamic Programming](/catalog/topics/dynamic-programming), [Stack](/catalog/topics/stack), [Monotonic Stack](/catalog/topics/monotonic-stack). [View on LeetCode](https://leetcode.com/problems/trapping-rain-water/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 42 # by problem number
lcpy gen -s trapping_rain_water # by problem name
```
## Problem
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.
### Examples

```
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
```
**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.
```
Input: height = [4,2,0,3,2,5]
Output: 9
```
### Constraints
* `n == height.length`
* `1 <= n <= 2 * 10^4`
* `0 <= height[i] <= 10^5`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/trapping_rain_water/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/trapping_rain_water/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def trap(self, height: list[int]) -> int:
if not height:
return 0
left, right = 0, len(height) - 1
left_max = right_max = water = 0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
water += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
water += right_max - height[right]
right -= 1
return water
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Trapping Rain Water II Python Solution
Source: https://leetcode-py.wisl.dev/problems/trapping-rain-water-ii
Tested Python solution for LeetCode 407 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 407, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Heap (Priority Queue)](/catalog/topics/heap-priority-queue), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/trapping-rain-water-ii/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 407 # by problem number
lcpy gen -s trapping_rain_water_ii # by problem name
```
## Problem
Given an `m x n` integer matrix `heightMap` representing the height of each unit cell in a 2D elevation map, return *the volume of water it can trap after raining*.
### Examples

```
Input: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
Output: 4
Explanation: After the rain, water is trapped between the blocks.
We have two small ponds 1 and 3 units trapped.
The total volume of water trapped is 4.
```

```
Input: heightMap = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]]
Output: 10
```
### Constraints
* `m == heightMap.length`
* `n == heightMap[i].length`
* `1 <= m, n <= 200`
* `0 <= heightMap[i][j] <= 2 * 10^4`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/trapping_rain_water_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/trapping_rain_water_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heapq
class Solution:
# Time: O(m*n*log(m*n))
# Space: O(m*n)
def trap_rain_water(self, height_map: list[list[int]]) -> int:
m, n = len(height_map), len(height_map[0])
if m < 3 or n < 3:
return 0
visited = [[False] * n for _ in range(m)]
heap: list[tuple[int, int, int]] = []
for i in range(m):
for j in (0, n - 1):
heapq.heappush(heap, (height_map[i][j], i, j))
visited[i][j] = True
for j in range(n):
for i in (0, m - 1):
if not visited[i][j]:
heapq.heappush(heap, (height_map[i][j], i, j))
visited[i][j] = True
total = 0
while heap:
wall, i, j = heapq.heappop(heap)
for di, dj in ((1, 0), (-1, 0), (0, 1), (0, -1)):
ni, nj = i + di, j + dj
if 0 <= ni < m and 0 <= nj < n and not visited[ni][nj]:
visited[ni][nj] = True
total += max(0, wall - height_map[ni][nj])
heapq.heappush(heap, (max(wall, height_map[ni][nj]), ni, nj))
return total
```
## Complexity
| Time | Space |
| ---------------- | ------- |
| O(m*n*log(m\*n)) | O(m\*n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Tree Diameter Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/tree-diameter
Tested Python solution for LeetCode 1245 with 25 pytest cases. Generate a practice environment with lcpy.
LeetCode 1245, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Graph](/catalog/topics/graph), [Topological Sort](/catalog/topics/topological-sort). [View on LeetCode](https://leetcode.com/problems/tree-diameter/description/).
Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1245 # by problem number
lcpy gen -s tree_diameter # by problem name
```
## Problem
The **diameter** of a tree is **the number of edges** in the longest path in that tree.
There is an undirected tree of `n` nodes labeled from `0` to `n - 1`. You are given a 2D array `edges` where `edges.length == n - 1` and `edges[i] = [ai, bi]` indicates that there is an undirected edge between nodes `ai` and `bi` in the tree.
Return **the diameter** of the tree.
### Examples

```
Input: edges = [[0,1],[0,2]]
Output: 2
```
**Explanation:** The longest path of the tree is the path 1 - 0 - 2.

```
Input: edges = [[0,1],[1,2],[2,3],[1,4],[4,5]]
Output: 4
```
**Explanation:** The longest path of the tree is the path 3 - 2 - 1 - 4 - 5.
### Constraints
* `n == edges.length + 1`
* `1 <= n <= 10^4`
* `0 <= ai, bi < n`
* `ai != bi`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/tree_diameter/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/tree_diameter/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict, deque
class Solution:
# Time: O(n)
# Space: O(n)
def tree_diameter(self, edges: list[list[int]]) -> int:
if not edges:
return 0
graph: dict[int, list[int]] = defaultdict(list)
for a, b in edges:
graph[a].append(b)
graph[b].append(a)
def bfs_farthest(src: int) -> tuple[int, int]:
dist = {src: 0}
queue: deque[int] = deque([src])
far_node, far_dist = src, 0
while queue:
node = queue.popleft()
for nxt in graph[node]:
if nxt not in dist:
dist[nxt] = dist[node] + 1
if dist[nxt] > far_dist:
far_dist = dist[nxt]
far_node = nxt
queue.append(nxt)
return far_node, far_dist
end, _ = bfs_farthest(edges[0][0])
_, diameter = bfs_farthest(end)
return diameter
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Triangle Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/triangle
Tested Python solution for LeetCode 120 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 120, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/triangle/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 120 # by problem number
lcpy gen -s triangle # by problem name
```
## Problem
Given a `triangle` array, return *the minimum path sum from top to bottom*.
For each step, you may move to an adjacent number of the row below. More formally, if you are on index `i` on the current row, you may move to either index `i` or index `i + 1` on the next row.
### Examples
```
Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: The triangle looks like:
2
3 4
6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).
```
```
Input: triangle = [[-10]]
Output: -10
```
### Constraints
* 1 \<= triangle.length \<= 200
* triangle\[0].length == 1
* triangle\[i].length == triangle\[i - 1].length + 1
* -10^4 \<= triangle\[i]\[j] \<= 10^4
**Follow up:** Could you do this using only `O(n)` extra space, where `n` is the total number of rows in the triangle?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/triangle/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/triangle/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def minimum_total(self, triangle: list[list[int]]) -> int:
dp = triangle[-1][:]
for row in range(len(triangle) - 2, -1, -1):
for col in range(row + 1):
dp[col] = triangle[row][col] + min(dp[col], dp[col + 1])
return dp[0]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Trim a Binary Search Tree Python Solution
Source: https://leetcode-py.wisl.dev/problems/trim-a-binary-search-tree
Tested Python solution for LeetCode 669 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 669, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/trim-a-binary-search-tree/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 669 # by problem number
lcpy gen -s trim_a_binary_search_tree # by problem name
```
## Problem
Given the root of a binary search tree and the lowest and highest boundaries as `low` and `high`, trim the tree so that all its elements lies in `[low, high]`. Trimming the tree should not change the relative structure of the elements that will remain in the tree (i.e., any node's descendant should remain a descendant). It can be proven that there is a unique answer.
Return the root of the trimmed binary search tree. Note that the root may change depending on the given bounds.
### Examples

```
Input: root = [1,0,2], low = 1, high = 2
Output: [1,null,2]
```

```
Input: root = [3,0,4,null,2,null,null,1], low = 1, high = 3
Output: [3,2,null,1]
```
### Constraints
* The number of nodes in the tree is in the range \[1, 10^4].
* 0 \<= Node.val \<= 10^4
* The value of each node in the tree is unique.
* root is guaranteed to be a valid binary search tree.
* 0 \<= low \<= high \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/trim_a_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/trim_a_binary_search_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def trim_bst(self, root: TreeNode[int] | None, low: int, high: int) -> TreeNode[int] | None:
if root is None:
return None
if root.val < low:
return self.trim_bst(root.right, low, high)
if root.val > high:
return self.trim_bst(root.left, low, high)
root.left = self.trim_bst(root.left, low, high)
root.right = self.trim_bst(root.right, low, high)
return root
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
[NeetCode All](/catalog/neetcode).
# Triples with Bitwise AND Equal To Zero
Source: https://leetcode-py.wisl.dev/problems/triples-with-bitwise-and-equal-to-zero
Tested Python solution for LeetCode 982 with 22 pytest cases. Generate a practice environment with lcpy.
LeetCode 982, [Hard](/catalog/hard). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/description/).
Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 982 # by problem number
lcpy gen -s triples_with_bitwise_and_equal_to_zero # by problem name
```
## Problem
Given an integer array `nums`, return *the number of **AND triples***.
An **AND triple** is a triple of indices `(i, j, k)` such that:
* `0 <= i < nums.length`
* `0 <= j < nums.length`
* `0 <= k < nums.length`
* `nums[i] & nums[j] & nums[k] == 0`, where `&` represents the bitwise-AND operator.
### Examples
```
Input: nums = [2,1,3]
Output: 12
Explanation: We could choose the following i, j, k triples:
(i=0, j=0, k=1) : 2 & 2 & 1
(i=0, j=1, k=0) : 2 & 1 & 2
(i=0, j=1, k=1) : 2 & 1 & 1
(i=0, j=1, k=2) : 2 & 1 & 3
(i=0, j=2, k=1) : 2 & 3 & 1
(i=1, j=0, k=0) : 1 & 2 & 2
(i=1, j=0, k=1) : 1 & 2 & 1
(i=1, j=0, k=2) : 1 & 2 & 3
(i=1, j=1, k=0) : 1 & 1 & 2
(i=1, j=2, k=0) : 1 & 3 & 2
(i=2, j=0, k=1) : 3 & 2 & 1
(i=2, j=1, k=0) : 3 & 1 & 2
```
```
Input: nums = [0,0,0]
Output: 27
```
### Constraints
* `1 <= nums.length <= 1000`
* `0 <= nums[i] < 2^16`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/triples_with_bitwise_and_equal_to_zero/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/triples_with_bitwise_and_equal_to_zero/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n^2 + n * d) where d is the number of distinct pair AND values
# Space: O(d)
def count_triplets(self, nums: list[int]) -> int:
pair_counts: Counter[int] = Counter()
for a in nums:
for b in nums:
pair_counts[a & b] += 1
total = 0
for x in nums:
for pair_and, count in pair_counts.items():
if pair_and & x == 0:
total += count
return total
```
## Complexity
| Time | Space |
| ----------------------------------------------------------------- | ----- |
| O(n^2 + n \* d) where d is the number of distinct pair AND values | O(d) |
## Tags
# Tuple with Same Product Python Solution
Source: https://leetcode-py.wisl.dev/problems/tuple-with-same-product
Tested Python solution for LeetCode 1726 with 36 pytest cases. Generate a practice environment with lcpy.
LeetCode 1726, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Counting](/catalog/topics/counting). [View on LeetCode](https://leetcode.com/problems/tuple-with-same-product/description/).
Generate this problem as a practice environment: tested reference solution, 36 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1726 # by problem number
lcpy gen -s tuple_with_same_product # by problem name
```
## Problem
Given an array `nums` of **distinct** positive integers, return *the number of tuples* `(a, b, c, d)` *such that* `a * b = c * d` *where* `a`, `b`, `c`, and `d` *are elements of* `nums`*, and* `a != b != c != d`.
### Examples
```
Input: nums = [2,3,4,6]
Output: 8
Explanation: There are 8 valid tuples:
(2,6,3,4) , (2,6,4,3) , (6,2,3,4) , (6,2,4,3)
(3,4,2,6) , (4,3,2,6) , (3,4,6,2) , (4,3,6,2)
```
```
Input: nums = [1,2,4,5,10]
Output: 16
Explanation: There are 16 valid tuples:
(1,10,2,5) , (1,10,5,2) , (10,1,2,5) , (10,1,5,2)
(2,5,1,10) , (2,5,10,1) , (5,2,1,10) , (5,2,10,1)
(2,10,4,5) , (2,10,5,4) , (10,2,4,5) , (10,2,5,4)
(4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
```
### Constraints
* 1 \<= nums.length \<= 1000
* 1 \<= nums\[i] \<= 10^4
* All elements in nums are distinct.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/tuple_with_same_product/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/tuple_with_same_product/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import defaultdict
class Solution:
# Time: O(n^2)
# Space: O(n^2)
def tuple_same_product(self, nums: list[int]) -> int:
product_counts: dict[int, int] = defaultdict(int)
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
product_counts[nums[i] * nums[j]] += 1
return sum(8 * c * (c - 1) // 2 for c in product_counts.values())
```
## Complexity
| Time | Space |
| ------ | ------ |
| O(n^2) | O(n^2) |
## Tags
[NeetCode All](/catalog/neetcode).
# Two City Scheduling Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/two-city-scheduling
Tested Python solution for LeetCode 1029 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1029, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/two-city-scheduling/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1029 # by problem number
lcpy gen -s two_city_scheduling # by problem name
```
## Problem
A company is planning to interview `2n` people. Given the array `costs` where `costs[i] = [aCosti, bCosti]`, the cost of flying the `ith` person to city `a` is `aCosti`, and the cost of flying the `ith` person to city `b` is `bCosti`.
Return *the minimum cost to fly every person to a city* such that exactly `n` people arrive in each city.
### Examples
```
Input: costs = [[10,20],[30,200],[400,50],[30,20]]
Output: 110
Explanation:
The first person goes to city A for a cost of 10.
The second person goes to city A for a cost of 30.
The third person goes to city B for a cost of 50.
The fourth person goes to city B for a cost of 20.
The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.
```
```
Input: costs = [[259,770],[448,54],[926,667],[184,139],[840,118],[577,469]]
Output: 1859
Explanation: For example, the way to achieve the minimum of 1859 is:
- Fly the 1st person (259, 770) to city A for 259.
- Fly the 2nd person (448, 54) to city B for 54.
- Fly the 3rd person (926, 667) to city B for 667.
- Fly the 4th person (184, 139) to city B for 139.
- Fly the 5th person (840, 118) to city B for 118.
- Fly the 6th person (577, 469) to city A for 577.
The total minimum cost is 1859.
```
```
Input: costs = [[515,563],[451,713],[537,709],[343,819],[855,779],[457,60],[650,359],[631,42]]
Output: 3086
Explanation: The total minimum cost is 3086.
```
### Constraints
* `2 * n == costs.length`
* `2 <= costs.length <= 100`
* `costs.length` is even.
* `1 <= aCosti, bCosti <= 1000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/two_city_scheduling/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/two_city_scheduling/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n log n)
# Space: O(n) for the sorted copy
def two_city_sched_cost(self, costs: list[list[int]]) -> int:
ordered = sorted(costs, key=lambda cost: cost[0] - cost[1])
n = len(ordered) // 2
return sum(cost[0] for cost in ordered[:n]) + sum(cost[1] for cost in ordered[n:])
```
## Complexity
| Time | Space |
| ---------- | ------------------------ |
| O(n log n) | O(n) for the sorted copy |
## Tags
[NeetCode All](/catalog/neetcode).
# 2 Keys Keyboard Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/two-keys-keyboard
Tested Python solution for LeetCode 650 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 650, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/two-keys-keyboard/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 650 # by problem number
lcpy gen -s two_keys_keyboard # by problem name
```
## Problem
There is only one character `'A'` on the screen of a notepad. You can perform one of two operations on this notepad for each step:
* **Copy All:** You can copy all the characters present on the screen (a partial copy is not allowed).
* **Paste:** You can paste the characters which are copied last time.
Given an integer `n`, return *the minimum number of operations to get the character* `'A'` *exactly* `n` *times on the screen*.
### Examples
```
Input: n = 3
Output: 3
Explanation: Initially, we have one character 'A'.
In step 1, we use Copy All operation.
In step 2, we use Paste operation to get 'AA'.
In step 3, we use Paste operation to get 'AAA'.
```
```
Input: n = 1
Output: 0
```
### Constraints
* 1 \<= n \<= 1000
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/two_keys_keyboard/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/two_keys_keyboard/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(sqrt(n))
# Space: O(1)
def min_steps(self, n: int) -> int:
# Each run of pastes multiplies the screen by a factor; copying a
# block of size d costs d operations total, so the answer is the sum
# of the prime factors of n.
operations = 0
factor = 2
while factor * factor <= n:
while n % factor == 0:
operations += factor
n //= factor
factor += 1
if n > 1:
operations += n
return operations
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(sqrt(n)) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Two Sum Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/two-sum
Tested Python solution for LeetCode 1 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 1, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table). [View on LeetCode](https://leetcode.com/problems/two-sum/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1 # by problem number
lcpy gen -s two_sum # by problem name
```
## Problem
Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
### Examples
```
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
```
**Explanation:** Because nums\[0] + nums\[1] == 9, we return \[0, 1].
```
Input: nums = [3,2,4], target = 6
Output: [1,2]
```
```
Input: nums = [3,3], target = 6
Output: [0,1]
```
### Constraints
* 2 \<= nums.length \<= 10^4
* -10^9 \<= nums\[i] \<= 10^9
* -10^9 \<= target \<= 10^9
* Only one valid answer exists.
**Follow-up:** Can you come up with an algorithm that is less than O(n^2) time complexity?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/two_sum/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/two_sum/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def two_sum(self, nums: list[int], target: int) -> list[int]:
seen: dict[int, int] = {}
answers: list[list[int]] = []
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
answer = [seen[complement], i]
answers.append(answer)
seen[num] = i
if len(answers) > 1:
raise ValueError(f"Found {len(answers)} answers in the solution: {answers}")
return answers[0] if answers else []
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Two Sum BSTs Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/two-sum-bsts
Tested Python solution for LeetCode 1214 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 1214, [Medium](/catalog/medium). Topics: [Stack](/catalog/topics/stack), [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/two-sum-bsts/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1214 # by problem number
lcpy gen -s two_sum_bsts # by problem name
```
## Problem
\Given the roots of two binary search trees, \root1\ and \root2\, return \true\ if and only if there is a node in the first tree and a node in the second tree whose values sum up to a given integer \target\.\
Given the \root\ of a binary search tree and an integer \k\, return \true\ \if there exist two elements in the BST such that their sum is equal to\ \k\, \or\ \false\ \otherwise\.\
\[1, 10^4]\.\-10^4 \<= Node.val \<= 10^4\\root\ is guaranteed to be a \valid\ binary search tree.\-10^5 \<= k \<= 10^5\\A word is \uncommon\ if it appears exactly once in one of the sentences, and \does not appear\ in the other sentence.\
\Given two sentences \s1\ and \s2\, return \a list of all the \uncommon words\\. You may return the answer in any order.
### Examples
```
Input: s1 = "this apple is sweet", s2 = "this apple is sour"
Output: ["sweet","sour"]
```
```
Input: s1 = "apple apple", s2 = "banana"
Output: ["banana"]
```
### Constraints
* 1 \<= s1.length, s2.length \<= 200
* s1 and s2 consist of lowercase English letters and spaces.
* s1 and s2 do not have leading or trailing spaces.
* All the words in s1 and s2 are separated by a single space.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/uncommon_words_from_two_sentences/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/uncommon_words_from_two_sentences/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(m + n)
# Space: O(m + n)
def uncommon_from_sentences(self, s1: str, s2: str) -> list[str]:
counts = Counter((s1 + " " + s2).split())
return [word for word, count in counts.items() if count == 1]
```
## Complexity
| Time | Space |
| -------- | -------- |
| O(m + n) | O(m + n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Uncrossed Lines Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/uncrossed-lines
Tested Python solution for LeetCode 1035 with 12 pytest cases. Generate a practice environment with lcpy.
LeetCode 1035, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/uncrossed-lines/description/).
Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1035 # by problem number
lcpy gen -s uncrossed_lines # by problem name
```
## Problem
You are given two integer arrays `nums1` and `nums2`. We write the integers of `nums1` and `nums2` (in the order they are given) on two separate horizontal lines.
We may draw connecting lines: a straight line connecting two numbers `nums1[i]` and `nums2[j]` such that:
* `nums1[i] == nums2[j]`, and
* the line we draw does not intersect any other connecting (non-horizontal) line.
Note that a connecting line cannot intersect even at the endpoints (i.e., each number can only belong to one connecting line).
Return *the maximum number of connecting lines we can draw in this way*.
### Examples

```
Input: nums1 = [1,4,2], nums2 = [1,2,4]
Output: 2
Explanation: We can draw 2 uncrossed lines as in the diagram.
We cannot draw 3 uncrossed lines, because the line from nums1[1] = 4 to nums2[2] = 4 will intersect the line from nums1[2]=2 to nums2[1]=2.
```
```
Input: nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
Output: 3
```
```
Input: nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
Output: 2
```
### Constraints
* `1 <= nums1.length, nums2.length <= 500`
* `1 <= nums1[i], nums2[j] <= 2000`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/uncrossed_lines/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/uncrossed_lines/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(m * n)
# Space: O(min(m, n))
def max_uncrossed_lines(self, nums1: list[int], nums2: list[int]) -> int:
if len(nums2) < len(nums1):
nums1, nums2 = nums2, nums1
prev = [0] * (len(nums2) + 1)
for a in nums1:
curr = [0] * (len(nums2) + 1)
for j, b in enumerate(nums2):
if a == b:
curr[j + 1] = prev[j] + 1
else:
curr[j + 1] = max(prev[j + 1], curr[j])
prev = curr
return prev[-1]
```
## Complexity
| Time | Space |
| --------- | ------------ |
| O(m \* n) | O(min(m, n)) |
## Tags
[NeetCode All](/catalog/neetcode).
# Unique Binary Search Trees Python Solution
Source: https://leetcode-py.wisl.dev/problems/unique-binary-search-trees
Tested Python solution for LeetCode 96 with 19 pytest cases. Generate a practice environment with lcpy.
LeetCode 96, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Dynamic Programming](/catalog/topics/dynamic-programming), [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/unique-binary-search-trees/description/).
Generate this problem as a practice environment: tested reference solution, 19 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 96 # by problem number
lcpy gen -s unique_binary_search_trees # by problem name
```
## Problem
Given an integer `n`, return *the number of structurally unique **BST's** (binary search trees) which has exactly `n` nodes of unique values from `1` to `n`*.
### Examples

```
Input: n = 3
Output: 5
```
```
Input: n = 1
Output: 1
```
### Constraints
* `1 <= n <= 19`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/unique_binary_search_trees/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/unique_binary_search_trees/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def num_trees(self, n: int) -> int:
dp = [0] * (n + 1)
dp[0] = 1
for nodes in range(1, n + 1):
for left in range(nodes):
dp[nodes] += dp[left] * dp[nodes - 1 - left]
return dp[n]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Unique Binary Search Trees II Python Solution
Source: https://leetcode-py.wisl.dev/problems/unique-binary-search-trees-ii
Tested Python solution for LeetCode 95 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 95, [Medium](/catalog/medium). Topics: [Dynamic Programming](/catalog/topics/dynamic-programming), [Backtracking](/catalog/topics/backtracking), [Tree](/catalog/topics/tree), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/unique-binary-search-trees-ii/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 95 # by problem number
lcpy gen -s unique_binary_search_trees_ii # by problem name
```
## Problem
Given an integer `n`, return *all the structurally unique **BST's** (binary search trees), which has exactly `n` nodes of unique values from `1` to `n`*. Return the answer in **any order**.
### Examples

```
Input: n = 3
Output: [[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]
```
```
Input: n = 1
Output: [[1]]
```
### Constraints
* `1 <= n <= 8`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/unique_binary_search_trees_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/unique_binary_search_trees_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(4^n / sqrt(n) * n)
# Space: O(4^n / sqrt(n) * n)
def generate_trees(self, n: int) -> list[TreeNode[int] | None]:
def build(start: int, end: int) -> list[TreeNode[int] | None]:
if start > end:
return [None]
trees: list[TreeNode[int] | None] = []
for root_val in range(start, end + 1):
for left in build(start, root_val - 1):
for right in build(root_val + 1, end):
root = TreeNode[int](root_val)
root.left = left
root.right = right
trees.append(root)
return trees
return build(1, n)
```
## Complexity
| Time | Space |
| --------------------- | --------------------- |
| O(4^n / sqrt(n) \* n) | O(4^n / sqrt(n) \* n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Unique Email Addresses Python Solution
Source: https://leetcode-py.wisl.dev/problems/unique-email-addresses
Tested Python solution for LeetCode 929 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 929, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/unique-email-addresses/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 929 # by problem number
lcpy gen -s unique_email_addresses # by problem name
```
## Problem
\
Every valid email consists of a local name and a domain name, separated by the \'@'\ sign. Besides lowercase letters, the email may contain one or more \'.'\ or \'+'\.\
"[alice@leetcode.com](mailto:alice@leetcode.com)"\, \"alice"\ is the \local name\, and \"leetcode.com"\ is the \domain name\.\If you add periods \'.'\ between some characters in the \local name\ part of an email address, mail sent there will be forwarded to the same address without dots in the local name. Note that this rule \does not apply\ to domain names.\
"[alice.z@leetcode.com](mailto:alice.z@leetcode.com)"\ and \"[alicez@leetcode.com](mailto:alicez@leetcode.com)"\ forward to the same email address.\If you add a plus \'+'\ in the \local name\, everything after the first plus sign will be \ignored\. This allows certain emails to be filtered. Note that this rule \does not apply\ to domain names.\
"[m.y+name@email.com](mailto:m.y+name@email.com)"\ will be forwarded to \"[my@email.com](mailto:my@email.com)"\.\It is possible to use both of these rules at the same time.\
\Given an array of strings \emails\ where we send one email to each \emails\[i]\, return \the number of different addresses that actually receive mails\.\
root\ of a binary tree, return \true\ if the given tree is \uni-valued\, or \false\ otherwise.
### Examples

```
Input: root = [1,1,1,1,1,null,1]
Output: true
```

```
Input: root = [2,2,2,5,2]
Output: false
```
### Constraints
* The number of nodes in the tree is in the range \[1, 100]
* 0 \<= Node.val \< 100
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/univalued_binary_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/univalued_binary_tree/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from leetcode_py import TreeNode
class Solution:
# Time: O(n)
# Space: O(h)
def is_unival_tree(self, root: TreeNode[int] | None) -> bool:
if root is None:
return True
stack = [root]
target = root.val
while stack:
node = stack.pop()
if node.val != target:
return False
if node.left is not None:
stack.append(node.left)
if node.right is not None:
stack.append(node.right)
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(h) |
## Tags
# UTF-8 Validation Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/utf-8-validation
Tested Python solution for LeetCode 393 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 393, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Bit Manipulation](/catalog/topics/bit-manipulation). [View on LeetCode](https://leetcode.com/problems/utf-8-validation/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 393 # by problem number
lcpy gen -s utf_8_validation # by problem name
```
## Problem
Given an integer array `data` representing the data, return whether it is a valid UTF-8 encoding (i.e. it translates to a sequence of valid UTF-8 encoded characters).
A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules:
1. For a 1-byte character, the first bit is a `0`, followed by its Unicode code.
2. For an n-bytes character, the first `n` bits are all one's, the `n + 1` bit is `0`, followed by `n - 1` bytes with the most significant 2 bits being `10`.
This is how the UTF-8 encoding would work:
```
Number of Bytes | UTF-8 Octet Sequence
| (binary)
--------------------+-----------------------------------------
1 | 0xxxxxxx
2 | 110xxxxx 10xxxxxx
3 | 1110xxxx 10xxxxxx 10xxxxxx
4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
```
`x` denotes a bit in the binary form of a byte that may be either `0` or `1`.
**Note:** The input is an array of integers. Only the **least significant 8 bits** of each integer is used to store the data. This means each integer represents only 1 byte of data.
### Examples
```
Input: data = [197,130,1]
Output: true
Explanation: data represents the octet sequence: 11000101 10000010 00000001.
It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character.
```
```
Input: data = [235,140,4]
Output: false
Explanation: data represented the octet sequence: 11101011 10001100 00000100.
The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character.
The next byte is a continuation byte which starts with 10 and that's correct.
But the second continuation byte does not start with 10, so it is invalid.
```
### Constraints
* 1 \<= data.length \<= 2 \* 10^4
* 0 \<= data\[i] \<= 255
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/utf_8_validation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/utf_8_validation/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def valid_utf8(self, data: list[int]) -> bool:
remaining = 0
for byte in data:
if remaining == 0:
if byte >> 7 == 0b0:
remaining = 0
elif byte >> 5 == 0b110:
remaining = 1
elif byte >> 4 == 0b1110:
remaining = 2
elif byte >> 3 == 0b11110:
remaining = 3
else:
return False
else:
if byte >> 6 != 0b10:
return False
remaining -= 1
return remaining == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Valid Anagram Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/valid-anagram
Tested Python solution for LeetCode 242 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 242, [Easy](/catalog/easy). Topics: [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/valid-anagram/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 242 # by problem number
lcpy gen -s valid_anagram # by problem name
```
## Problem
Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.
### Examples
```
Input: s = "anagram", t = "nagaram"
Output: true
```
```
Input: s = "rat", t = "car"
Output: false
```
### Constraints
* 1 \<= s.length, t.length \<= 5 \* 10^4
* s and t consist of lowercase English letters.
**Follow up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_anagram/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_anagram/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from collections import Counter
class Solution:
# Time: O(n)
# Space: O(1) - at most 26 unique characters
def is_anagram(self, s: str, t: str) -> bool:
return Counter(s) == Counter(t)
```
## Complexity
| Time | Space |
| ---- | ----------------------------------- |
| O(n) | O(1) - at most 26 unique characters |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Valid Mountain Array Python Solution
Source: https://leetcode-py.wisl.dev/problems/valid-mountain-array
Tested Python solution for LeetCode 941 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 941, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array). [View on LeetCode](https://leetcode.com/problems/valid-mountain-array/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 941 # by problem number
lcpy gen -s valid_mountain_array # by problem name
```
## Problem
Given an array of integers `arr`, return `true` if and only if it is a valid mountain array.
Recall that arr is a mountain array if and only if:
* `arr.length >= 3`
* There exists some `i` with `0 < i < arr.length - 1` such that:
* `arr[0] < arr[1] < ... < arr[i - 1] < arr[i]`
* `arr[i] > arr[i + 1] > ... > arr[arr.length - 1]`

### Examples
```
Input: arr = [2,1]
Output: false
```
```
Input: arr = [3,5,5]
Output: false
```
```
Input: arr = [0,3,2,1]
Output: true
```
### Constraints
* 1 \<= arr.length \<= 10^4
* 0 \<= arr\[i] \<= 10^4
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_mountain_array/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_mountain_array/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def valid_mountain_array(self, arr: list[int]) -> bool:
i = 0
n = len(arr)
while i + 1 < n and arr[i] < arr[i + 1]:
i += 1
if i == 0 or i == n - 1:
return False
while i + 1 < n and arr[i] > arr[i + 1]:
i += 1
return i == n - 1
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Valid Number Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/valid-number
Tested Python solution for LeetCode 65 with 45 pytest cases. Generate a practice environment with lcpy.
LeetCode 65, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/valid-number/description/).
Generate this problem as a practice environment: tested reference solution, 45 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 65 # by problem number
lcpy gen -s valid_number # by problem name
```
## Problem
Given a string `s`, return whether `s` is a valid number.
For example, all the following are valid numbers: `"2"`, `"0089"`, `"-0.1"`, `"+3.14"`, `"4."`, `"-.9"`, `"2e10"`, `"-90E3"`, `"3e+7"`, `"+6e-1"`, `"53.5e93"`, `"-123.456e789"`, while the following are not valid numbers: `"abc"`, `"1a"`, `"1e"`, `"e3"`, `"99e2.5"`, `"--6"`, `"-+3"`, `"95a54e53"`.
Formally, a valid number is defined using one of the following definitions:
* An integer number followed by an optional exponent.
* A decimal number followed by an optional exponent.
An integer number is defined with an optional sign `'-'` or `'+'` followed by digits.
A decimal number is defined with an optional sign `'-'` or `'+'` followed by one of the following definitions:
* Digits followed by a dot `'.'`.
* Digits followed by a dot `'.'` followed by digits.
* A dot `'.'` followed by digits.
An exponent is defined with an exponent notation `'e'` or `'E'` followed by an integer number.
The digits are defined as one or more digits.
### Examples
```
Input: s = "0"
Output: true
```
```
Input: s = "e"
Output: false
```
```
Input: s = "."
Output: false
```
### Constraints
* 1 \<= s.length \<= 20
* s consists of only English letters (both uppercase and lowercase), digits (0-9), plus '+', minus '-', or dot '.'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_number/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def is_number(self, s: str) -> bool:
i, n = 0, len(s)
def skip_digits() -> bool:
nonlocal i
start = i
while i < n and s[i].isdigit():
i += 1
return i > start
if s[i] in "+-":
i += 1
if skip_digits():
if i < n and s[i] == ".":
i += 1
skip_digits()
else:
if i >= n or s[i] != ".":
return False
i += 1
if not skip_digits():
return False
if i < n and s[i] in "eE":
i += 1
if i < n and s[i] in "+-":
i += 1
if not skip_digits():
return False
return i == n
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
# Valid Palindrome Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/valid-palindrome
Tested Python solution for LeetCode 125 with 16 pytest cases. Generate a practice environment with lcpy.
LeetCode 125, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/valid-palindrome/description/).
Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 125 # by problem number
lcpy gen -s valid_palindrome # by problem name
```
## Problem
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.
Given a string `s`, return `true` if it is a **palindrome**, or `false` otherwise.
### Examples
```
Input: s = "A man, a plan, a canal: Panama"
Output: true
```
**Explanation:** "amanaplanacanalpanama" is a palindrome.
```
Input: s = "race a car"
Output: false
```
**Explanation:** "raceacar" is not a palindrome.
```
Input: s = " "
Output: true
```
**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.
### Constraints
* `1 <= s.length <= 2 * 10^5`
* `s` consists only of printable ASCII characters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_palindrome/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_palindrome/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def is_palindrome(self, s: str) -> bool:
left, right = 0, len(s) - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if s[left].lower() != s[right].lower():
return False
left += 1
right -= 1
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Valid Palindrome II Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/valid-palindrome-ii
Tested Python solution for LeetCode 680 with 18 pytest cases. Generate a practice environment with lcpy.
LeetCode 680, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/valid-palindrome-ii/description/).
Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 680 # by problem number
lcpy gen -s valid_palindrome_ii # by problem name
```
## Problem
Given a string `s`, return `true` if the `s` can be palindrome after deleting **at most one** character from it.
### Examples
```
Input: s = "aba"
Output: true
```
```
Input: s = "abca"
Output: true
Explanation: You could delete the character 'c'.
```
```
Input: s = "abc"
Output: false
```
### Constraints
* 1 \<= s.length \<= 10^5
* `s` consists of lowercase English letters.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_palindrome_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_palindrome_ii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def valid_palindrome(self, s: str) -> bool:
def is_palindrome(left: int, right: int) -> bool:
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
# Mismatch: try skipping either the left or the right character.
return is_palindrome(left + 1, right) or is_palindrome(left, right - 1)
left += 1
right -= 1
return True
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Valid Palindrome III Python Solution
Source: https://leetcode-py.wisl.dev/problems/valid-palindrome-iii
Tested Python solution for LeetCode 1216 with 24 pytest cases. Generate a practice environment with lcpy.
LeetCode 1216, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming). [View on LeetCode](https://leetcode.com/problems/valid-palindrome-iii/description/).
Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 1216 # by problem number
lcpy gen -s valid_palindrome_iii # by problem name
```
## Problem
Given a string `s` and an integer `k`, return `true` if `s` is a `k`**-palindrome**.
A string is `k`**-palindrome** if it can be transformed into a palindrome by removing at most `k` characters from it.
### Examples
```
Input: s = "abcdeca", k = 2
Output: true
```
**Explanation:** Remove 'b' and 'e' characters.
```
Input: s = "abbababa", k = 1
Output: true
```
### Constraints
* `1 <= s.length <= 1000`
* `s` consists of only lowercase English letters.
* `1 <= k <= s.length`
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_palindrome_iii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_palindrome_iii/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def is_valid_palindrome(self, s: str, k: int) -> bool:
n = len(s)
dp = [0] * n
for i in range(n - 1, -1, -1):
prev = 0
dp[i] = 1
for j in range(i + 1, n):
temp = dp[j]
if s[i] == s[j]:
dp[j] = prev + 2
else:
dp[j] = max(dp[j], dp[j - 1])
prev = temp
return n - dp[n - 1] <= k
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Valid Parentheses Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/valid-parentheses
Tested Python solution for LeetCode 20 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 20, [Easy](/catalog/easy). Topics: [String](/catalog/topics/string), [Stack](/catalog/topics/stack). [View on LeetCode](https://leetcode.com/problems/valid-parentheses/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 20 # by problem number
lcpy gen -s valid_parentheses # by problem name
```
## Problem
Given a string `s` containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.
An input string is valid if:
1. Open brackets must be closed by the same type of brackets.
2. Open brackets must be closed in the correct order.
3. Every close bracket has a corresponding open bracket of the same type.
### Examples
```
Input: s = "()"
Output: true
```
```
Input: s = "()[]{}"
Output: true
```
```
Input: s = "(]"
Output: false
```
```
Input: s = "([])"
Output: true
```
```
Input: s = "([)]"
Output: false
```
### Constraints
* `1 <= s.length <= 10^4`
* `s` consists of parentheses only `'()[]{}'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_parentheses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_parentheses/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def is_valid(self, s: str) -> bool:
stack = []
pairs = {"(": ")", "[": "]", "{": "}"}
for char in s:
if char in pairs:
stack.append(char)
elif not stack or pairs[stack.pop()] != char:
return False
return not stack
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
# Valid Parenthesis String Python Solution
Source: https://leetcode-py.wisl.dev/problems/valid-parenthesis-string
Tested Python solution for LeetCode 678 with 14 pytest cases. Generate a practice environment with lcpy.
LeetCode 678, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Stack](/catalog/topics/stack), [Greedy](/catalog/topics/greedy). [View on LeetCode](https://leetcode.com/problems/valid-parenthesis-string/description/).
Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 678 # by problem number
lcpy gen -s valid_parenthesis_string # by problem name
```
## Problem
Given a string `s` containing only three types of characters: `'('`, `')'` and `'*'`, return `true` *if* `s` *is **valid***.
The following rules define a **valid** string:
* Any left parenthesis `'('` must have a corresponding right parenthesis `')'`.
* Any right parenthesis `')'` must have a corresponding left parenthesis `'('`.
* Left parenthesis `'('` must go before the corresponding right parenthesis `')'`.
* `'*'` could be treated as a single right parenthesis `')'` or a single left parenthesis `'('` or an empty string `""`.
### Examples
```
Input: s = "()"
Output: true
```
```
Input: s = "(*)"
Output: true
```
```
Input: s = "(*))"
Output: true
```
### Constraints
* 1 \<= s.length \<= 100
* `s[i]` is `'('`, `')'` or `'*'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_parenthesis_string/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_parenthesis_string/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(1)
def check_valid_string(self, s: str) -> bool:
# Range of possible open-parenthesis counts after processing each char.
low = 0
high = 0
for char in s:
if char == "(":
low += 1
high += 1
elif char == ")":
low = max(low - 1, 0)
high -= 1
else: # '*' can act as '(', ')' or empty
low = max(low - 1, 0)
high += 1
if high < 0:
return False
return low == 0
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(1) |
## Tags
[NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode).
# Valid Perfect Square Python Solution
Source: https://leetcode-py.wisl.dev/problems/valid-perfect-square
Tested Python solution for LeetCode 367 with 21 pytest cases. Generate a practice environment with lcpy.
LeetCode 367, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Binary Search](/catalog/topics/binary-search). [View on LeetCode](https://leetcode.com/problems/valid-perfect-square/description/).
Generate this problem as a practice environment: tested reference solution, 21 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 367 # by problem number
lcpy gen -s valid_perfect_square # by problem name
```
## Problem
Given a positive integer `num`, return `true` if `num` is a perfect square or `false` otherwise.
A **perfect square** is an integer that is the square of an integer. In other words, it is the product of some integer with itself.
You must not use any built-in library function, such as `sqrt`.
### Examples
```
Input: num = 16
Output: true
Explanation: We return true because 4 * 4 = 16 and 4 is an integer.
```
```
Input: num = 14
Output: false
Explanation: We return false because 3.742 * 3.742 = 14 and 3.742 is not an integer.
```
### Constraints
* 1 \<= num \<= 2^31 - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_perfect_square/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_perfect_square/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(log num)
# Space: O(1)
def is_perfect_square(self, num: int) -> bool:
low, high = 1, num
while low <= high:
mid = (low + high) // 2
squared = mid * mid
if squared == num:
return True
if squared < num:
low = mid + 1
else:
high = mid - 1
return False
```
## Complexity
| Time | Space |
| ---------- | ----- |
| O(log num) | O(1) |
## Tags
[NeetCode All](/catalog/neetcode).
# Valid Permutations for DI Sequence
Source: https://leetcode-py.wisl.dev/problems/valid-permutations-for-di-sequence
Tested Python solution for LeetCode 903 with 20 pytest cases. Generate a practice environment with lcpy.
LeetCode 903, [Hard](/catalog/hard). Topics: [String](/catalog/topics/string), [Dynamic Programming](/catalog/topics/dynamic-programming), [Prefix Sum](/catalog/topics/prefix-sum). [View on LeetCode](https://leetcode.com/problems/valid-permutations-for-di-sequence/description/).
Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 903 # by problem number
lcpy gen -s valid_permutations_for_di_sequence # by problem name
```
## Problem
You are given a string `s` of length `n` where `s[i]` is either:
* `'D'` means decreasing, or
* `'I'` means increasing.
A permutation `perm` of `n + 1` integers of all the integers in the range `[0, n]` is called a **valid permutation** if for all valid `i`:
* If `s[i] == 'D'`, then `perm[i] > perm[i + 1]`, and
* If `s[i] == 'I'`, then `perm[i] < perm[i + 1]`.
Return *the number of **valid permutations*** `perm`. Since the answer may be large, return it **modulo** `10^9 + 7`.
### Examples
```
Input: s = "DID"
Output: 5
```
**Explanation:** The 5 valid permutations of (0, 1, 2, 3) are:
(1, 0, 3, 2)
(2, 0, 3, 1)
(2, 1, 3, 0)
(3, 0, 2, 1)
(3, 1, 2, 0)
```
Input: s = "D"
Output: 1
```
### Constraints
* `n == s.length`
* `1 <= n <= 200`
* `s[i]` is either `'I'` or `'D'`.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_permutations_for_di_sequence/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_permutations_for_di_sequence/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n^2)
# Space: O(n)
def num_perms_di_sequence(self, s: str) -> int:
mod = 1_000_000_007
n = len(s)
# dp[j] = ways to place values so far where the last value is the
# j-th smallest of the values still unused.
dp = [1] * (n + 1)
for i, ch in enumerate(s):
m = n + 1 - i
ndp = [0] * (m - 1)
if ch == "I":
# next value is larger: its rank is at least the last rank
run = 0
for j in range(m - 1):
run = (run + dp[j]) % mod
ndp[j] = run
else:
# next value is smaller: its rank is strictly below the last rank
suf = 0
for j in range(m - 2, -1, -1):
suf = (suf + dp[j + 1]) % mod
ndp[j] = suf
dp = ndp
return dp[0]
```
## Complexity
| Time | Space |
| ------ | ----- |
| O(n^2) | O(n) |
## Tags
# Valid Square Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/valid-square
Tested Python solution for LeetCode 593 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 593, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Geometry](/catalog/topics/geometry). [View on LeetCode](https://leetcode.com/problems/valid-square/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 593 # by problem number
lcpy gen -s valid_square # by problem name
```
## Problem
Given the coordinates of four points in 2D space \p1\, \p2\, \p3\ and \p4\, return \true\ \if the four points construct a square\.
\The coordinate of a point \p\i\\ is represented as \\[x\i\, y\i\]\. The input is \not\ given in any order.\
A \valid square\ has four equal sides with positive length and four equal angles (90-degree angles).\
### Examples ``` Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1] Output: true ``` ``` Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,12] Output: false ``` ``` Input: p1 = [1,0], p2 = [-1,0], p3 = [0,1], p4 = [0,-1] Output: true ``` ### Constraints * p1.length == p2.length == p3.length == p4.length == 2 * -10^4 \<= xi, yi \<= 10^4 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_square/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_square/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(1) - always 6 pairwise distances over 4 fixed points # Space: O(1) def valid_square(self, p1: list[int], p2: list[int], p3: list[int], p4: list[int]) -> bool: pts = (p1, p2, p3, p4) dists = sorted( (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 for i, a in enumerate(pts) for b in pts[i + 1 :] ) return 0 < dists[0] == dists[3] and dists[4] == dists[5] == 2 * dists[0] ``` ## Complexity | Time | Space | | ------------------------------------------------------ | ----- | | O(1) - always 6 pairwise distances over 4 fixed points | O(1) | ## Tags # Valid Sudoku Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/valid-sudoku Tested Python solution for LeetCode 36 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 36, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/valid-sudoku/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 36 # by problem number lcpy gen -s valid_sudoku # by problem name ``` ## Problem Determine if a `9 x 9` Sudoku board is valid. Only the filled cells need to be validated **according to the following rules**: 1. Each row must contain the digits `1-9` without repetition. 2. Each column must contain the digits `1-9` without repetition. 3. Each of the nine `3 x 3` sub-boxes of the grid must contain the digits `1-9` without repetition. **Note:** * A Sudoku board (partially filled) could be valid but is not necessarily solvable. * Only the filled cells need to be validated according to the mentioned rules. ### Examples  ``` 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"]] Output: true ``` ``` 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"]] Output: false 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. ``` ### Constraints * `board.length == 9` * `board[i].length == 9` * `board[i][j]` is a digit `1-9` or `'.'`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_sudoku/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_sudoku/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(1) - fixed 9x9 board # Space: O(1) - fixed size sets def is_valid_sudoku(self, board: list[list[str]]) -> bool: rows: list[set[str]] = [set() for _ in range(9)] cols: list[set[str]] = [set() for _ in range(9)] boxes: list[list[set[str]]] = [[set() for _ in range(3)] for _ in range(3)] for i in range(9): for j in range(9): if board[i][j] != ".": num = board[i][j] if num in rows[i] or num in cols[j] or num in boxes[i // 3][j // 3]: return False rows[i].add(num) cols[j].add(num) boxes[i // 3][j // 3].add(num) return True ``` ## Complexity | Time | Space | | ---------------------- | ---------------------- | | O(1) - fixed 9x9 board | O(1) - fixed size sets | ## Tags [Grind](/catalog/grind), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Valid Tic-Tac-Toe State Python Solution Source: https://leetcode-py.wisl.dev/problems/valid-tic-tac-toe-state Tested Python solution for LeetCode 794 with 24 pytest cases. Generate a practice environment with lcpy. LeetCode 794, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/valid-tic-tac-toe-state/description/). Generate this problem as a practice environment: tested reference solution, 24 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 794 # by problem number lcpy gen -s valid_tic_tac_toe_state # by problem name ``` ## Problem Given a Tic-Tac-Toe board as a string array `board`, return `true` if and only if it is possible to reach this board position during the course of a valid tic-tac-toe game. The board is a `3 x 3` array that consists of characters `' '`, `'X'`, and `'O'`. The `' '` character represents an empty square. Here are the rules of Tic-Tac-Toe: * Players take turns placing characters into empty squares `' '`. * The first player always places `'X'` characters, while the second player always places `'O'` characters. * `'X'` and `'O'` characters are always placed into empty squares, never filled ones. * The game ends when there are three of the same (non-empty) character filling any row, column, or diagonal. * The game also ends if all squares are non-empty. * No more moves can be played if the game is over. ### Examples  ``` Input: board = ["O "," "," "] Output: false Explanation: The first player always plays "X". ```  ``` Input: board = ["XOX"," X "," "] Output: false Explanation: Players take turns making moves. ```  ``` Input: board = ["XOX","O O","XOX"] Output: true ``` ### Constraints * board.length == 3 * board\[i].length == 3 * `board[i][j]` is either `'X'`, `'O'`, or `' '`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_tic_tac_toe_state/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_tic_tac_toe_state/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(1) - the board is always 3 x 3 # Space: O(1) def valid_tic_tac_toe(self, board: list[str]) -> bool: x_count = sum(row.count("X") for row in board) o_count = sum(row.count("O") for row in board) if o_count not in (x_count - 1, x_count): return False x_wins = self._wins(board, "X") o_wins = self._wins(board, "O") if x_wins and o_wins: return False if x_wins: return x_count == o_count + 1 if o_wins: return x_count == o_count return True def _wins(self, board: list[str], player: str) -> bool: lines = [board[i] for i in range(3)] lines += ["".join(row[j] for row in board) for j in range(3)] lines.append("".join(board[i][i] for i in range(3))) lines.append("".join(board[i][2 - i] for i in range(3))) return any(line == player * 3 for line in lines) ``` ## Complexity | Time | Space | | -------------------------------- | ----- | | O(1) - the board is always 3 x 3 | O(1) | ## Tags # Valid Triangle Number Python Solution Source: https://leetcode-py.wisl.dev/problems/valid-triangle-number Tested Python solution for LeetCode 611 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 611, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Two Pointers](/catalog/topics/two-pointers), [Binary Search](/catalog/topics/binary-search), [Greedy](/catalog/topics/greedy), [Sorting](/catalog/topics/sorting). [View on LeetCode](https://leetcode.com/problems/valid-triangle-number/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 611 # by problem number lcpy gen -s valid_triangle_number # by problem name ``` ## Problem Given an integer array `nums`, return the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle. ### Examples ``` Input: nums = [2,2,3,4] Output: 3 Explanation: Valid combinations are: 2,3,4 (using the first 2) 2,3,4 (using the second 2) 2,2,3 ``` ``` Input: nums = [4,2,3,4] Output: 4 ``` ### Constraints * 1 \<= nums.length \<= 1000 * 0 \<= nums\[i] \<= 1000 ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_triangle_number/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_triangle_number/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n^2) # Space: O(1) extra (sorting not counted) def triangle_number(self, nums: list[int]) -> int: nums = sorted(nums) count = 0 for k in range(len(nums) - 1, 1, -1): left, right = 0, k - 1 while left < right: if nums[left] + nums[right] > nums[k]: count += right - left right -= 1 else: left += 1 return count ``` ## Complexity | Time | Space | | ------ | -------------------------------- | | O(n^2) | O(1) extra (sorting not counted) | ## Tags # Valid Word Abbreviation Python Solution Source: https://leetcode-py.wisl.dev/problems/valid-word-abbreviation Tested Python solution for LeetCode 408 with 32 pytest cases. Generate a practice environment with lcpy. LeetCode 408, [Easy](/catalog/easy). Topics: [Two Pointers](/catalog/topics/two-pointers), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/valid-word-abbreviation/description/). Generate this problem as a practice environment: tested reference solution, 32 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 408 # by problem number lcpy gen -s valid_word_abbreviation # by problem name ``` ## Problem A string can be **abbreviated** by replacing any number of **non-adjacent**, **non-empty** substrings with their lengths. The lengths **should not** have leading zeros. For example, a string such as `"substitution"` could be abbreviated as (but not limited to): * `"s10n"` (`"s ubstitutio n"`) * `"sub4u4"` (`"sub stit u tion"`) * `"12"` (`"substitution"`) * `"su3i1u2on"` (`"su bst i t u ti on"`) * `"substitution"` (no substrings replaced) The following are **not valid** abbreviations: * `"s55n"` (`"s ubsti tutio n"`, the replaced substrings are adjacent) * `"s010n"` (has leading zeros) * `"s0ubstitution"` (replaces an empty substring) Given a string `word` and an abbreviation `abbr`, return *whether the string **matches** the given abbreviation*. A **substring** is a contiguous **non-empty** sequence of characters within a string. ### Examples ``` Input: word = "internationalization", abbr = "i12iz4n" Output: true Explanation: The word "internationalization" can be abbreviated as "i12iz4n" ("i nternational iz atio n"). ``` ``` Input: word = "apple", abbr = "a2e" Output: false Explanation: The word "apple" cannot be abbreviated as "a2e". ``` ### Constraints * `1 <= word.length <= 20` * `1 <= abbr.length <= 20` * `word` consists of only lowercase English letters. * `abbr` consists of lowercase English letters and digits. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_word_abbreviation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_word_abbreviation/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(n) # Space: O(1) def valid_word_abbreviation(self, word: str, abbr: str) -> bool: i = j = 0 m, n = len(word), len(abbr) while i < m and j < n: if abbr[j].isdigit(): if abbr[j] == "0": return False count = 0 while j < n and abbr[j].isdigit(): count = count * 10 + int(abbr[j]) j += 1 i += count else: if word[i] != abbr[j]: return False i += 1 j += 1 return i == m and j == n ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Valid Word Square Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/valid-word-square Tested Python solution for LeetCode 422 with 16 pytest cases. Generate a practice environment with lcpy. LeetCode 422, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/valid-word-square/description/). Generate this problem as a practice environment: tested reference solution, 16 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 422 # by problem number lcpy gen -s valid_word_square # by problem name ``` ## Problem Given an array of strings `words`, return `true` *if it forms a valid **word square***. A sequence of strings forms a valid **word square** if the `k^th` row and column read the same string, where `0 <= k < max(numRows, numColumns)`. ### Examples  ``` Input: words = ["abcd","bnrt","crmy","dtye"] Output: true Explanation: The 1st row and 1st column both read "abcd". The 2nd row and 2nd column both read "bnrt". The 3rd row and 3rd column both read "crmy". The 4th row and 4th column both read "dtye". Therefore, it is a valid word square. ```  ``` Input: words = ["abcd","bnrt","crm","dt"] Output: true Explanation: The 1st row and 1st column both read "abcd". The 2nd row and 2nd column both read "bnrt". The 3rd row and 3rd column both read "crm". The 4th row and 4th column both read "dt". Therefore, it is a valid word square. ```  ``` Input: words = ["ball","area","read","lady"] Output: false Explanation: The 3rd row reads "read" while the 3rd column reads "lead". Therefore, it is NOT a valid word square. ``` ### Constraints * `1 <= words.length <= 500` * `1 <= words[i].length <= 500` * `words[i]` consists of only lower-case English letters. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_word_square/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/valid_word_square/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(m * n) for m rows of length n # Space: O(1) def valid_word_square(self, words: list[str]) -> bool: for i, word in enumerate(words): for j, ch in enumerate(word): if j >= len(words) or i >= len(words[j]) or words[j][i] != ch: return False return True ``` ## Complexity | Time | Space | | -------------------------------- | ----- | | O(m \* n) for m rows of length n | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Validate Binary Search Tree Python Solution Source: https://leetcode-py.wisl.dev/problems/validate-binary-search-tree Tested Python solution for LeetCode 98 with 12 pytest cases. Generate a practice environment with lcpy. LeetCode 98, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Binary Search Tree](/catalog/topics/binary-search-tree), [Binary Tree](/catalog/topics/binary-tree). [View on LeetCode](https://leetcode.com/problems/validate-binary-search-tree/description/). Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 98 # by problem number lcpy gen -s validate_binary_search_tree # by problem name ``` ## Problem Given the `root` of a binary tree, determine if it is a valid binary search tree (BST). A **valid BST** is defined as follows: * The left subtree of a node contains only nodes with keys **strictly less than** the node's key. * The right subtree of a node contains only nodes with keys **strictly greater than** the node's key. * Both the left and right subtrees must also be binary search trees. ### Examples  ``` Input: root = [2,1,3] Output: true ```  ``` Input: root = [5,1,4,null,null,3,6] Output: false ``` **Explanation:** The root node's value is 5 but its right child's value is 4. ### Constraints * The number of nodes in the tree is in the range `[1, 10^4]`. * `-2^31 <= Node.val <= 2^31 - 1` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/validate_binary_search_tree/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/validate_binary_search_tree/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque from leetcode_py import TreeNode class Solution: @classmethod def validate(cls, node: TreeNode[int] | None, min_val: float, max_val: float) -> bool: if not node: return True if node.val <= min_val or node.val >= max_val: return False return cls.validate(node.left, min_val, node.val) and cls.validate( node.right, node.val, max_val ) # Time: O(n) # Space: O(h) def is_valid_bst(self, root: TreeNode[int] | None) -> bool: return self.validate(root, float("-inf"), float("inf")) class SolutionDFS: # Time: O(n) # Space: O(h) def is_valid_bst(self, root: TreeNode[int] | None) -> bool: if not root: return True stack = [(root, float("-inf"), float("inf"))] while stack: node, min_val, max_val = stack.pop() if node.val <= min_val or node.val >= max_val: return False if node.right: stack.append((node.right, node.val, max_val)) if node.left: stack.append((node.left, min_val, node.val)) return True class SolutionBFS: # Time: O(n) # Space: O(w) where w is max width def is_valid_bst(self, root: TreeNode[int] | None) -> bool: if not root: return True queue = deque([(root, float("-inf"), float("inf"))]) while queue: node, min_val, max_val = queue.popleft() if node.val <= min_val or node.val >= max_val: return False if node.right: queue.append((node.right, node.val, max_val)) if node.left: queue.append((node.left, min_val, node.val)) return True ``` ## Complexity | Time | Space | | ---- | ----- | | O(n) | O(h) | ## Tags [Grind 75](/catalog/grind-75), [Grind](/catalog/grind), [Blind 75](/catalog/blind-75), [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75). # Validate Binary Tree Nodes Python Solution Source: https://leetcode-py.wisl.dev/problems/validate-binary-tree-nodes Tested Python solution for LeetCode 1361 with 20 pytest cases. Generate a practice environment with lcpy. LeetCode 1361, [Medium](/catalog/medium). Topics: [Tree](/catalog/topics/tree), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [Union Find](/catalog/topics/union-find), [Graph](/catalog/topics/graph). [View on LeetCode](https://leetcode.com/problems/validate-binary-tree-nodes/description/). Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1361 # by problem number lcpy gen -s validate_binary_tree_nodes # by problem name ``` ## Problem You have \n\ binary tree nodes numbered from \0\ to \n - 1\ where node \i\ has two children \leftChild\[i]\ and \rightChild\[i]\, return \true\ if and only if all the given nodes form \exactly one valid binary tree\.
If node \i\ has no left child then \leftChild\[i]\ will equal \-1\, similarly for the right child.
Note that the nodes have no values and that we only use the node numbers in this problem.
### Examples
```
Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
Output: true
```
```
Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
Output: false
```
```
Input: n = 2, leftChild = [1,0], rightChild = [-1,-1]
Output: false
```
### Constraints
* n == leftChild.length == rightChild.length
* 1 \<= n \<= 10^4
* -1 \<= leftChild\[i], rightChild\[i] \<= n - 1
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/validate_binary_tree_nodes/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/validate_binary_tree_nodes/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n)
def validate_binary_tree_nodes(
self, n: int, left_child: list[int], right_child: list[int]
) -> bool:
# A valid binary tree: exactly one root (in-degree 0), every other
# node has in-degree 1, and all nodes are reachable from the root.
indegree = [0] * n
for child in left_child + right_child:
if child == -1:
continue
indegree[child] += 1
if indegree[child] > 1:
return False
roots = [i for i in range(n) if indegree[i] == 0]
if len(roots) != 1:
return False
seen = [False] * n
stack = [roots[0]]
count = 0
while stack:
node = stack.pop()
if seen[node]:
return False
seen[node] = True
count += 1
for child in (left_child[node], right_child[node]):
if child != -1:
stack.append(child)
return count == n
```
## Complexity
| Time | Space |
| ---- | ----- |
| O(n) | O(n) |
## Tags
[NeetCode All](/catalog/neetcode).
# Validate IP Address Python Solution with Tests
Source: https://leetcode-py.wisl.dev/problems/validate-ip-address
Tested Python solution for LeetCode 468 with 25 pytest cases. Generate a practice environment with lcpy.
LeetCode 468, [Medium](/catalog/medium). Topics: [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/validate-ip-address/description/).
Generate this problem as a practice environment: tested reference solution, 25 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 468 # by problem number
lcpy gen -s validate_ip_address # by problem name
```
## Problem
Given a string `queryIP`, return `"IPv4"` if IP is a valid IPv4 address, `"IPv6"` if IP is a valid IPv6 address or `"Neither"` if IP is not a correct IP of any type.
A valid **IPv4** address is an IP in the form `"x1.x2.x3.x4"` where `0 <= xi <= 255` and `xi` **cannot contain** leading zeros. For example, `"192.168.1.1"` and `"192.168.1.0"` are valid IPv4 addresses while `"192.168.01.1"`, `"192.168.1.00"`, and `"192.168@1.1"` are invalid IPv4 addresses.
A valid **IPv6** address is an IP in the form `"x1:x2:x3:x4:x5:x6:x7:x8"` where:
* `1 <= xi.length <= 4`
* `xi` is a **hexadecimal string** which may contain digits, lowercase English letters (`'a'` to `'f'`) and upper-case English letters (`'A'` to `'F'`).
* Leading zeros are allowed in `xi`.
For example, `"2001:0db8:85a3:0000:0000:8a2e:0370:7334"` and `"2001:db8:85a3:0:0:8A2E:0370:7334"` are valid IPv6 addresses, while `"2001:0db8:85a3::8A2E:037j:7334"` and `"02001:0db8:85a3:0000:0000:8a2e:0370:7334"` are invalid IPv6 addresses.
### Examples
```
Input: queryIP = "172.16.254.1"
Output: "IPv4"
```
**Explanation:** This is a valid IPv4 address, return "IPv4".
```
Input: queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
Output: "IPv6"
```
**Explanation:** This is a valid IPv6 address, return "IPv6".
```
Input: queryIP = "256.256.256.256"
Output: "Neither"
```
**Explanation:** This is neither a IPv4 address nor a IPv6 address.
### Constraints
* 1 \<= queryIP.length \<= 50
* queryIP consists only of English letters, digits and the characters '.' and ':'.
## Solution
Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/validate_ip_address/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/validate_ip_address/test_solution.py):
```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
# Time: O(n)
# Space: O(n) for the split parts
def valid_ip_address(self, query_ip: str) -> str:
if self._is_ipv4(query_ip):
return "IPv4"
if self._is_ipv6(query_ip):
return "IPv6"
return "Neither"
def _is_ipv4(self, query_ip: str) -> bool:
parts = query_ip.split(".")
if len(parts) != 4:
return False
return all(self._is_ipv4_octet(part) for part in parts)
def _is_ipv4_octet(self, part: str) -> bool:
if not part or len(part) > 3 or not part.isdigit():
return False
if part[0] == "0" and len(part) > 1:
return False
return int(part) <= 255
def _is_ipv6(self, query_ip: str) -> bool:
parts = query_ip.split(":")
if len(parts) != 8:
return False
return all(self._is_ipv6_group(part) for part in parts)
def _is_ipv6_group(self, part: str) -> bool:
if not 1 <= len(part) <= 4:
return False
return all(char in self.HEX_DIGITS for char in part)
HEX_DIGITS: frozenset[str] = frozenset("0123456789abcdefABCDEF")
```
## Complexity
| Time | Space |
| ---- | ------------------------ |
| O(n) | O(n) for the split parts |
## Tags
# Validate Stack Sequences Python Solution
Source: https://leetcode-py.wisl.dev/problems/validate-stack-sequences
Tested Python solution for LeetCode 946 with 15 pytest cases. Generate a practice environment with lcpy.
LeetCode 946, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Stack](/catalog/topics/stack), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/validate-stack-sequences/description/).
Generate this problem as a practice environment: tested reference solution, 15 [parametrized pytest cases](/practice/testing), and a playground notebook:
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 946 # by problem number
lcpy gen -s validate_stack_sequences # by problem name
```
## Problem
\Given two integer arrays \pushed\ and \popped\ each with \distinct\ values, return \true\ if this could have been the result of a sequence of push and pop operations on an initially empty stack, or \false\ otherwise.\
(0, 0)\ facing north. The robot receives an array of integers \commands\, which represents a sequence of moves that it needs to execute. There are only three possible types of instructions the robot can receive:\
\-2\: Turn left 90 degrees.\-1\: Turn right 90 degrees.\1 \<= k \<= 9\: Move forward \k\ units, one unit at a time.\Some of the grid squares are obstacles. The \ith\ obstacle is at grid point \obstacles\[i] = (xi, yi)\. If the robot runs into an obstacle, it will stay in its current location (on the block adjacent to the obstacle) and move onto the next command.\
Return \the maximum squared Euclidean distance that the robot reaches at any point in its path\.\
### Examples ``` Input: commands = [4,-1,3], obstacles = [] Output: 25 Explanation: The robot starts at (0, 0): 1. Move north 4 units to (0, 4). 2. Turn right to face east. 3. Move east 3 units to (3, 4). The furthest point the robot ever gets from the origin is (3, 4), which squared is 3^2 + 4^2 = 25 units away. ``` ``` Input: commands = [4,-1,4,-2,4], obstacles = [[2,4]] Output: 65 Explanation: The robot is being tracked: 1. Move north 4 units to (0, 4). 2. Turn right to face east. 3. Move east 1 unit and get blocked by the obstacle at (2, 4), robot is at (1, 4). 4. Turn left to face north. 5. Move north 4 units to (1, 8). The furthest point the robot ever gets from the origin is (1, 8), which squared is 1^2 + 8^2 = 65 units away. ``` ``` Input: commands = [6,-1,-1,6], obstacles = [] Output: 36 Explanation: The robot starts at (0, 0): 1. Move north 6 units to (0, 6). 2. Turn right to face east. 3. Turn right to face south. 4. Move south 6 units to (0, 0). The furthest point the robot ever gets from the origin is (0, 6), which squared is 6^2 = 36 units away. ``` ### Constraints * 1 \<= commands.length \<= 10^4 * commands\[i] is either -2, -1, or an integer in the range \[1, 9]. * 0 \<= obstacles.length \<= 10^4 * -3 \* 10^4 \<= xi, yi \<= 3 \* 10^4 * The answer is guaranteed to be less than 2^31. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/walking_robot_simulation/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/walking_robot_simulation/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(c + o) # Space: O(o) def robot_sim(self, commands: list[int], obstacles: list[list[int]]) -> int: blocked = {(x, y) for x, y in obstacles} x, y, dx, dy = 0, 0, 0, 1 best = 0 for command in commands: if command == -2: dx, dy = -dy, dx elif command == -1: dx, dy = dy, -dx else: for _ in range(command): next_x, next_y = x + dx, y + dy if (next_x, next_y) in blocked: break x, y = next_x, next_y best = max(best, x * x + y * y) return best ``` ## Complexity | Time | Space | | -------- | ----- | | O(c + o) | O(o) | ## Tags [NeetCode All](/catalog/neetcode). # Walls And Gates Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/walls-and-gates Tested Python solution for LeetCode 286 with 17 pytest cases. Generate a practice environment with lcpy. LeetCode 286, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Breadth-First Search](/catalog/topics/breadth-first-search), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/walls-and-gates/description/). Generate this problem as a practice environment: tested reference solution, 17 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 286 # by problem number lcpy gen -s walls_and_gates # by problem name ``` ## Problem You are given a `m × n` 2D grid initialized with these three possible values: * `-1` - A wall or obstacle that can not be traversed. * `0` - A gate. * `INF` - Infinity an empty room. We use the value `2^31 - 1 = 2147483647` to represent `INF`. Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with `INF`. **Follow up:** Can you solve it in-place and in O(m × n) time complexity? ### Examples ``` Input: rooms = [[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]] Output: [[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]] ``` **Explanation:** the 2D grid is: ``` INF -1 0 INF INF INF INF -1 INF -1 INF -1 0 -1 INF INF ``` the result is: ``` 3 -1 0 1 2 2 1 -1 1 -1 2 -1 0 -1 3 4 ``` explanation: the gate is located at (0,2), (3,0), (3,3). the room at (0,0) is distance 3 from the nearest gate at (3,0). ``` Input: rooms = [[0,-1],[2147483647,2147483647]] Output: [[0,-1],[1,2]] ``` ### Constraints * `m == rooms.length` * `n == rooms[i].length` * `1 <= m, n <= 100` * `rooms[i][j]` is one of `-1`, `0`, or `2147483647`. ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/walls_and_gates/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/walls_and_gates/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from collections import deque class Solution: # Time: O(m * n) # Space: O(m * n) def walls_and_gates(self, rooms: list[list[int]]) -> None: if not rooms or not rooms[0]: return rows, cols = len(rooms), len(rooms[0]) queue: deque[tuple[int, int]] = deque() for r in range(rows): for c in range(cols): if rooms[r][c] == 0: queue.append((r, c)) directions = [(1, 0), (-1, 0), (0, 1), (0, -1)] while queue: r, c = queue.popleft() for dr, dc in directions: nr, nc = r + dr, c + dc if 0 <= nr < rows and 0 <= nc < cols and rooms[nr][nc] == 2147483647: rooms[nr][nc] = rooms[r][c] + 1 queue.append((nr, nc)) ``` ## Complexity | Time | Space | | --------- | --------- | | O(m \* n) | O(m \* n) | ## Tags [NeetCode 150](/catalog/neetcode-150), [NeetCode 250](/catalog/neetcode-250), [NeetCode All](/catalog/neetcode). # Water and Jug Problem Python Solution Source: https://leetcode-py.wisl.dev/problems/water-and-jug-problem Tested Python solution for LeetCode 365 with 26 pytest cases. Generate a practice environment with lcpy. LeetCode 365, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), Greatest Common Divisor. [View on LeetCode](https://leetcode.com/problems/water-and-jug-problem/description/). Generate this problem as a practice environment: tested reference solution, 26 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 365 # by problem number lcpy gen -s water_and_jug_problem # by problem name ``` ## Problem You are given two jugs with capacities `x` liters and `y` liters. You have an infinite water supply. Return *whether the total amount of water in both jugs may reach* `target` *using the following operations*: * Fill either jug completely with water. * Completely empty either jug. * Pour water from one jug into another until the receiving jug is full, or the transferring jug is empty. ### Examples ``` Input: x = 3, y = 5, target = 4 Output: true Explanation: Fill the 5-liter jug (0, 5). Pour from the 5-liter jug into the 3-liter jug, leaving 2 liters (3, 2). Empty the 3-liter jug (0, 2). Transfer the 2 liters from the 5-liter jug to the 3-liter jug (2, 0). Fill the 5-liter jug again (2, 5). Pour from the 5-liter jug into the 3-liter jug until the 3-liter jug is full. This leaves 4 liters in the 5-liter jug (3, 4). Empty the 3-liter jug. Now, you have exactly 4 liters in the 5-liter jug (0, 4). ``` ``` Input: x = 2, y = 6, target = 5 Output: false ``` ``` Input: x = 1, y = 2, target = 3 Output: true Explanation: Fill both jugs. The total amount of water in both jugs is equal to 3 now. ``` ### Constraints * `1 <= x, y, target <= 10^3` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/water_and_jug_problem/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/water_and_jug_problem/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} from math import gcd class Solution: # Time: O(log(min(x, y))) # Space: O(1) def can_measure_water(self, x: int, y: int, target: int) -> bool: if target > x + y: return False return target % gcd(x, y) == 0 ``` ## Complexity | Time | Space | | ----------------- | ----- | | O(log(min(x, y))) | O(1) | ## Tags # Water Bottles Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/water-bottles Tested Python solution for LeetCode 1518 with 22 pytest cases. Generate a practice environment with lcpy. LeetCode 1518, [Easy](/catalog/easy). Topics: [Math](/catalog/topics/math), [Simulation](/catalog/topics/simulation). [View on LeetCode](https://leetcode.com/problems/water-bottles/description/). Generate this problem as a practice environment: tested reference solution, 22 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1518 # by problem number lcpy gen -s water_bottles # by problem name ``` ## Problem There are `numBottles` water bottles that are initially full of water. You can exchange `numExchange` empty water bottles from the market with one full water bottle. The operation of drinking a full water bottle turns it into an empty bottle. Given the two integers `numBottles` and `numExchange`, return *the **maximum** number of water bottles you can drink*. ### Examples  ``` Input: numBottles = 9, numExchange = 3 Output: 13 Explanation: You can exchange 3 empty bottles to get 1 full water bottle. Number of water bottles you can drink: 9 + 3 + 1 = 13. ```  ``` Input: numBottles = 15, numExchange = 4 Output: 19 Explanation: You can exchange 4 empty bottles to get 1 full water bottle. Number of water bottles you can drink: 15 + 3 + 1 = 19. ``` ### Constraints * `1 <= numBottles <= 100` * `2 <= numExchange <= 100` ## Solution Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/water_bottles/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/water_bottles/test_solution.py): ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} class Solution: # Time: O(log numBottles) # Space: O(1) def num_water_bottles(self, num_bottles: int, num_exchange: int) -> int: drunk = num_bottles empty = num_bottles while empty >= num_exchange: full, empty = divmod(empty, num_exchange) drunk += full empty += full return drunk ``` ## Complexity | Time | Space | | ----------------- | ----- | | O(log numBottles) | O(1) | ## Tags [NeetCode All](/catalog/neetcode). # Web Crawler Python Solution with Tests Source: https://leetcode-py.wisl.dev/problems/web-crawler Tested Python solution for LeetCode 1236 with 18 pytest cases. Generate a practice environment with lcpy. LeetCode 1236, [Medium](/catalog/medium). Topics: [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search), [String](/catalog/topics/string), [Interactive](/catalog/topics/interactive). [View on LeetCode](https://leetcode.com/problems/web-crawler/description/). Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} lcpy gen -n 1236 # by problem number lcpy gen -s web_crawler # by problem name ``` ## Problem Given a url `startUrl` and an interface `HtmlParser`, implement a web crawler to crawl all links that are under the same hostname as `startUrl`. Return all urls obtained by your web crawler in **any** order. Your crawler should: * Start from the page: `startUrl` * Call `HtmlParser.getUrls(url)` to get all urls from a webpage of given url. * Do not crawl the same link twice. * Explore only the links that are under the same hostname as `startUrl`.  As shown in the example url above, the hostname is `example.org`. For simplicity sake, you may assume all urls use http protocol without any port specified. For example, the urls `http://leetcode.com/problems` and `http://leetcode.com/contest` are under the same hostname, while urls `http://example.org/test` and `http://example.com/abc` are not under the same hostname. The `HtmlParser` interface is defined as such: ``` interface HtmlParser { // Return a list of all urls from a webpage of given url. public Listwords1\ and \words2\.\
\A string \b\ is a \subset\ of string \a\ if every letter in \b\ occurs in \a\ including multiplicity.\
"wrr"\ is a subset of \"warrior"\ but is not a subset of \"world"\.\A string \a\ from \words1\ is \universal\ if for every string \b\ in \words2\, \b\ is a subset of \a\.\
Return an array of all the \universal\ strings in \words1\. You may return the answer in \any order\.\