Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b98d9ec

Browse files
authoredMay 14, 2025
Merge pull request #14 from Alonza0314/2025/05/09
2025/05/09
2 parents c2c9025 + 4d71938 commit b98d9ec

10 files changed

+262
-1
lines changed
 

‎Hard/312 Burst Balloons.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# 312. Burst Balloons
2+
3+
## Intuition
4+
5+
The key insight is to think about the problem in reverse: instead of bursting balloons one by one, we can think about adding balloons back one by one. For each step, we consider which balloon to add last.
6+
7+
## Approach
8+
9+
1. Add two dummy balloons with value 1 at the beginning and end of the array.
10+
2. Define `dp[left][right]` as the maximum coins that can be collected by bursting all balloons between indices left and right (exclusive).
11+
3. For each subproblem of length, we try each balloon (at position tmp) as the last one to burst.
12+
4. The recurrence relation is:
13+
`dp[left][right] = max(dp[left][right], dp[left][tmp] + dp[tmp][right] + nums[left] * nums[tmp] * nums[right])`
14+
5. The final answer is `dp[0][n+1]`, representing the maximum coins obtained by bursting all original balloons.
15+
16+
## Complexity
17+
18+
- Time complexity: O(n³)
19+
- Space complexity: O(n²)
20+
21+
## Keywords
22+
23+
- Dynamic Programming
24+
- Interval DP
25+
26+
## Code
27+
28+
```go
29+
func maxCoins(nums []int) int {
30+
nums = append([]int{1}, nums...)
31+
nums = append(nums, 1)
32+
33+
dp := make([][]int, len(nums))
34+
for i := range dp {
35+
dp[i] = make([]int, len(nums))
36+
}
37+
38+
for length := 2; length < len(nums); length += 1 {
39+
for left := 0; left < len(nums) - length; left += 1 {
40+
right := left + length
41+
for tmp := left + 1; tmp < right; tmp += 1 {
42+
dp[left][right] = max(dp[left][right], dp[left][tmp] + dp[tmp][right] + nums[left] * nums[tmp] * nums[right])
43+
}
44+
}
45+
}
46+
47+
return dp[0][len(nums) - 1]
48+
}
49+
```

‎Hard/887 Super Egg Drop.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# 887. Super Egg Drop
2+
3+
## Intuition
4+
5+
The traditional approach using dynamic programming with states (eggs, floors) leads to O(K*N²) complexity, which is too slow. Instead, we can reformulate the problem: if we have K eggs and can make M moves, what's the maximum number of floors we can cover?
6+
7+
## Approach
8+
9+
For each move, we have two possibilities when dropping an egg from a floor:
10+
11+
1. The egg breaks, so we can only use K-1 eggs for floors below
12+
2. The egg doesn't break, so we can use K eggs for floors above
13+
14+
We use a mathematical recursion to calculate the maximum floors we can cover with K eggs and M moves:
15+
16+
- Let maxFloor[i] represent the maximum number of floors that can be determined with i eggs and current number of moves
17+
- For each move, we update maxFloor[i] = 1 + maxFloor[i-1] + maxFloor[i]
18+
- maxFloor[i-1]: floors covered if egg breaks
19+
- maxFloor[i]: floors covered if egg doesn't break
20+
- +1: the current floor we're dropping from
21+
22+
We keep increasing the number of moves until the maximum floor we can check is greater than or equal to N.
23+
24+
## Complexity
25+
26+
- Time complexity: O(K log N)
27+
- Space complexity: O(K)
28+
29+
## Keywords
30+
31+
- Dynamic Programming
32+
33+
## Code
34+
35+
```go
36+
func superEggDrop(k int, n int) int {
37+
maxFloor := make([]int, k + 1)
38+
m := 0
39+
for ; maxFloor[k] < n; m += 1 {
40+
for i := k; i > 0; i -= 1 {
41+
maxFloor[i] = 1 + maxFloor[i - 1] + maxFloor[i]
42+
}
43+
}
44+
return m
45+
}
46+
```

