HomeLeetcode377. Combination Sum IV - Leetcode Solutions

377. Combination Sum IV – Leetcode Solutions

Description

Given an array of distinct integers nums and a target integer target, return the number of possible combinations that add up to target.

The test cases are generated so that the answer can fit in a 32-bit integer.

Examples:

Example 1:

Input: nums = [1,2,3], target = 4
Output: 7
Explanation:
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.

Example 2:

Input: nums = [9], target = 3
Output: 0

Solution in Python

To solve this problem, we need to calculate the number of combinations of elements from the list nums that sum up to a given target. Since the order of elements matters, different sequences with the same numbers are considered different combinations.

Approach:

This is a Dynamic Programming (DP) problem, where:

  • We define dp[i] as the number of ways to achieve a sum of i using the numbers in nums.
  • The solution to the problem will be stored in dp[target].

Steps:

  1. Define Base Case:
    • dp[0] = 1: There is one way to make the sum of 0, which is by choosing no numbers.
  2. Recurrence Relation:
    • For each number i from 1 to target, we iterate through each number in nums. If num <= i, we add dp[i - num] to dp[i] because if we already know how many ways we can get i - num, adding num to each of those combinations gives us valid combinations to reach i.
  3. Iterate and Fill the DP Array:
    • We start from i = 1 up to target and fill in the values of dp[i] based on previously computed values.
  4. Result:
    • The result will be stored in dp[target].

This approach ensures that each sub-problem (sum i) is solved only once, and it efficiently builds up the solution to target.

Complexity:

  • Time Complexity: O(target×len(nums)) because for each sum from 1 to target, we iterate over all elements in nums.
  • Space Complexity: O(target) for the dp array.
Python
class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        # Initialize a DP array with (target + 1) elements, all set to 0 initially
        dp = [0] * (target + 1)
        
        # Base case: There is one way to achieve a sum of 0 (by using no numbers)
        dp[0] = 1
        
        # Fill dp array for each sum from 1 to target
        for i in range(1, target + 1):
            # For each number in nums, check if it can be used to reach the current sum i
            for num in nums:
                if i >= num:
                    # Add the number of ways to make up (i - num) to dp[i]
                    dp[i] += dp[i - num]
        
        # The result is the number of ways to achieve the sum `target`
        return dp[target]

Explanation with Example:

For nums = [1, 2, 3] and target = 4:

  1. Initialize dp = [1, 0, 0, 0, 0].
  2. Compute each dp[i]:
    • dp[1]: Only 1 can reach 1, so dp[1] = dp[0] = 1.
    • dp[2]: 1+1 and 2 can reach 2, so dp[2] = dp[1] + dp[0] = 1 + 1 = 2.
    • dp[3]: 1+1+1, 1+2, and 3 can reach 3, so dp[3] = dp[2] + dp[1] + dp[0] = 2 + 1 + 1 = 4.
    • dp[4]: 1+1+1+1, 1+1+2, 1+3, 2+2, 3+1 can reach 4, so dp[4] = dp[3] + dp[2] + dp[1] = 4 + 2 + 1 = 7.

So, dp[4] = 7, which is the answer.

Solution in C++

C++
class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        // Step 1: Create a DP array of size `target + 1` to store the number of ways 
        // to reach each sum from 0 up to `target`. Initialize all elements to 0.
        vector<unsigned int> dp(target + 1, 0);
        
        // Step 2: Base case - there is one way to reach the sum of 0, which is by not 
        // choosing any elements.
        dp[0] = 1;
        
        // Step 3: Fill the DP array. For each intermediate sum from 1 to `target`, 
        // calculate the number of ways it can be formed using the elements in `nums`.
        for (int i = 1; i <= target; i++) {
            // Step 4: For each number in `nums`, check if it can be used to form the 
            // current sum `i`. This is possible if `i - num >= 0`.
            for (int num : nums) {
                if (i - num >= 0) {
                    // Step 5: Add the number of ways to reach `i - num` to the number of ways to reach `i`.
                    dp[i] += dp[i - num];
                }
            }
        }
        
        // Step 6: The answer is the number of ways to reach the target sum.
        return dp[target];
    }
};

Solution in Javascript

JavaScript
var combinationSum4 = function(nums, target) {
    // Initialize a dp array where dp[i] represents the number of combinations to reach sum i.
    // Set dp[0] = 1 because there is one way to reach sum 0: by choosing no elements.
    const dp = new Array(target + 1).fill(0);
    dp[0] = 1;
    
    // Loop through all possible sums from 1 to the target.
    for (let i = 1; i <= target; i++) {
        // For each sum i, iterate over all numbers in nums.
        for (let num of nums) {
            // Check if the current number can contribute to the sum i.
            if (i >= num) {
                // Add the number of ways to form (i - num) to dp[i].
                dp[i] += dp[i - num];
            }
        }
    }
    
    // dp[target] now contains the number of combinations to form the target sum.
    return dp[target];
};

Solution in Java

Java
class Solution {
    public int combinationSum4(int[] nums, int target) {
        // DP array where dp[i] represents the number of ways to reach sum i
        int[] dp = new int[target + 1];
        
        // Base case: there's one way to get to 0 (by choosing no elements)
        dp[0] = 1;
        
        // Loop through each sum from 1 up to the target
        for (int currentTarget = 1; currentTarget <= target; currentTarget++) {
            // Check each number in the nums array to see if it can contribute
            for (int num : nums) {
                // Only proceed if the current number is not greater than the currentTarget
                if (num <= currentTarget) {
                    // Add the ways to get to the remaining target after using 'num'
                    dp[currentTarget] += dp[currentTarget - num];
                }
            }
        }
        
        // dp[target] now contains the number of combinations to reach 'target'
        return dp[target];
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular