Skip to content

Commit 429207f

Browse files
Merge pull request #119 from romankurnovskii/problems-3562-2482-1261-1008-1630-1079-2785-797-237-3271-2637-1605-1551-1347-2326-1823-2221-2120
Add solutions and explanations for problems 237, 797, 1008, 1079, 1261, 1347, 1551, 1605, 1630, 1823, 2120, 2221, 2326, 2482, 2785, 3562
2 parents 0937f9b + 9e8160c commit 429207f

File tree

33 files changed

+811
-843
lines changed

33 files changed

+811
-843
lines changed

data/leetcode-problems.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25839,5 +25839,6 @@
2583925839
"2120": {"id": 2120, "category": "Simulation", "title": "Execution of All Suffix Instructions Staying in a Grid", "difficulty": "Medium", "link": "https://leetcode.com/problems/execution-of-all-suffix-instructions-staying-in-a-grid/", "tags": []},
2584025840
"2221": {"id": 2221, "category": "Array", "title": "Find Triangular Sum of an Array", "difficulty": "Medium", "link": "https://leetcode.com/problems/find-triangular-sum-of-an-array/", "tags": []},
2584125841
"1605": {"id": 1605, "category": "Matrix", "title": "Find Valid Matrix Given Row and Column Sums", "difficulty": "Medium", "link": "https://leetcode.com/problems/find-valid-matrix-given-row-and-column-sums/", "tags": []},
25842-
"1551": {"id": 1551, "category": "Math", "title": "Minimum Operations to Make Array Equal", "difficulty": "Medium", "link": "https://leetcode.com/problems/minimum-operations-to-make-array-equal/", "tags": []}
25842+
"1551": {"id": 1551, "category": "Math", "title": "Minimum Operations to Make Array Equal", "difficulty": "Medium", "link": "https://leetcode.com/problems/minimum-operations-to-make-array-equal/", "tags": []},
25843+
"3562": {"id": 3562, "category": "Dynamic Programming", "title": "Maximum Profit from Trading Stocks with Discounts", "difficulty": "Hard", "link": "https://leetcode.com/problems/maximum-profit-from-trading-stocks-with-discounts/", "tags": []}
2584325844
}

explanations/1008/en.md

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,55 @@
22

33
### Strategy
44

5-
**Restate the problem**
6-
Given preorder traversal of a BST, reconstruct the tree.
7-
8-
**1.1 Constraints & Complexity**
9-
- **Input Size:** up to 100 nodes.
10-
- **Time Complexity:** O(n) using a stack to place nodes.
11-
- **Space Complexity:** O(n) for the stack/tree nodes.
12-
- **Edge Case:** Single-node preorder list.
13-
14-
**1.2 High-level approach**
15-
Iterate preorder; use a stack of ancestors. Each value smaller than stack top goes left; otherwise pop until finding parent, then attach right.
16-
![BST reconstruction from preorder](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png)
17-
18-
**1.3 Brute force vs. optimized strategy**
19-
- **Brute Force:** Insert each value via BST insert — still O(n²) worst case (sorted input).
20-
- **Optimized:** Monotonic stack to place nodes in O(n).
21-
22-
**1.4 Decomposition**
23-
1. Create root from first value; push to stack.
24-
2. For each next value:
25-
- If value < stack top, set as left child of top.
26-
- Else pop until stack empty or top > value; last popped is parent; attach as right child.
27-
3. Push new node to stack.
28-
4. Return root.
5+
**Constraints & Edge Cases**
6+
7+
* **Preorder Array:** The preorder traversal array has length 1-100, with unique values between 1-1000. The array is guaranteed to form a valid BST.
8+
* **Time Complexity:** We process each element once, and for each element we may need to find the split point. In worst case, this is O(n²), but average case is O(n log n). **Time Complexity: O(n²)** worst case, **O(n log n)** average, **Space Complexity: O(n)** for recursion stack.
9+
* **Edge Case:** If the array has only one element, we return a single node tree.
10+
11+
**High-level approach**
12+
13+
The problem asks us to construct a BST from its preorder traversal. In preorder, the root comes first, followed by all left subtree nodes, then all right subtree nodes.
14+
15+
**Brute force vs. optimized strategy**
16+
17+
* **Brute Force:** For each element, insert it into the BST one by one. This would be O(n²) time.
18+
* **Optimized:** Use the property that in preorder, after the root, all values less than root form the left subtree, and all values greater than root form the right subtree. Recursively build left and right subtrees.
19+
20+
**Decomposition**
21+
22+
1. **Root Selection:** The first element in preorder is always the root.
23+
2. **Split Point:** Find where values transition from less than root to greater than root.
24+
3. **Recursive Construction:** Build left subtree from elements before split, right subtree from elements after split.
2925

