Skip to content

Commit da1be55

Browse files
committed
Add solutions, explanations, and update normalize_json.py for problems 1925, 3100, 3133, 3164, 3197, 3228, 3260, 3291, 3320, 3351, 3380, 3413, 3444, 3471
- Solutions verified and accepted via LeetCode submitter - Created explanations following required structure - Updated normalize_json.py to follow Prettier style with one number per line for arrays - Fixed solutions for 3380 (rectangle validation) and 3291 (Trie optimization)
1 parent 2645c5b commit da1be55

File tree

19 files changed

+4995
-234
lines changed

19 files changed

+4995
-234
lines changed

data/book-sets.json

Lines changed: 4147 additions & 167 deletions
Large diffs are not rendered by default.

explanations/1925/en.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We need to count the number of square triples (a, b, c) where a² + b² = c² and all three numbers are between 1 and n.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `1 <= n <= 250`
9+
- **Time Complexity:** O(n²) where n is the input value, as we iterate over all pairs (a, b)
10+
- **Space Complexity:** O(1) as we only use a counter variable
11+
- **Edge Case:** When n = 1, there are no valid triples since we need at least 3 numbers
12+
13+
**1.2 High-level approach:**
14+
We iterate through all possible pairs (a, b), calculate c² = a² + b², and check if the square root of c² is an integer and within the range [1, n].
15+
16+
![Pythagorean triple visualization](https://assets.leetcode.com/static_assets/others/pythagorean-triple.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Try all combinations of (a, b, c) and check if a² + b² = c², which would be O(n³)
20+
- **Optimized Strategy:** For each pair (a, b), calculate c and verify it's a perfect square, achieving O(n²) time
21+
- **Emphasize the optimization:** By calculating c from a and b, we eliminate the need to iterate over c, reducing complexity from O(n³) to O(n²)
22+
23+
**1.4 Decomposition:**
24+
1. Initialize a counter to zero
25+
2. Iterate through all possible values of a from 1 to n
26+
3. For each a, iterate through all possible values of b from 1 to n
27+
4. Calculate c² = a² + b² and find c as the integer square root
28+
5. Verify that c is a perfect square (c * c == c²) and within range [1, n]
29+
6. Increment the counter for each valid triple
30+
31+
### Steps (The "How")
32+
33+
**2.1 Initialization & Example Setup:**
34+
Let's use the example: `n = 5`
35+
- Initialize counter: `res = 0`
36+
37+
**2.2 Start Checking:**
38+
We iterate through all pairs (a, b).
39+
40+
**2.3 Trace Walkthrough:**
41+
42+
| a | b |||| c | c*c == c²? | 1 <= c <= 5? | Count |
43+
|---|---|----|----|----|---|------------|---------------|-------|
44+
| 3 | 4 | 9 | 16 | 25 | 5 | Yes | Yes | 1 |
45+
| 4 | 3 | 16 | 9 | 25 | 5 | Yes | Yes | 2 |
46+
47+
**2.4 Increment and Loop:**
48+
After checking all pairs, we continue to the result.
49+
50+
**2.5 Return Result:**
51+
The result is 2, representing the two valid triples: (3, 4, 5) and (4, 3, 5).

explanations/3100/en.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We start with numBottles full bottles. We can drink bottles (turning them into empty bottles) and exchange empty bottles for full ones. Each exchange requires numExchange empty bottles and increases the exchange rate by 1. We want to maximize the total bottles drunk.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `1 <= numBottles <= 100`, `1 <= numExchange <= 100`
9+
- **Time Complexity:** O(numBottles) in the worst case, as we exchange until we can't
10+
- **Space Complexity:** O(1) as we only track a few variables
11+
- **Edge Case:** If numExchange > numBottles initially, we can only drink the initial bottles
12+
13+
**1.2 High-level approach:**
14+
We drink all initial bottles, then repeatedly exchange empty bottles for full ones while the exchange rate allows. Each exchange gives us one more bottle to drink and increases the exchange rate.
15+
16+
![Water bottles exchange visualization](https://assets.leetcode.com/static_assets/others/greedy-algorithm.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Simulate each operation step by step, which is what we do - this is already optimal
20+
- **Optimized Strategy:** Greedily exchange whenever possible, maximizing drinks at each step
21+
- **Emphasize the optimization:** The greedy approach ensures we always maximize drinks by exchanging as soon as we have enough empty bottles
22+
23+
**1.4 Decomposition:**
24+
1. Drink all initial bottles and count them
25+
2. While we have enough empty bottles for an exchange, exchange them for one full bottle
26+
3. Drink the newly obtained full bottle
27+
4. Increase the exchange rate by 1 for the next exchange
28+
5. Repeat until we can't exchange anymore
29+
30+
### Steps (The "How")
31+
32+
**2.1 Initialization & Example Setup:**
33+
Let's use the example: `numBottles = 13`, `numExchange = 6`
34+
- Initial state: `res = 0`, `empty = 0`, `exchange = 6`
35+
- Drink all 13 bottles: `res = 13`, `empty = 13`
36+
37+
**2.2 Start Exchanging:**
38+
We check if we can exchange empty bottles for a full one.
39+
40+
**2.3 Trace Walkthrough:**
41+
42+
| Step | Empty | Exchange Rate | Can Exchange? | Action | Empty After | res |
43+
|------|-------|---------------|---------------|--------|-------------|-----|
44+
| Initial | 13 | 6 | Yes | Exchange 6 for 1, drink it | 8 | 14 |
45+
| 1 | 8 | 7 | Yes | Exchange 7 for 1, drink it | 2 | 15 |
46+
| 2 | 2 | 8 | No | Stop | 2 | 15 |
47+
48+
**2.4 Increment and Loop:**
49+
After each exchange, we increment the exchange rate and continue until we can't exchange.
50+
51+
**2.5 Return Result:**
52+
The result is 15, which is the maximum number of bottles we can drink.

explanations/3133/en.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We need to construct an array of n positive integers where each element is greater than the previous, and the bitwise AND of all elements equals x. We want to minimize the last element.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `1 <= n, x <= 10^8`
9+
- **Time Complexity:** O(log(max(n, x))) as we process bits of n-1
10+
- **Space Complexity:** O(1) as we only use a few variables
11+
- **Edge Case:** When n = 1, the result is simply x
12+
13+
**1.2 High-level approach:**
14+
We merge x with (n-1) by keeping all set bits of x and filling the remaining bit positions with bits from (n-1). This ensures the AND equals x while creating the smallest possible last element.
15+
16+
![Bit manipulation visualization](https://assets.leetcode.com/static_assets/others/bit-manipulation.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Try all possible arrays starting from x, which would be exponential
20+
- **Optimized Strategy:** Use bit manipulation to merge x with (n-1), ensuring AND equals x while minimizing the result
21+
- **Emphasize the optimization:** Bit manipulation allows us to directly construct the optimal value without searching
22+
23+
**1.4 Decomposition:**
24+
1. Start with x as the base result
25+
2. Process each bit of (n-1) from right to left
26+
3. For each bit position where x has 0, find the next available 0 position
27+
4. If the current bit of (n-1) is 1, set the corresponding bit in the result
28+
5. Continue until all bits of (n-1) are processed
29+
30+
### Steps (The "How")
31+
32+
**2.1 Initialization & Example Setup:**
33+
Let's use the example: `n = 3`, `x = 4`
34+
- Binary: x = 4 = `100`, n-1 = 2 = `10`
35+
- Initialize: `res = 4` (`100`), `v = 2` (`10`), `bit_pos = 0`
36+
37+
**2.2 Start Processing:**
38+
We process bits of v and merge them into res.
39+
40+
**2.3 Trace Walkthrough:**
41+
42+
| Step | v | v binary | bit_pos | res binary | Action | res after |
43+
|------|---|----------|---------|------------|--------|-----------|
44+
| Start | 2 | 10 | 0 | 100 | Check bit 0 of v | - |
45+
| 1 | 2 | 10 | 1 | 100 | v has 0 at bit 0, skip | 100 |
46+
| 2 | 1 | 1 | 1 | 100 | Find pos 1 (x has 0), v has 1, set bit 1 | 110 (6) |
47+
| 3 | 0 | 0 | 2 | 110 | v is 0, done | 110 (6) |
48+
49+
**2.4 Increment and Loop:**
50+
After processing all bits, we have the final result.
51+
52+
**2.5 Return Result:**
53+
The result is 6, which is the minimum last element. The array [4, 5, 6] has AND = 4 and satisfies the conditions.

explanations/3164/en.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We need to count subarrays of size (m+1) in nums that match a given pattern. The pattern specifies relationships between consecutive elements: 1 means increasing, 0 means equal, -1 means decreasing.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `2 <= n <= 100`, `1 <= m < n`
9+
- **Time Complexity:** O(n * m) where n is array length and m is pattern length, as we check each starting position and each pattern element
10+
- **Space Complexity:** O(1) as we only use a counter
11+
- **Edge Case:** When m = 0, all subarrays of size 1 match (trivially)
12+
13+
**1.2 High-level approach:**
14+
For each possible starting position, we check if the subarray matches the pattern by verifying each pattern condition against the corresponding elements in the subarray.
15+
16+
![Pattern matching visualization](https://assets.leetcode.com/static_assets/others/pattern-matching.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Check all subarrays and verify pattern, which is what we do - this is already optimal for the constraints
20+
- **Optimized Strategy:** For each starting position, verify pattern conditions sequentially, breaking early if a condition fails
21+
- **Emphasize the optimization:** Early termination when a pattern condition fails avoids unnecessary checks
22+
23+
**1.4 Decomposition:**
24+
1. Iterate through all possible starting positions i (from 0 to n-m-1)
25+
2. For each starting position, check if the subarray matches the pattern
26+
3. For each pattern element k, verify the relationship between nums[i+k] and nums[i+k+1]
27+
4. If all pattern conditions are satisfied, increment the counter
28+
5. Return the total count
29+
30+
### Steps (The "How")
31+
32+
**2.1 Initialization & Example Setup:**
33+
Let's use the example: `nums = [1,2,3,4,5,6]`, `pattern = [1,1]`
34+
- Initialize counter: `res = 0`
35+
- Pattern means: nums[i+1] > nums[i] and nums[i+2] > nums[i+1]
36+
37+
**2.2 Start Checking:**
38+
We check each possible starting position.
39+
40+
**2.3 Trace Walkthrough:**
41+
42+
| Start i | Subarray | Check nums[i+1] > nums[i]? | Check nums[i+2] > nums[i+1]? | Match? | Count |
43+
|---------|----------|----------------------------|------------------------------|--------|-------|
44+
| 0 | [1,2,3] | 2 > 1 ✓ | 3 > 2 ✓ | Yes | 1 |
45+
| 1 | [2,3,4] | 3 > 2 ✓ | 4 > 3 ✓ | Yes | 2 |
46+
| 2 | [3,4,5] | 4 > 3 ✓ | 5 > 4 ✓ | Yes | 3 |
47+
| 3 | [4,5,6] | 5 > 4 ✓ | 6 > 5 ✓ | Yes | 4 |
48+
49+
**2.4 Increment and Loop:**
50+
After checking all starting positions, we have the total count.
51+
52+
**2.5 Return Result:**
53+
The result is 4, representing the 4 subarrays that match the pattern.

explanations/3197/en.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We need to make the XOR of all array elements equal to k by flipping bits in the binary representation of elements. Each bit flip counts as one operation. We want the minimum number of operations.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `1 <= nums.length <= 10^5`
9+
- **Time Complexity:** O(n) where n is the length of nums, as we iterate once to calculate XOR
10+
- **Space Complexity:** O(1) as we only use a few variables
11+
- **Edge Case:** If the XOR of all elements already equals k, we need 0 operations
12+
13+
**1.2 High-level approach:**
14+
Calculate the XOR of all elements, then count how many bits differ between this XOR value and k. Each differing bit requires exactly one flip operation to correct.
15+
16+
![Bit manipulation visualization](https://assets.leetcode.com/static_assets/others/bit-manipulation.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Try all possible bit flips, which would be exponential
20+
- **Optimized Strategy:** Calculate the XOR of all elements, find the difference with k, and count the number of set bits in the difference
21+
- **Emphasize the optimization:** We can determine the minimum operations directly from the bitwise difference, avoiding any search
22+
23+
**1.4 Decomposition:**
24+
1. Calculate the XOR of all elements in the array
25+
2. Compute the bitwise XOR between the result and k to find differing bits
26+
3. Count the number of set bits in the difference
27+
4. Return the count as the minimum number of operations
28+
29+
### Steps (The "How")
30+
31+
**2.1 Initialization & Example Setup:**
32+
Let's use the example: `nums = [2,1,3,4]`, `k = 1`
33+
- Initialize: `xor_all = 0`
34+
35+
**2.2 Start Calculating:**
36+
We iterate through the array to calculate XOR.
37+
38+
**2.3 Trace Walkthrough:**
39+
40+
| Element | Binary | xor_all Before | xor_all After | Binary After |
41+
|---------|--------|----------------|---------------|--------------|
42+
| 2 | 010 | 000 | 010 | 010 |
43+
| 1 | 001 | 010 | 011 | 011 |
44+
| 3 | 011 | 011 | 000 | 000 |
45+
| 4 | 100 | 000 | 100 | 100 |
46+
47+
Final XOR: 100 (binary) = 4 (decimal)
48+
k = 1 = 001 (binary)
49+
Difference: 100 XOR 001 = 101 (binary) = 5 (decimal)
50+
Set bits in 101: 2 bits
51+
52+
**2.4 Increment and Loop:**
53+
After processing all elements, we calculate the difference and count bits.
54+
55+
**2.5 Return Result:**
56+
The result is 2, meaning we need to flip 2 bits to make the XOR equal to k.

explanations/3228/en.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We can remove pairs of elements from the array (first two, last two, or first and last) and get a score equal to their sum. We want to maximize the number of operations where all operations have the same score.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `2 <= nums.length <= 2000`
9+
- **Time Complexity:** O(n²) for DP with memoization, where n is array length
10+
- **Space Complexity:** O(n²) for the memoization cache
11+
- **Edge Case:** If all elements are the same, we can perform many operations with the same score
12+
13+
**1.2 High-level approach:**
14+
Try all three possible first operation scores. For each fixed score, use dynamic programming with memoization to find the maximum number of operations we can perform with that score.
15+
16+
![Dynamic programming visualization](https://assets.leetcode.com/static_assets/others/dynamic-programming.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Try all possible sequences of operations, which is exponential
20+
- **Optimized Strategy:** Fix the first operation score, then use DP with memoization to find the maximum operations for that score, achieving O(n²) time
21+
- **Emphasize the optimization:** Memoization avoids recalculating the same subproblems, dramatically reducing time complexity
22+
23+
**1.4 Decomposition:**
24+
1. Identify the three possible first operation scores (first two, last two, first and last)
25+
2. For each possible score, use DP to find maximum operations
26+
3. In DP, for each subarray [l, r], try all three removal options if they match the target score
27+
4. Use memoization to cache results for subarrays
28+
5. Return the maximum across all three possible scores
29+
30+
### Steps (The "How")
31+
32+
**2.1 Initialization & Example Setup:**
33+
Let's use the example: `nums = [3,2,1,2,3,4]`
34+
- Possible first scores: 3+2=5, 3+4=7, 4+3=7
35+
- Try target_score = 5
36+
37+
**2.2 Start DP:**
38+
We use memoized DP to find maximum operations for score 5.
39+
40+
**2.3 Trace Walkthrough:**
41+
42+
| Subarray | Options | Best Result |
43+
|----------|---------|-------------|
44+
| [3,2,1,2,3,4] | Remove first two (5), Remove last two (7), Remove first+last (7) | 1 + dp([1,2,3,4]) |
45+
| [1,2,3,4] | Remove first+last (5) | 1 + dp([2,3]) |
46+
| [2,3] | Remove first+last (5) | 1 + dp([]) |
47+
| [] | Base case | 0 |
48+
49+
Total: 1 + 1 + 1 = 3 operations
50+
51+
**2.4 Increment and Loop:**
52+
After trying all three possible scores, we take the maximum.
53+
54+
**2.5 Return Result:**
55+
The result is 3, which is the maximum number of operations with the same score.

explanations/3291/en.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Explanation
2+
3+
### Strategy (The "Why")
4+
5+
**Restate the problem:** We need to form the target string by concatenating valid strings, where a valid string is any prefix of a word in the words array. We want the minimum number of valid strings needed.
6+
7+
**1.1 Constraints & Complexity:**
8+
- Input size: `1 <= words.length <= 100`, `1 <= target.length <= 5000`
9+
- **Time Complexity:** O(sum(word_lengths) + n * m) where n is target length and m is average prefix length, using Trie
10+
- **Space Complexity:** O(sum(word_lengths)) for the Trie
11+
- **Edge Case:** If target starts with a character not in any word, return -1
12+
13+
**1.2 High-level approach:**
14+
Build a Trie of all prefixes from words, then use dynamic programming where dp[i] represents the minimum valid strings needed to form target[0:i]. For each position, use the Trie to find all matching prefixes.
15+
16+
![Trie and DP visualization](https://assets.leetcode.com/static_assets/others/trie-dp.png)
17+
18+
**1.3 Brute force vs. optimized strategy:**
19+
- **Brute Force:** Try all possible prefix combinations, which is exponential
20+
- **Optimized Strategy:** Use Trie for efficient prefix matching and DP to track minimum cost, achieving polynomial time
21+
- **Emphasize the optimization:** The Trie allows O(m) prefix matching instead of O(m * word_count), and DP avoids recalculating subproblems
22+
23+
**1.4 Decomposition:**
24+
1. Build a Trie containing all prefixes from all words
25+
2. Initialize DP array where dp[i] = minimum valid strings for target[0:i]
26+
3. For each position i in target, use Trie to find all matching prefixes starting at i
27+
4. Update dp[j] for each matching prefix ending at j
28+
5. Return dp[n] or -1 if impossible
29+
30+
### Steps (The "How")
31+
32+
**2.1 Initialization & Example Setup:**
33+
Let's use the example: `words = ["abc","aaaaa","bcdef"]`, `target = "aabcdabc"`
34+
- Build Trie with prefixes: "a", "aa", "aaa", ..., "abc", "bcd", "bcde", "bcdef", ...
35+
- Initialize: `dp = [0, inf, inf, ...]`
36+
37+
**2.2 Start Processing:**
38+
We use DP with Trie to find matching prefixes.
39+
40+
**2.3 Trace Walkthrough:**
41+
42+
| Position i | Trie Match | Prefix | End j | dp[j] Before | dp[j] After |
43+
|------------|-----------|--------|-------|--------------|-------------|
44+
| 0 | "aa" | "aa" | 2 | inf | 1 |
45+
| 0 | "a" | "a" | 1 | inf | 1 |
46+
| 2 | "bcd" | "bcd" | 5 | inf | 2 |
47+
| 5 | "abc" | "abc" | 8 | inf | 3 |
48+
49+
**2.4 Increment and Loop:**
50+
After processing all positions, we have dp[8] = 3.
51+
52+
**2.5 Return Result:**
53+
The result is 3, which is the minimum number of valid strings: "aa" + "bcd" + "abc" = "aabcdabc".

0 commit comments

Comments
 (0)