LeetCode Problem Workspace
Combination Sum II
Find all unique combinations of numbers that sum to a target using backtracking with careful pruning to avoid duplicates.
2
Topics
9
Code langs
3
Related
Practice Focus
Medium · Backtracking search with pruning
Answer-first summary
Find all unique combinations of numbers that sum to a target using backtracking with careful pruning to avoid duplicates.
Ace coding interviews with Interview AiBoxInterview AiBox guidance for Backtracking search with pruning
This problem requires generating all unique combinations from a list of candidates that sum exactly to a target. Each candidate can be used only once, and duplicates in the result must be avoided. A backtracking approach with pruning ensures efficiency by skipping repeated elements and stopping paths that exceed the target early.
Problem Statement
Given a list of candidate integers and a target integer, determine all unique combinations of candidates where the sum equals the target. Each number in the list can only be used once in a combination, so careful tracking of used elements is essential to avoid duplicate results.
Your solution must return all unique combinations without repetition. Efficient pruning during backtracking is necessary because exploring all subsets without eliminating duplicates can lead to exponential time waste, especially with repeated candidate values.
Examples
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 details omitted.
Example 2
Input: candidates = [2,5,2,1,2], target = 5
Output: [ [1,2,2], [5] ]
Example details omitted.
Constraints
- 1 <= candidates.length <= 100
- 1 <= candidates[i] <= 50
- 1 <= target <= 30
Solution Approach
Sort and Prepare Candidates
Start by sorting the candidate array. Sorting helps in pruning duplicate values and allows early stopping when the current sum exceeds the target. This setup ensures the backtracking search explores only valid paths.
Backtracking with Pruning
Use a recursive backtracking function to build combinations. Skip candidates that are identical to the previous one at the same recursion depth to prevent duplicate combinations. Stop recursion if the running sum exceeds the target to prune unnecessary paths.
Collect Valid Combinations
Whenever the running sum matches the target, add a copy of the current path to the results. After exploring each candidate, backtrack by removing the last element to explore alternative paths, ensuring all unique solutions are captured.
Complexity Analysis
| Metric | Value |
|---|---|
| Time | O(2^N) |
| Space | O(N) |
Time complexity is O(2^N) due to exploring subsets of candidates, and space complexity is O(N) for the recursion stack and temporary combination path storage.
What Interviewers Usually Probe
- Check if candidates are sorted to simplify duplicate handling.
- Ask about pruning early when sum exceeds target.
- Probe understanding of skipping duplicates in backtracking to avoid repeated combinations.
Common Pitfalls or Variants
Common pitfalls
- Not sorting candidates first, which complicates duplicate skipping.
- Using a candidate multiple times per combination when only single use is allowed.
- Failing to prune recursion early, leading to excessive computation and timeouts.
Follow-up variants
- Combination Sum (allowing unlimited usage of candidates).
- Target Sum with negative numbers included, requiring careful pruning.
- Finding combinations of a fixed length that sum to the target.
FAQ
What is the main difference between Combination Sum and Combination Sum II?
Combination Sum II allows each candidate to be used only once, whereas Combination Sum permits unlimited use of each candidate.
How does backtracking with pruning work in Combination Sum II?
It recursively explores candidate combinations, skipping duplicates and stopping paths where the current sum exceeds the target to optimize search.
Why do we need to sort candidates first?
Sorting ensures duplicates are adjacent, which allows easy skipping of repeated elements and enables early pruning when the sum exceeds the target.
Can the solution handle candidates with multiple duplicates?
Yes, but careful skipping of repeated values during the same recursion depth is necessary to prevent duplicate combinations in the results.
What is the time complexity of solving Combination Sum II?
The worst-case time complexity is O(2^N), as all subsets of candidates may need to be explored, though pruning reduces practical computation significantly.
Solution
Solution 1: Sorting + Pruning + Backtracking
We can first sort the array to facilitate pruning and skipping duplicate numbers.
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(i: int, s: int):
if s == 0:
ans.append(t[:])
return
if i >= len(candidates) or s < candidates[i]:
return
for j in range(i, len(candidates)):
if j > i and candidates[j] == candidates[j - 1]:
continue
t.append(candidates[j])
dfs(j + 1, s - candidates[j])
t.pop()
candidates.sort()
ans = []
t = []
dfs(0, target)
return ansSolution 2: Sorting + Pruning + Backtracking(Another Form)
We can also change the implementation logic of the function $dfs(i, s)$ to another form. If we choose the current number, we add the current number to the search path $t$, then recursively call the function $dfs(i + 1, s - candidates[i])$, and after the recursion ends, we remove the current number from the search path $t$. If we do not choose the current number, we can skip all numbers that are the same as the current number, then recursively call the function $dfs(j, s)$, where $j$ is the index of the first number that is different from the current number.
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(i: int, s: int):
if s == 0:
ans.append(t[:])
return
if i >= len(candidates) or s < candidates[i]:
return
for j in range(i, len(candidates)):
if j > i and candidates[j] == candidates[j - 1]:
continue
t.append(candidates[j])
dfs(j + 1, s - candidates[j])
t.pop()
candidates.sort()
ans = []
t = []
dfs(0, target)
return ansContinue Practicing
Continue Topic
array
Practice more edge cases under the same topic.
arrow_forwardauto_awesomeContinue Pattern
Backtracking search with pruning
Expand the same solving frame across more problems.
arrow_forwardsignal_cellular_altSame Difficulty Track
Medium
Stay on this level to stabilize interview delivery.
arrow_forward