3026
### Steps
3127

32-
**2.1 Initialization & Example Setup**
33-
Example: `[8,5,1,7,10,12]`; root = 8, stack = [8].
28+
1. **Initialization & Example Setup**
29+
Let's use `preorder = [8,5,1,7,10,12]` as our example.
30+
- If preorder is empty, return None.
31+
32+
2. **Root Creation**
33+
- Create root node with value `preorder[0] = 8`.
3434

35-
**2.2 Start Checking**
36-
Process each value, updating stack and children.
35+
3. **Find Split Point**
36+
- Start from index 1, find the first index where `preorder[i] >= preorder[0]`.
37+
- For our example: `preorder[1]=5 < 8`, `preorder[2]=1 < 8`, `preorder[3]=7 < 8`, `preorder[4]=10 >= 8`.
38+
- Split point `i = 4`.
3739

38-
**2.3 Trace Walkthrough**
39-
| val | Stack before | Action | Child |
40-
|-----|--------------|---------------------------------|--------|
41-
| 5 | [8] | 5 < 8 → left of 8 | left |
42-
| 1 | [8,5] | 1 < 5 → left of 5 | left |
43-
| 7 | [8,5,1] | pop 1,5 (last popped=5) → right | right |
44-
| 10 | [8,7] | pop 7,8 (last popped=8) → right | right |
45-
| 12 | [10] | pop none → right of 10 | right |
40+
4. **Trace Walkthrough**
4641

47-
**2.4 Increment and Loop**
48-
Continue until all preorder values are attached.
42+
| Step | Left Subtree | Root | Right Subtree | Action |
43+
|------|--------------|------|----------------|--------|
44+
| 1 | [5,1,7] | 8 | [10,12] | Create root(8) |
45+
| 2 | [1] | 5 | [7] | Build left: root(5) |
46+
| 3 | [] | 1 | [] | Build left of 5: root(1) |
47+
| 4 | [] | 7 | [] | Build right of 5: root(7) |
48+
| 5 | [] | 10 | [12] | Build right: root(10) |
49+
| 6 | [] | 12 | [] | Build right of 10: root(12) |
4950

50-
**2.5 Return Result**
51-
Root of the constructed BST.
51+
5. **Recursive Construction**
52+
- `root.left = bstFromPreorder([5,1,7])` → builds left subtree
53+
- `root.right = bstFromPreorder([10,12])` → builds right subtree
5254

55+
6. **Return Result**
56+
Return the root node of the constructed BST.

explanations/1079/en.md

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,57 @@
22

33
### Strategy
44

5-
**Restate the problem**
6-
Count all non-empty sequences that can be formed from the multiset of tiles (letters), respecting available counts.
5+
**Constraints & Edge Cases**
76

8-
**1.1 Constraints & Complexity**
9-
- **Input Size:** `1 <= len(tiles) <= 7`.
10-
- **Time Complexity:** O(n! * n) in worst case (backtracking over permutations), acceptable for n <= 7.
11-
- **Space Complexity:** O(n) recursion depth + O(1) counts.
12-
- **Edge Case:** Single tile → exactly 1 sequence.
7+
* **String Length:** The tiles string has length 1-7, consisting of uppercase English letters. This small constraint allows for backtracking solutions.
8+
* **Time Complexity:** We generate all possible sequences using backtracking. The number of sequences depends on the character frequencies. **Time Complexity: O(2^n)** where n is the number of unique sequences, **Space Complexity: O(n)** for recursion stack and character counts.
9+
* **Edge Case:** If tiles has only one character, there's exactly one sequence (the character itself).
1310

14-
**1.2 High-level approach**
15-
Use backtracking with frequency counts; at each step, pick a letter with remaining count, decrement, recurse, then restore.
16-
![Backtracking over letter counts](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png)
11+
**High-level approach**
1712

