Home
DSA Patterns
Dynamic Programming
Burst Balloons
Burst Balloons
Maximise the coins from bursting every balloon with interval DP: guess which balloon in a range bursts last, so its neighbours are the range's walls.
Problem Understanding
Burst Balloons: balloon i has the number nums[i]. Bursting it earns nums[left] · nums[i] · nums[right], where left and right are its current neighbours (a missing neighbour counts as 1), and then those neighbours become adjacent. Return the most coins you can collect by bursting them all.
Example: nums = [3, 1, 5, 8] returns 167: burst 1, 5, 3, 8 for 15 + 120 + 24 + 8.
The Intuition: Think About the Last Balloon
Choosing the first balloon to burst does not split the problem: its neighbours change, so the left and right parts keep interacting.
Choose the last one instead. Pad the array with a 1 at each end, and look at the open interval between walls l and r:
- If
kis the last balloon burst inside it, everything else in(l, r)is already gone, sok's neighbours are exactlylandr. It earnsvals[l] · vals[k] · vals[r]. - Before that, the balloons in
(l, k)and in(k, r)were burst withkstanding between them as a wall, so the two sides never touch: they are independent subproblems. - Try every
kand keep the best:dp[l][r] = max(dp[l][k] + vals[l] · vals[k] · vals[r] + dp[k][r]).
This is interval dynamic programming: the state is a range, and ranges are filled from short to long. The same "split at k" shape solves matrix-chain multiplication; compare it with the row-by-row tables of Edit Distance.
Interactive Walkthrough
The padded balloons sit on top with the walls l, r and the last balloon k marked. Below, the triangle holds dp[l][r] for every interval with something inside; the cell being solved is solid and the two sub-intervals it adds are tinted. Try Ones inside to see why the cheap balloons go first.
Dry Run Table
Input: nums = [3, 1, 5, 8], padded to vals = [1, 3, 1, 5, 8, 1] (indexes 0 to 5)
| l \ r | 2 | 3 | 4 | 5 |
|---|---|---|---|---|
| 0 | 3 | 30 | 159 | 167 |
| 1 | 15 | 135 | 159 | |
| 2 | 40 | 48 | ||
| 3 | 40 |
dp[1][3] = 15: only balloon 1 (value 1) is inside, between 3 and 5.dp[0][5] = 167: the best last balloon is 8 (index 4):dp[0][4] 159 + 1 · 8 · 1 + dp[4][5] 0.
Answer: 167.
The Solution Template
Bottom-up interval DP, filled by length. len is the distance between the two walls, so an interval with one balloon inside has len = 2.
Burst Balloons Code
1var maxCoins = function(nums) {2 const vals = [1, ...nums, 1];3 const n = vals.length;4 const dp = Array.from({ length: n }, () => Array(n).fill(0));5 for (let len = 2; len < n; len++) {6 for (let l = 0; l + len < n; l++) {7 const r = l + len;8 for (let k = l + 1; k < r; k++) {9 const coins = dp[l][k] + vals[l] * vals[k] * vals[r] + dp[k][r];10 dp[l][r] = Math.max(dp[l][r], coins);11 }12 }13 }14 return dp[0][n - 1];15};
Edge Cases & Common Mistakes
- Choosing the first balloon: the subproblems are not independent; always reason about the last one.
- Forgetting the padding: without the 1s at each end, the walls of the outermost interval do not exist.
- Closed vs open intervals:
dp[l][r]covers balloons strictly betweenlandr; the walls themselves are not burst in that interval. - Fill order: iterating
lfrom 0 upward withrfroml + 2readsdp[k][r]before it is computed; fill by length, or runldownward. - One balloon:
[7]gives1 · 7 · 1 = 7.
Summary
Pad nums with 1 on both sides. For each interval by increasing length, try every balloon k inside as the last to burst: dp[l][k] + vals[l] · vals[k] · vals[r] + dp[k][r]. Return dp[0][n - 1]. O(n³) time, O(n²) space.
More practice: DSA interview questions with answers · patterns cheat sheet