‎Medium/416 Partition Equal Subset Sum.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ func canPartition(nums []int) bool {
6666
}
6767
return dp[sum]
6868
}
69-
```
69+
```

‎README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
| 210 | Course Schedule II | [go](/Medium/210%20Course%20Schedule%20II.md) | M |
2929
| 236 | Lowest Common Ancestor of a Binary Tree | [go](/Medium/236%20Lowest%20Common%20Ancestor%20of%20a%20Binary%20Tree.md) | M |
3030
| 239 | Sliding Window Maximum | [go](/Hard/239%20Sliding%20Window%20Maximum.md) | H |
31+
| 312 | Burst Balloons | [go](/Hard/312%20Burst%20Balloons.md) | H |
3132
| 322 | Coin Change | [go](/Medium/322%20Coin%20Change.md) | M |
3233
| 416 | Partition Equal Subset Sum | [go](/Medium/416%20Partition%20Equal%20Subset%20Sum.md) | M |
3334
| 435 | Non-overlapping Interval | [go](/Medium/435%20Non-overlapping%20Intervals.md) | M |
@@ -44,6 +45,7 @@
4445
| 855 | Exam Room | [go](/Medium/855%20Exam%20Room.md) | M |
4546
| 875 | Koko Eating Bananas | [go](/Medium/875%20Koko%20Eating%20Bananas.md) | M |
4647
| 881 | Boats to Save People | [go](/Medium/881%20Boats%20to%20Save%20People.md) | M |
48+
| 887 | Super Egg Drop | [go](/Hard/887%20Super%20Egg%20Drop.md) | H |
4749
| 912 | Sort an Array | [go](/Medium/912%20Sort%20an%20Array.md) | M |
4850
| 948 | Bag of Tokens | [go](/Medium/948%20Bag%20Of%20Tokens.md) | M |
4951
| 1395 | Count Number of Trams | [go](/Medium/1395%20Count%20Number%20of%20Teams.md) | M |

‎Week12/312 AC.png

122 KB
Loading

‎Week12/312 Burst Balloons.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# 312. Burst Balloons
2+
3+
## Intuition
4+
5+
The key insight is to think about the problem in reverse: instead of bursting balloons one by one, we can think about adding balloons back one by one. For each step, we consider which balloon to add last.
6+
7+
## Approach
8+
9+
1. Add two dummy balloons with value 1 at the beginning and end of the array.
10+
2. Define `dp[left][right]` as the maximum coins that can be collected by bursting all balloons between indices left and right (exclusive).
11+
3. For each subproblem of length, we try each balloon (at position tmp) as the last one to burst.
12+
4. The recurrence relation is:
13+
`dp[left][right] = max(dp[left][right], dp[left][tmp] + dp[tmp][right] + nums[left] * nums[tmp] * nums[right])`
14+
5. The final answer is `dp[0][n+1]`, representing the maximum coins obtained by bursting all original balloons.
15+
16+
## Complexity
17+
18+
- Time complexity: O(n³)
19+
- Space complexity: O(n²)
20+
21+
## Keywords
22+
23+
- Dynamic Programming
24+
- Interval DP
25+
26+
## Code
27+
28+
```go
29+
func maxCoins(nums []int) int {
30+
nums = append([]int{1}, nums...)
31+
nums = append(nums, 1)
32+
33+
dp := make([][]int, len(nums))
34+
for i := range dp {
35+
dp[i] = make([]int, len(nums))
36+
}
37+
38+
for length := 2; length < len(nums); length += 1 {
39+
for left := 0; left < len(nums) - length; left += 1 {
40+
right := left + length
41+
for tmp := left + 1; tmp < right; tmp += 1 {
42+
dp[left][right] = max(dp[left][right], dp[left][tmp] + dp[tmp][right] + nums[left] * nums[tmp] * nums[right])
43+
}
44+
}
45+
}
46+
47+
return dp[0][len(nums) - 1]
48+
}
49+
```

‎Week12/416 AC.png