18-
**1.3 Brute force vs. optimized strategy**
19-
- **Brute Force:** Generate all permutations with duplicates and then deduplicate — costly.
20-
- **Optimized:** Use counts to avoid generating identical branches; count as we go.
13+
The problem asks us to count all possible non-empty sequences we can form from the given tiles. Each tile can be used at most as many times as it appears in the original string.
2114

22-
**1.4 Decomposition**
23-
1. Build frequency map of letters.
24-
2. DFS: for each letter with count > 0, use it (res++), decrement, recurse, restore.
25-
3. Sum all counts encountered.
26-
4. Return `res`.
15+
**Brute force vs. optimized strategy**
2716

28-
### Steps
29-
30-
**2.1 Initialization & Example Setup**
31-
Example: `tiles = "AAB"`; counts: A:2, B:1, `res=0`.
17+
* **Brute Force:** Generate all possible sequences and count them. This is what we do, but we use backtracking to avoid duplicates efficiently.
18+
* **Optimized:** Use backtracking with character frequency counting. For each character, we can either use it (if available) or skip it. Count each valid sequence as we build it.
3219

33-
**2.2 Start Checking**
34-
Try each available letter, recurse with updated counts.
20+
**Decomposition**
3521

36-
**2.3 Trace Walkthrough**
37-
| Path | Counts after pick | res increment | Notes |
38-
|---------|-------------------|---------------|--------------|
39-
| A | A:1,B:1 | +1 | recurse more |
40-
| AA | A:0,B:1 | +1 | recurse |
41-
| AAB | A:0,B:0 | +1 | dead end |
42-
| AB | A:1,B:0 | +1 | recurse |
43-
| ... | ... | ... | ... |
22+
1. **Count Characters:** Create a frequency map of all characters in tiles.
23+
2. **Backtrack:** For each character, try using it (if available) and recursively count sequences.
24+
3. **Count Sequences:** Each time we add a character, we have a new sequence, so increment the count.
4425

45-
**2.4 Increment and Loop**
46-
Each pick adds 1 to `res` (for the new sequence) before deeper recursion.
47-
48-
**2.5 Return Result**
49-
Final `res = 8` for the example.
26+
### Steps
5027

28+
1. **Initialization & Example Setup**
29+
Let's use `tiles = "AAB"` as our example.
30+
- Count characters: `count = {'A': 2, 'B': 1}`.
31+
32+
2. **Backtrack Function**
33+
The `backtrack(count)` function:
34+
- Initialize `res = 0` to count sequences.
35+
- For each character in count:
36+
- If count[char] > 0, we can use it.
37+
- Increment `res` by 1 (this character alone is a sequence).
38+
- Decrement count[char], recursively call backtrack, then restore count[char].
39+
40+
3. **Trace Walkthrough**
41+
42+
Starting with `count = {'A': 2, 'B': 1}`:
43+
44+
| Step | Character | Count After | Sequences Found | Action |
45+
|------|-----------|-------------|-----------------|--------|
46+
| 1 | 'A' | {'A':1,'B':1} | 1 ("A") | Use A, recurse |
47+
| 2 | 'A' | {'A':0,'B':1} | 1 ("AA") | Use A again, recurse |
48+
| 3 | 'B' | {'A':0,'B':0} | 1 ("AAB") | Use B, recurse |
49+
| 4 | 'B' | {'A':1,'B':0} | 1 ("AB") | Backtrack, use B instead |
50+
| 5 | 'A' | {'A':0,'B':0} | 1 ("ABA") | Use A, recurse |
51+
| 6 | 'B' | {'A':2,'B':0} | 1 ("B") | Backtrack, use B first |
52+
| 7 | 'A' | {'A':1,'B':0} | 1 ("BA") | Use A, recurse |
53+
| 8 | 'A' | {'A':0,'B':0} | 1 ("BAA") | Use A again |
54+
55+
Total: 8 sequences ("A", "AA", "AAB", "AB", "ABA", "B", "BA", "BAA")
56+
57+
4. **Return Result**
58+
Return the total count from backtrack function.

explanations/1261/en.md

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,51 @@
22

33
### Strategy
44

5-
**Restate the problem**
6-
Recover a contaminated binary tree where original root was 0 and children follow `left = 2*x+1`, `right = 2*x+2`. Support queries to check if a target value exists.
5+
**Constraints & Edge Cases**
76

8-
**1.1 Constraints & Complexity**
9-
- **Input Size:** Up to `1e4` nodes, height <= 20.
10-
- **Time Complexity:** O(n) to recover; O(1) average for `find` via set lookup.
11-
- **Space Complexity:** O(n) to store recovered values.
12-
- **Edge Case:** Single-node tree.
7+
* **Tree Structure:** The binary tree has a specific structure where root.val = 0, and for any node with value x, left child has value 2*x+1 and right child has value 2*x+2. The tree height is at most 20.
8+
* **Time Complexity:** Initialization takes O(n) time to recover all values, where n is the number of nodes. Each find operation is O(1) with a hash set. **Time Complexity: O(n)** for initialization, **O(1)** for find, **Space Complexity: O(n)** for storing values.
9+
* **Edge Case:** If the tree is empty or has only one node, the recovery still works correctly.
1310

14-
**1.2 High-level approach**
15-
DFS from root, assign values by the given formulas, store all in a hash set for O(1) membership.
16-
![Tree recovery with value formulas](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png)
11+
**High-level approach**
1712

18-
**1.3 Brute force vs. optimized strategy**
19-
- **Brute Force:** Recover on every `find`, re-walking the tree — repeated O(n).
20-
- **Optimized:** Recover once, store in a set — O(n) build, O(1) queries.
13+
The problem asks us to recover a contaminated binary tree and then check if a target value exists. The tree follows a specific pattern: root is 0, and each node's value determines its children's values.
2114

22-
**1.4 Decomposition**
23-
1. DFS from root with value parameter.
24-
2. Assign `val`, insert into set.
25-
3. Recurse to children with `2*val+1` and `2*val+2`.
26-
4. `find` checks membership in the set.
15+
**Brute force vs. optimized strategy**
16+
17+
* **Brute Force:** For each find operation, traverse the entire tree to check if the target exists. This would be O(n) per find, which is inefficient for multiple queries.
18+
* **Optimized:** Recover all values during initialization and store them in a hash set. Each find operation becomes O(1) lookup. This trades O(n) space for O(1) query time.
19+
20+
**Decomposition**
21+
22+
1. **Recovery:** Traverse the tree and recover each node's value based on its parent's value.
23+
2. **Storage:** Store all recovered values in a hash set for O(1) lookup.
24+
3. **Query:** Check if target exists in the hash set.
2725

2826
### Steps
2927

30-
**2.1 Initialization & Example Setup**
31-
Start at root with value 0, empty set.
28+
1. **Initialization & Example Setup**
29+
Let's use a tree with root value -1 (contaminated) as our example.
30+
- Initialize `self.values = set()` to store recovered values.
31+
- Call `recover(root, 0)` to start recovery from root with value 0.
3232

33-
**2.2 Start Processing**
34-
DFS visits each node, computing and storing values.
33+
2. **Recovery Process**
34+
The `recover` function recursively sets node values:
35+
- If node is None, return (base case).
36+
- Set `node.val = val` (recover the value).
37+
- Add `val` to `self.values`.
38+
- Recover left child: `recover(node.left, 2 * val + 1)`.
39+
- Recover right child: `recover(node.right, 2 * val + 2)`.
3540

36-
**2.3 Trace Walkthrough**
37-
| Node | Assigned val | Action |
38-
|------|--------------|---------------|
39-
| root | 0 | add to set |
40-
| left | 1 | add to set |
41-
| right| 2 | add to set |
41+
3. **Trace Walkthrough**
4242

43-
**2.4 Increment and Loop**
44-
Continue recursively; each node’s children follow the formula.
43+
For a tree `[-1, null, -1]` (root with right child):
44+
- Root: `recover(root, 0)``root.val = 0`, add 0 to set → `{0}`
45+
- Right child: `recover(root.right, 2*0+2 = 2)``right.val = 2`, add 2 to set → `{0, 2}`
4546

46-
**2.5 Return Result**
47-
`find(target)` returns `target in set`.
47+
4. **Find Operation**
48+
- `find(1)`: Check if 1 in `{0, 2}` → False
49+
- `find(2)`: Check if 2 in `{0, 2}` → True
4850

51+
5. **Return Result**
52+
Return True if target is in the set, False otherwise.

explanations/1347/en.md

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,47 @@
22

33
### Strategy
44

5-
**Restate the problem**
6-
Given two equal-length lowercase strings `s` and `t`, find the minimum number of character replacements in `t` to make it an anagram of `s`.
5+
**Constraints & Edge Cases**
76

