Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion data/leetcode-problems.json
Original file line number Diff line number Diff line change
Expand Up @@ -25839,5 +25839,6 @@
"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": []},
"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": []},
"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": []},
"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": []}
"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": []},
"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": []}
}
84 changes: 44 additions & 40 deletions explanations/1008/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,55 @@

### Strategy

**Restate the problem**
Given preorder traversal of a BST, reconstruct the tree.

**1.1 Constraints & Complexity**
- **Input Size:** up to 100 nodes.
- **Time Complexity:** O(n) using a stack to place nodes.
- **Space Complexity:** O(n) for the stack/tree nodes.
- **Edge Case:** Single-node preorder list.

**1.2 High-level approach**
Iterate preorder; use a stack of ancestors. Each value smaller than stack top goes left; otherwise pop until finding parent, then attach right.
![BST reconstruction from preorder](https://assets.leetcode.com/static_assets/public/images/LeetCode_logo.png)

**1.3 Brute force vs. optimized strategy**
- **Brute Force:** Insert each value via BST insert — still O(n²) worst case (sorted input).
- **Optimized:** Monotonic stack to place nodes in O(n).

**1.4 Decomposition**
1. Create root from first value; push to stack.
2. For each next value:
- If value < stack top, set as left child of top.
- Else pop until stack empty or top > value; last popped is parent; attach as right child.
3. Push new node to stack.
4. Return root.
**Constraints & Edge Cases**

* **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.
* **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.
* **Edge Case:** If the array has only one element, we return a single node tree.

**High-level approach**

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.

**Brute force vs. optimized strategy**

* **Brute Force:** For each element, insert it into the BST one by one. This would be O(n²) time.
* **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.

**Decomposition**

1. **Root Selection:** The first element in preorder is always the root.
2. **Split Point:** Find where values transition from less than root to greater than root.
3. **Recursive Construction:** Build left subtree from elements before split, right subtree from elements after split.

### Steps

**2.1 Initialization & Example Setup**
Example: `[8,5,1,7,10,12]`; root = 8, stack = [8].
1. **Initialization & Example Setup**
Let's use `preorder = [8,5,1,7,10,12]` as our example.
- If preorder is empty, return None.

2. **Root Creation**
- Create root node with value `preorder[0] = 8`.

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

**2.3 Trace Walkthrough**
| val | Stack before | Action | Child |
|-----|--------------|---------------------------------|--------|
| 5 | [8] | 5 < 8 → left of 8 | left |
| 1 | [8,5] | 1 < 5 → left of 5 | left |
| 7 | [8,5,1] | pop 1,5 (last popped=5) → right | right |
| 10 | [8,7] | pop 7,8 (last popped=8) → right | right |
| 12 | [10] | pop none → right of 10 | right |
4. **Trace Walkthrough**

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

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

6. **Return Result**
Return the root node of the constructed BST.
82 changes: 45 additions & 37 deletions explanations/1079/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,57 @@

### Strategy

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

**1.1 Constraints & Complexity**
- **Input Size:** `1 <= len(tiles) <= 7`.
- **Time Complexity:** O(n! * n) in worst case (backtracking over permutations), acceptable for n <= 7.
- **Space Complexity:** O(n) recursion depth + O(1) counts.
- **Edge Case:** Single tile → exactly 1 sequence.
* **String Length:** The tiles string has length 1-7, consisting of uppercase English letters. This small constraint allows for backtracking solutions.
* **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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Clarify the time-complexity notation and what n represents.

Referring to n as “the number of unique sequences” is misleading—n is usually the input size (e.g., len(tiles)), and the number of sequences is what scales like 2^n. Please rephrase to define n as the input length (e.g., O(2^n) where n is len(tiles)), or use a more standard bound such as O(2^n * n) if you want to account for sequence length as well.

* **Edge Case:** If tiles has only one character, there's exactly one sequence (the character itself).

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

**1.3 Brute force vs. optimized strategy**
- **Brute Force:** Generate all permutations with duplicates and then deduplicate — costly.
- **Optimized:** Use counts to avoid generating identical branches; count as we go.
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.

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

### Steps

**2.1 Initialization & Example Setup**
Example: `tiles = "AAB"`; counts: A:2, B:1, `res=0`.
* **Brute Force:** Generate all possible sequences and count them. This is what we do, but we use backtracking to avoid duplicates efficiently.
* **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.

**2.2 Start Checking**
Try each available letter, recurse with updated counts.
**Decomposition**

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

**2.4 Increment and Loop**
Each pick adds 1 to `res` (for the new sequence) before deeper recursion.

**2.5 Return Result**
Final `res = 8` for the example.
### Steps

1. **Initialization & Example Setup**
Let's use `tiles = "AAB"` as our example.
- Count characters: `count = {'A': 2, 'B': 1}`.

2. **Backtrack Function**
The `backtrack(count)` function:
- Initialize `res = 0` to count sequences.
- For each character in count:
- If count[char] > 0, we can use it.
- Increment `res` by 1 (this character alone is a sequence).
- Decrement count[char], recursively call backtrack, then restore count[char].

3. **Trace Walkthrough**

Starting with `count = {'A': 2, 'B': 1}`:

| Step | Character | Count After | Sequences Found | Action |
|------|-----------|-------------|-----------------|--------|
| 1 | 'A' | {'A':1,'B':1} | 1 ("A") | Use A, recurse |
| 2 | 'A' | {'A':0,'B':1} | 1 ("AA") | Use A again, recurse |
| 3 | 'B' | {'A':0,'B':0} | 1 ("AAB") | Use B, recurse |
| 4 | 'B' | {'A':1,'B':0} | 1 ("AB") | Backtrack, use B instead |
| 5 | 'A' | {'A':0,'B':0} | 1 ("ABA") | Use A, recurse |
| 6 | 'B' | {'A':2,'B':0} | 1 ("B") | Backtrack, use B first |
| 7 | 'A' | {'A':1,'B':0} | 1 ("BA") | Use A, recurse |
| 8 | 'A' | {'A':0,'B':0} | 1 ("BAA") | Use A again |

Total: 8 sequences ("A", "AA", "AAB", "AB", "ABA", "B", "BA", "BAA")

4. **Return Result**
Return the total count from backtrack function.
68 changes: 36 additions & 32 deletions explanations/1261/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,51 @@

### Strategy

**Restate the problem**
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.
**Constraints & Edge Cases**

**1.1 Constraints & Complexity**
- **Input Size:** Up to `1e4` nodes, height <= 20.
- **Time Complexity:** O(n) to recover; O(1) average for `find` via set lookup.
- **Space Complexity:** O(n) to store recovered values.
- **Edge Case:** Single-node tree.
* **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.
* **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.
* **Edge Case:** If the tree is empty or has only one node, the recovery still works correctly.

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

**1.3 Brute force vs. optimized strategy**
- **Brute Force:** Recover on every `find`, re-walking the tree — repeated O(n).
- **Optimized:** Recover once, store in a set — O(n) build, O(1) queries.
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.

**1.4 Decomposition**
1. DFS from root with value parameter.
2. Assign `val`, insert into set.
3. Recurse to children with `2*val+1` and `2*val+2`.
4. `find` checks membership in the set.
**Brute force vs. optimized strategy**

* **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.
* **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.

**Decomposition**

1. **Recovery:** Traverse the tree and recover each node's value based on its parent's value.
2. **Storage:** Store all recovered values in a hash set for O(1) lookup.
3. **Query:** Check if target exists in the hash set.

### Steps

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

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

**2.3 Trace Walkthrough**
| Node | Assigned val | Action |
|------|--------------|---------------|
| root | 0 | add to set |
| left | 1 | add to set |
| right| 2 | add to set |
3. **Trace Walkthrough**

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

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

5. **Return Result**
Return True if target is in the set, False otherwise.
69 changes: 32 additions & 37 deletions explanations/1347/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,47 @@

### Strategy

**Restate the problem**
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`.
**Constraints & Edge Cases**
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use Markdown heading syntax for section headers instead of bold emphasis.

Lines 5, 11, 15, and 20 use bold text (e.g., **Constraints & Edge Cases**) for subsection headers. Per Markdown conventions and linting rules, these should use heading syntax (###) to maintain proper document structure and consistency.

Apply this diff to convert bold emphasis to proper Markdown headings:

-**Constraints & Edge Cases**
+### Constraints & Edge Cases

Repeat for lines 11, 15, and 20:

  • **High-level approach**### High-level approach
  • **Brute force vs. optimized strategy**### Brute force vs. optimized strategy
  • **Decomposition**### Decomposition

Also applies to: 11-11, 15-15, 20-20

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

5-5: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🤖 Prompt for AI Agents
In explanations/1347/en.md around lines 5, 11, 15, and 20, subsection headers
are written with bold emphasis (e.g., **Constraints & Edge Cases**) instead of
Markdown heading syntax; replace each bolded subsection header with a level-3
Markdown heading by changing the bold text to start with "### " (so line 5
becomes "### Constraints & Edge Cases", line 11 "### High-level approach", line
15 "### Brute force vs. optimized strategy", and line 20 "### Decomposition")
ensuring spacing consistency and leaving surrounding content unchanged.


**1.1 Constraints & Complexity**
- **Input Size:** up to 5×10^4 characters.
- **Time Complexity:** O(n) to count frequencies.
- **Space Complexity:** O(1) since alphabet size is fixed (26).
- **Edge Case:** Already anagrams → 0 steps.
* **String Length:** Both strings have length 1 to 5*10^4, and they have the same length. They consist of lowercase English letters only.
* **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).
* **Edge Case:** If the strings are already anagrams, return 0.

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

**1.3 Brute force vs. optimized strategy**
- **Brute Force:** Try all replacement combinations — exponential.
- **Optimized:** Frequency difference — O(n), straightforward.
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.

**1.4 Decomposition**
1. Count frequencies of `s` and `t`.
2. For each letter, compute `max(0, count_s - count_t)` and sum.
3. That sum is the number of replacements needed in `t`.
4. Return the sum.
**Brute force vs. optimized strategy**

* **Brute Force:** Try all possible character replacements. This would be exponential.
* **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.

**Decomposition**

1. **Count Frequencies:** Count occurrences of each character in s and t.
2. **Calculate Differences:** For each character, if s has more occurrences, add the difference to the result.
3. **Return:** The total number of replacements needed.

### Steps

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

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

**2.3 Trace Walkthrough**
| Char | count_s | count_t | deficit (if s needs more) |
|------|---------|---------|----------------------------|
| e | 3 | 1 | +2 |
| l | 1 | 0 | +1 |
| t | 1 | 1 | 0 |
| c | 1 | 2 | 0 |
| o | 1 | 0 | +1 |
| d | 1 | 0 | +1 |
| ... | ... | ... | ... |
Total = 5.
3. **Trace Walkthrough**

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

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

5. **Return Result**
Return the total number of steps: 1.
Loading