Combination Sum
Master this topic with zero to advance depth.
Combination Sum
The Goal: Finding Target Sum
Given an array of distinct integers candidates and a target integer, find all unique combinations where the chosen numbers sum to target. You may return the combinations in any order.
Key Rule: Unlimited Re-use
The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different.
Decision Tree Branching
At each step, you can either:
- Use the current element: Subtract its value from the target and stay at the same index (because we can re-use it).
- Skip the current element: Move to the next index in the array.
Find all unique combinations in candidates that sum to target (reuse allowed). Includes visual decision tree.
Examples
Level I: Basic Backtracking (Include/Exclude)
Intuition
At every step, we either include the current candidate or move to the next candidate.
We use recursion to explore the decision tree. If target == 0, we found a valid combination. If target < 0 or we've used all candidates, we backtrack.
Detailed Dry Run
Dry Run: target=7, candidates=[2,3]
| Step | idx | target | path | Action |
| :--- | :-- | :----- | :------ | :---------------- |
| 1 | 0 | 7 | [] | Start |
| 2 | 0 | 5 | [2] | Use 2 |
| 3 | 0 | 3 | [2,2] | Use 2 |
| 4 | 0 | 1 | [2,2,2] | Use 2 |
| 5 | 0 | -1 | [2,2,2] | FAIL (Backtrack) |
| 6 | 1 | 1 | [2,2] | Skip 2, Try 3 |
| 7 | 1 | -2 | [2,2,3] | FAIL (Backtrack) |
| 8 | 1 | 7 | [] | Skip all for id=0 |Level II: Optimized Backtracking (Loop-Based + Sorting)
Intuition
Sorting the candidates allows us to break early from the loop once the target is exceeded.
For each call, iterate through candidates from the current index to the end. If target - candidates[i] < 0, stop the loop (pruning).
Detailed Dry Run
target=7, candidates=[2,3,6,7]
- Try 2. Recurse 5. Try 2. Recurse 3. Try 2. Recurse 1. Try 2 (FAIL - 3rd 2 is fine, 4th fails). Break.
- Backtrack to target 3. Try 3. Recurse 0. SUCCESS [2,2,3].
Level III: Iterative DP (Unbounded Knapsack Style)
Intuition
Since we only care about the values and can reuse items, we can use a DP table where dp[i] stores all unique combinations summing to i.
Initialize dp[0] with an empty combination. For each candidate, iterate from candidate to target, adding the candidate to all combinations in dp[i - candidate] and storing them in dp[i].
Detailed Dry Run
target=3, candidates=[1,2]
- dp[0] = [[]], dp[1,2,3] = []
- Use 1: dp[1]=[[1]], dp[2]=[[1,1]], dp[3]=[[1,1,1]]
- Use 2: dp[2]=[[1,1],[2]], dp[3]=[[1,1,1],[1,2]]
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.