8-
**1.1 Constraints & Complexity**
9-
- **Input Size:** up to 5×10^4 characters.
10-
- **Time Complexity:** O(n) to count frequencies.
11-
- **Space Complexity:** O(1) since alphabet size is fixed (26).
12-
- **Edge Case:** Already anagrams → 0 steps.
7+
* **String Length:** Both strings have length 1 to 5*10^4, and they have the same length. They consist of lowercase English letters only.
8+
* **Time Complexity:** We count frequencies in both strings (O(n)), then compare them (O(26) = O(1)). **Time Complexity: O(n)**, **Space Complexity: O(1)** for the frequency arrays (26 letters).
9+
* **Edge Case:** If the strings are already anagrams, return 0.
1310

14-
**1.2 High-level approach**
15-
Count letters in both strings; for each character, if `s` needs more than `t` has, that deficit contributes to the answer.
16-
![Frequency gap guiding replacements](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png)
11+
**High-level approach**
1712

18-
**1.3 Brute force vs. optimized strategy**
19-
- **Brute Force:** Try all replacement combinations — exponential.
20-
- **Optimized:** Frequency difference — O(n), straightforward.
13+
The problem asks for the minimum steps to make string t an anagram of string s. In each step, we can replace any character in t. We need to count how many characters in t need to be changed to match the frequency of characters in s.
2114

22-
**1.4 Decomposition**
23-
1. Count frequencies of `s` and `t`.
24-
2. For each letter, compute `max(0, count_s - count_t)` and sum.
25-
3. That sum is the number of replacements needed in `t`.
26-
4. Return the sum.
15+
**Brute force vs. optimized strategy**
16+
17+
* **Brute Force:** Try all possible character replacements. This would be exponential.
18+
* **Optimized:** Count character frequencies in both strings. For each character, if s has more occurrences than t, we need to replace (count_s[char] - count_t[char]) characters in t.
19+
20+
**Decomposition**
21+
22+
1. **Count Frequencies:** Count occurrences of each character in s and t.
23+
2. **Calculate Differences:** For each character, if s has more occurrences, add the difference to the result.
24+
3. **Return:** The total number of replacements needed.
2725

2826
### Steps
2927

30-
**2.1 Initialization & Example Setup**
31-
Example: `s="leetcode"`, `t="practice"`.
28+
1. **Initialization & Example Setup**
29+
Let's use `s = "bab"`, `t = "aba"` as our example.
30+
- Count s: `count_s = {'b': 2, 'a': 1}`.
31+
- Count t: `count_t = {'a': 2, 'b': 1}`.
3232

33-
**2.2 Start Checking**
34-
Build `count_s`, `count_t`.
33+
2. **Calculate Differences**
34+
- For 'a': `count_s['a'] = 1`, `count_t['a'] = 2`. No change needed (t has enough).
35+
- For 'b': `count_s['b'] = 2`, `count_t['b'] = 1`. Need `2 - 1 = 1` replacement.
3536

36-
**2.3 Trace Walkthrough**
37-
| Char | count_s | count_t | deficit (if s needs more) |
38-
|------|---------|---------|----------------------------|
39-
| e | 3 | 1 | +2 |
40-
| l | 1 | 0 | +1 |
41-
| t | 1 | 1 | 0 |
42-
| c | 1 | 2 | 0 |
43-
| o | 1 | 0 | +1 |
44-
| d | 1 | 0 | +1 |
45-
| ... | ... | ... | ... |
46-
Total = 5.
37+
3. **Trace Walkthrough**
4738

48-
**2.4 Increment and Loop**
49-
Sum deficits over all 26 letters.
39+
| Character | count_s | count_t | Difference | Steps Needed |
40+
|-----------|---------|---------|------------|--------------|
41+
| 'a' | 1 | 2 | 1 - 2 = -1 | 0 (t has enough) |
42+
| 'b' | 2 | 1 | 2 - 1 = 1 | 1 |
5043

51-
**2.5 Return Result**
52-
Return the total replacements (5 in the example).
44+
4. **Result**
45+
Total steps = 1. We need to replace one 'a' in t with 'b' to get "bba" or "abb", which are anagrams of "bab".
5346

47+
5. **Return Result**
48+
Return the total number of steps: 1.

0 commit comments

Comments
 (0)