HomeLeetcode312. Burst Balloons - Leetcode Solutions

312. Burst Balloons – Leetcode Solutions

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:

  1. Input Augmentation: We first add 1 at both ends of the nums 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.
  2. DP Array Setup: A 2D list dp is created where dp[left][right] stores the maximum coins that can be obtained from bursting balloons between indices left and right, exclusively.
  3. 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 gives nums[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.
  4. 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 added 1s).

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];
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular