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.
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
Constraints:
1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums
are unique.1 <= target <= 1000
Follow up: What if negative numbers are allowed in the given array? How does it change the problem? What limitation we need to add to the question to allow negative numbers?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We need to find the number of different combinations of numbers from a given set that add up to a specific target. The brute force way is to simply try every possible combination until we find all the ones that sum to the target. It's like trying every possibility until we hit the correct sum.
Here's how the algorithm would work step-by-step:
def combination_sum_brute_force(numbers, target):
number_of_combinations = 0
def find_combinations(current_sum, current_combination):
nonlocal number_of_combinations
# If the current sum is equal to the target,
# increment the number of combinations
if current_sum == target:
number_of_combinations += 1
return
# Stop exploring if the current sum exceeds the target
if current_sum > target:
return
for number in numbers:
# Explore combinations by adding each number from the input
# to the current combination
find_combinations(current_sum + number, current_combination + [number])
find_combinations(0, [])
return number_of_combinations
The best way to solve this is by building up the answer gradually. Instead of checking every single combination, we'll use prior calculated results to figure out the answer for larger numbers. This approach is similar to the idea of remembering answers to previous questions so you don't have to re-calculate them again.
Here's how the algorithm would work step-by-step:
def combination_sum_4(numbers, target): combinations = [0] * (target + 1)
# There is one way to reach zero, by using no numbers.
combinations[0] = 1
for current_target in range(1, target + 1):
for number in numbers:
# Only proceed if subtracting the number results in a non-negative value.
if current_target - number >= 0:
# Add ways to reach current target from previous reachable targets.
combinations[current_target] += combinations[current_target - number]
return combinations[target]
Case | How to Handle |
---|---|
nums is null or empty | Return 0 because no combinations can be formed with an empty set. |
target is 0 | Return 1 because there is one way to achieve a sum of 0 (choosing no numbers). |
target is negative | Return 0 because the sum of positive numbers cannot be negative. |
nums contains a number larger than target | The dynamic programming or recursive approach inherently handles this by not considering numbers larger than the remaining target. |
Integer overflow when calculating the number of combinations | Use a data type with a larger range (e.g., long) to store the number of combinations to avoid overflow. |
nums contains duplicate numbers - the problem states they are distinct, but good to ask | The problem statement guarantees distinct numbers, no special handling is needed, otherwise we'd need to modify our approach or pre-process to make the numbers distinct. |
Large input array nums and large target value | The dynamic programming solution has a time complexity of O(target * n), so ensure the target value does not cause a timeout. |
No possible combination exists to reach target | The dynamic programming or recursive solution will return 0, indicating no possible combinations. |