Description
You are given n
balloons, indexed from 0
to n - 1
. Each balloon is painted with a number on it represented by an array nums
. You are asked to burst all the balloons.
If you burst the ith
balloon, you will get nums[i - 1] * nums[i] * nums[i + 1]
coins. If i - 1
or i + 1
goes out of bounds of the array, then treat it as if there is a balloon with a 1
painted on it.
Return the maximum coins you can collect by bursting the balloons wisely.
Examples:
Example 1:
Input: nums = [3,1,5,8]
Output: 167
Explanation:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
Example 2:
Input: nums = [1,5]
Output: 10
Solution in Python
Python
class Solution:
def maxCoins(self, nums: List[int]) -> int:
# Add 1 at the beginning and the end of the list to handle edge cases easily.
nums = [1] + nums + [1]
n = len(nums)
# Create a dp array where dp[left][right] represents the maximum coins
# that can be obtained by bursting all balloons between indices left and right (exclusive).
dp = [[0] * n for _ in range(n)]
# Iterate over the possible lengths of subarrays to burst
for length in range(2, n): # length is the distance between 'left' and 'right'
for left in range(0, n - length): # left boundary of the subarray
right = left + length # right boundary of the subarray
# Iterate over each balloon to burst last in this subarray (between left and right)
for i in range(left + 1, right):
# Calculate the coins gained by bursting the ith balloon last in this range
coins = nums[left] * nums[i] * nums[right]
# Add the coins gained from the subproblems (left, i) and (i, right)
coins += dp[left][i] + dp[i][right]
# Update the dp value for the range (left, right)
dp[left][right] = max(dp[left][right], coins)
# Return the result from bursting all balloons between the first and last added 1s
return dp[0][n - 1]
Explanation:
- Input Augmentation: We first add
1
at both ends of thenums
list. This simplifies edge cases where a balloon is burst at the beginning or the end of the list, as they can be treated as adjacent to an implicit balloon with a value of 1. - DP Array Setup: A 2D list
dp
is created wheredp[left][right]
stores the maximum coins that can be obtained from bursting balloons between indicesleft
andright
, exclusively. - Dynamic Programming: We iterate over possible lengths of subarrays to burst. For each subarray, we try bursting each balloon in that range as the last one and calculate the coins earned by it. This involves:
- Bursting the balloon
i
, which givesnums[left] * nums[i] * nums[right]
coins. - Adding the result of solving the subproblems for the ranges
(left, i)
and(i, right)
, i.e., the coins collected from bursting all other balloons in these subarrays.
- Bursting the balloon
- Result: The value
dp[0][n-1]
will contain the maximum coins from bursting all the balloons in the original array, as it considers the entire range between the first and last balloon (with the two added1
s).
Solution in C++
C++
class Solution {
public:
int maxCoins(vector<int>& nums) {
// Add 1 at the beginning and the end of the nums array to handle boundary conditions easily
nums.insert(nums.begin(), 1);
nums.push_back(1);
int n = nums.size(); // n is the size of the modified nums array
// Create a 2D dp array where dp[left][right] will store the maximum coins
// we can get by bursting all the balloons between the indices left and right (exclusive)
vector<vector<int>> dp(n, vector<int>(n, 0));
// Iterate over the possible lengths of subarrays to burst
for (int length = 2; length < n; ++length) {
for (int left = 0; left < n - length; ++left) {
int right = left + length; // Define the right boundary of the subarray
// Iterate over each balloon to burst last in the range (left, right)
for (int i = left + 1; i < right; ++i) {
// Calculate the coins gained by bursting the ith balloon last in this range
int coins = nums[left] * nums[i] * nums[right];
// Add the coins obtained from the two subproblems dp[left][i] and dp[i][right]
coins += dp[left][i] + dp[i][right];
// Update the dp array with the maximum coins for the range (left, right)
dp[left][right] = max(dp[left][right], coins);
}
}
}
// The result is stored in dp[0][n-1], which corresponds to bursting all balloons
// between the first and last added 1s (i.e., the entire original nums array)
return dp[0][n-1];
}
};
Solution in Javascript
JavaScript
var maxCoins = function(nums) {
// Add 1 at the beginning and the end of the nums array to simplify boundary conditions
nums.unshift(1);
nums.push(1);
const n = nums.length; // n is the size of the modified nums array
// Create a 2D dp array where dp[left][right] will store the maximum coins
// we can get by bursting all balloons between the indices left and right (exclusive)
const dp = Array.from({ length: n }, () => Array(n).fill(0));
// Iterate over the possible lengths of subarrays to burst
for (let length = 2; length < n; length++) {
for (let left = 0; left < n - length; left++) {
let right = left + length; // Define the right boundary of the subarray
// Iterate over each balloon to burst last in the range (left, right)
for (let i = left + 1; i < right; i++) {
// Calculate the coins gained by bursting the ith balloon last in this range
const coins = nums[left] * nums[i] * nums[right];
// Add the coins obtained from the two subproblems dp[left][i] and dp[i][right]
const totalCoins = coins + dp[left][i] + dp[i][right];
// Update the dp array with the maximum coins for the range (left, right)
dp[left][right] = Math.max(dp[left][right], totalCoins);
}
}
}
// The result is stored in dp[0][n-1], which corresponds to bursting all balloons
// between the first and last added 1s (i.e., the entire original nums array)
return dp[0][n - 1];
};
Solution in Java
Java
class Solution {
public int maxCoins(int[] nums) {
// Create a new array with 1 added at the beginning and the end of nums
int n = nums.length;
int[] extendedNums = new int[n + 2];
// Add 1 at the beginning and the end of the extendedNums array
extendedNums[0] = 1;
extendedNums[n + 1] = 1;
// Copy the original nums array into extendedNums
for (int i = 1; i <= n; i++) {
extendedNums[i] = nums[i - 1];
}
// Create a dp array where dp[left][right] represents the maximum coins
// we can collect by bursting all balloons between indices left and right (exclusive)
int[][] dp = new int[n + 2][n + 2];
// Iterate over possible lengths of subarrays
for (int length = 2; length < n + 2; length++) {
for (int left = 0; left < n + 2 - length; left++) {
int right = left + length; // Define the right boundary of the subarray
// Iterate over each balloon to burst last in this subarray (between left and right)
for (int i = left + 1; i < right; i++) {
// Calculate the coins obtained by bursting the ith balloon last in this subarray
int coins = extendedNums[left] * extendedNums[i] * extendedNums[right];
// Add the coins obtained from the two subproblems: dp[left][i] and dp[i][right]
coins += dp[left][i] + dp[i][right];
// Update the dp value for the range (left, right)
dp[left][right] = Math.max(dp[left][right], coins);
}
}
}
// The result is stored in dp[0][n+1], which corresponds to bursting all balloons
// between the first and last added 1s (i.e., the entire original nums array)
return dp[0][n + 1];
}
}