Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sum to target
.
Each number in candidates
may only be used once in the combination.
Note: The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8 Output: [ [1,1,6], [1,2,5], [1,7], [2,6] ]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5 Output: [ [1,2,2], [5] ]
Constraints:
1 <= candidates.length <= 100
1 <= candidates[i] <= 50
1 <= target <= 30
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:
The brute force approach for this problem is all about trying every possible combination. We'll explore all the ways to pick numbers from the given set, seeing which ones add up to our target number. It's like trying every possibility until we find the right ones.
Here's how the algorithm would work step-by-step:
def combination_sum_ii_brute_force(candidates, target):
results = []
unique_combinations = set()
def find_combinations(index, current_combination, current_sum):
if current_sum == target:
# Convert to tuple for set uniqueness check
sorted_combination = tuple(sorted(current_combination))
if sorted_combination not in unique_combinations:
results.append(current_combination[:])
unique_combinations.add(sorted_combination)
return
if current_sum > target or index >= len(candidates):
return
# Explore including the current candidate
current_combination.append(candidates[index])
find_combinations(index + 1, current_combination, current_sum + candidates[index])
current_combination.pop()
# Crucial step: Exclude current candidate.
find_combinations(index + 1, current_combination, current_sum)
find_combinations(0, [], 0)
return results
The key is to explore combinations in a structured way, avoiding redundant calculations caused by duplicate numbers. By carefully making each decision in a controlled manner, you can find all unique combinations that sum to the target efficiently. This also involves pre-processing the numbers to make the search more efficient.
Here's how the algorithm would work step-by-step:
def combination_sum_two(candidates, target):
result = []
candidates.sort()
def backtrack(combination, remaining_target, start_index):
if remaining_target == 0:
result.append(combination[:])
return
if remaining_target < 0:
return
for i in range(start_index, len(candidates)):
# Prevent duplicate combinations
if i > start_index and candidates[i] == candidates[i - 1]:
continue
current_candidate = candidates[i]
# Explore including the current number
combination.append(current_candidate)
backtrack(combination, remaining_target - current_candidate, i + 1)
# Backtrack: remove the current number to explore other possibilities
combination.pop()
backtrack([], target, 0)
return result
Case | How to Handle |
---|---|
Empty candidates array | Return an empty list since there are no numbers to form combinations. |
Null candidates array | Throw an IllegalArgumentException or return an empty list, depending on desired behavior and constraints, to prevent a NullPointerException. |
Target is zero | Return a list containing an empty list if the candidates contains a zero, and an empty list if not. |
Candidates array contains negative numbers | The problem statement typically forbids negative numbers, so either throw an IllegalArgumentException or filter out negative values from the input array before processing. |
Candidates array contains duplicate numbers that can lead to duplicate combinations | Sort the candidates array and skip over duplicate numbers during the recursive calls to avoid generating the same combination multiple times. |
Target is negative | Return an empty list because with positive candidates it is impossible to reach a negative target. |
Target is unreachable with the given candidates | Return an empty list after exploring all possible combinations without finding any that sum up to the target. |
Candidates array contains very large numbers that could lead to integer overflow when summing | If the sum exceeds the maximum integer value, either switch to using long to store intermediate sums, or if the sum becomes greater than target, backtrack to avoid integer overflow issues. |