Combination Sum

medium

You're given an array of distinct positive integers candidates and a target integer target. Return every unique combination of numbers from candidates that adds up to exactly target.

You may reuse the same number as many times as you like. A combination is defined by how many of each number it contains — so [2,2,3] and [2,3] are different answers, while [2,2,3] and [3,2,2] count as the same combination. You may return the combinations and the numbers within them in any order.

Every test is chosen so that fewer than 150 distinct combinations exist for the given input.

Hints

You can use each number as many times as you like - so this isn't about choosing a subset, it's about how many of each number you take.
Fix an order: only ever extend a combination with a number at or after the one you just used. That single rule makes duplicate reorderings impossible.
Sort the candidates first. Then inside the loop, the moment a candidate is larger than what's left to reach, you can stop entirely - every later candidate is even bigger.

Common doubts

Because a number may be reused any number of times. Staying at the same index lets you pick it again; only moving forward (never backward) is what stops duplicate combinations.
Carry a start index and only add candidates at index >= start. Every combination then gets built in exactly one canonical (non-decreasing) order.
No - the start-index method is correct on any order. Sorting is what enables the break-early pruning that makes it fast.

Interview follow-ups

That's Combination Sum II: sort, recurse with i + 1 to move forward, and skip equal siblings at the same depth so duplicate combinations don't appear.
Switch to dynamic programming - an unbounded-knapsack style dp over the target counting ways, in O(N * target) time.

Fun facts

  • This is the unbounded knapsack pattern in disguise - the exact same reuse-allowed recursion powers Coin Change and 'number of ways to make an amount'.
  • The one detail that separates this from Subsets is recursing on i instead of i + 1 - that single change flips 'use each once' into 'use each unlimited times'.

Asked at

AmazonMicrosoftGoogleAdobeBloomberg
Frequently Sometimes Occasionally
Example 1
Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]
2 + 2 + 3 = 7 (2 is reused), and 7 = 7. Those are the only two ways.
Example 2
Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]
Example 3
Input: candidates = [2], target = 1
Output: []
The only number is 2, which already overshoots 1, so nothing sums to the target.
Constraints

- 1 <= candidates.length <= 30 - 2 <= candidates[i] <= 40 - All elements of candidates are distinct. - 1 <= target <= 40 - Fewer than 150 unique combinations exist for any input.

Solve this problem →