125 KB
Loading
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# 416. Partition Equal Subset Sum
2+
3+
## Intuition
4+
5+
The problem can be transformed into finding if we can select some numbers from the array that sum up to half of the total sum. This is essentially a 0/1 knapsack problem where we need to determine if we can fill a knapsack of capacity sum/2 using the given numbers.
6+
7+
## Approach
8+
9+
1. First, calculate the total sum of the array
10+
2. If the sum is odd, return false as equal partition is impossible
11+
3. Divide the sum by 2 to get our target sum
12+
4. Use dynamic programming to solve:
13+
- Create a dp array where dp[j] represents if we can make sum j using the numbers
14+
- For each number, we can either include it or not include it
15+
- Use a temporary array to avoid affecting previous calculations
16+
- If at any point we can make the target sum, return true
17+
5. As an optimization, we also:
18+
- Sort the array first
19+
- Use binary search to check if target sum exists directly in array
20+
21+
## Complexity
22+
23+
- Time complexity: O(n * sum)
24+
- Space complexity: O(sum)
25+
26+
## Keywords
27+
28+
- Dynamic Programming
29+
- 0/1 Knapsack
30+
- Binary Search
31+
32+
## Code
33+
34+
```go
35+
func canPartition(nums []int) bool {
36+
sum := 0
37+
for _, num := range nums {
38+
sum += num
39+
}
40+
if sum & 1 == 1 {
41+
return false
42+
}
43+
sum >>= 1
44+
sort.Ints(nums)
45+
_, flag := slices.BinarySearch(nums, sum)
46+
if flag {
47+
return true
48+
}
49+
dp := make([]bool, sum + 1)
50+
dp[0] = true
51+
for _, num := range nums {
52+
tmp := make([]bool, sum + 1)
53+
tmp[0] = true
54+
for j := 1; j <= sum ; j += 1 {
55+
tmp[j] = dp[j]
56+
if j >= num {
57+
tmp[j] = (tmp[j] || dp[j - num])
58+
}
59+
}
60+
61+
if tmp[sum] {
62+
return true
63+
}
64+
65+
copy(dp, tmp)
66+
}
67+
return dp[sum]
68+
}
69+
```

‎Week12/887 AC.png

123 KB
Loading

‎Week12/887 Super Egg Drop.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# 887. Super Egg Drop
2+
3+
## Intuition
4+
5+
The traditional approach using dynamic programming with states (eggs, floors) leads to O(K*N²) complexity, which is too slow. Instead, we can reformulate the problem: if we have K eggs and can make M moves, what's the maximum number of floors we can cover?
6+
7+
## Approach
8+
9+
For each move, we have two possibilities when dropping an egg from a floor:
10+
11+
1. The egg breaks, so we can only use K-1 eggs for floors below
12+
2. The egg doesn't break, so we can use K eggs for floors above
13+
14+
We use a mathematical recursion to calculate the maximum floors we can cover with K eggs and M moves:
15+
16+
- Let maxFloor[i] represent the maximum number of floors that can be determined with i eggs and current number of moves
17+
- For each move, we update maxFloor[i] = 1 + maxFloor[i-1] + maxFloor[i]
18+
- maxFloor[i-1]: floors covered if egg breaks
19+
- maxFloor[i]: floors covered if egg doesn't break
20+
- +1: the current floor we're dropping from
21+
22+
We keep increasing the number of moves until the maximum floor we can check is greater than or equal to N.
23+
24+
## Complexity
25+
26+
- Time complexity: O(K log N)
27+
- Space complexity: O(K)
28+
29+
## Keywords
30+
31+
- Dynamic Programming
32+
33+
## Code
34+
35+
```go
36+
func superEggDrop(k int, n int) int {
37+
maxFloor := make([]int, k + 1)
38+
m := 0
39+
for ; maxFloor[k] < n; m += 1 {
40+
for i := k; i > 0; i -= 1 {
41+
maxFloor[i] = 1 + maxFloor[i - 1] + maxFloor[i]
42+
}
43+
}
44+
return m
45+
}
46+
```

0 commit comments

Comments
 (0)
Please sign in to comment.