Combination Sum (repeating elements)

Medium Recursion & Backtracking Pick / Not-Pick Original on LeetCode

Combination Sum (repeating elements) is a medium recursion & backtracking problem solved with the pick / not-pick pattern. The best approach, optimal (sorted loop with early break), runs in O(2^(t/m)) time and O(t/m) space. Below are 2 approaches in Java, from pick / not-pick with reuse up.

Problem

Given distinct positive integers candidates and a target, return all unique combinations that sum to target. The same number can be used any number of times, and two combinations are the same if they use the same numbers the same number of times.

Examples

Example 1

Input
candidates = [2, 3, 5], target = 8
Output
[[2,2,2,2],[2,3,3],[3,5]]

Example 2

Input
candidates = [4], target = 3
Output
[]

Constraints

  • 1 <= candidates.length <= 30, distinct values from 2 to 40
  • 1 <= target <= 40
  • Each candidate can be used any number of times.

Animated walkthrough

A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.

Concepts first, then the problem and every approach, step by step.

Space to play or pause · ← → to jump a step · click or drag the bar to seek

Solutions

Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.

ApproachTimeSpace
Pick / not-pick with reuseO(2^(t/m))O(t/m)
Optimal (sorted loop with early break)O(2^(t/m))O(t/m)

1Pick / not-pick with reuse

TimeO(2^(t/m))t = target, m = smallest candidate: the deepest path has t/m picks.
SpaceO(t/m)

At index i either use candidates[i] again (stay at i) or move on to i + 1.

  1. If target == 0, record. If i == n or target < 0, return.
  2. Pick: add, recurse(i, target - c), remove. Skip: recurse(i + 1, target).
Java
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> out = new ArrayList<>();
        go(candidates, 0, target, new ArrayList<>(), out);
        return out;
    }

    private void go(int[] c, int i, int target, List<Integer> path, List<List<Integer>> out) {
        if (target == 0) { out.add(new ArrayList<>(path)); return; }
        if (i == c.length || target < 0) return;
        path.add(c[i]);
        go(c, i, target - c[i], path, out);
        path.remove(path.size() - 1);
        go(c, i + 1, target, path, out);
    }
}

2Optimal (sorted loop with early break)

TimeO(2^(t/m))
SpaceO(t/m)

Sort the candidates. At each level loop from start. Once a candidate is bigger than the remaining target, every later one is too, so break. Recursing with the same index lets a number repeat.

  1. Sort candidates.
  2. for i from start: if c[i] > target, break.
  3. Add c[i], recurse(i, target - c[i]), remove.
Java
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> out = new ArrayList<>();
        go(candidates, 0, target, new ArrayList<>(), out);
        return out;
    }

    private void go(int[] c, int start, int target, List<Integer> path, List<List<Integer>> out) {
        if (target == 0) { out.add(new ArrayList<>(path)); return; }
        for (int i = start; i < c.length; i++) {
            if (c[i] > target) break;
            path.add(c[i]);
            go(c, i, target - c[i], path, out);
            path.remove(path.size() - 1);
        }
    }
}

Edge cases to test

  • No combination possible
  • A single candidate repeated many times

Hints

Hint 1

After picking candidates[i], recurse from i again (not i + 1) so it can be reused, but never go back to earlier indices.

FAQ

What is the best time complexity for Combination Sum (repeating elements)?

Optimal (sorted loop with early break) runs in O(2^(t/m)) time and O(t/m) extra space.

Which pattern does Combination Sum (repeating elements) use?

It is a recursion & backtracking problem that uses the pick / not-pick pattern. Other problems with the same pattern: Generate all binary strings without consecutive 1's, Subsets (2 choices per element), Subsets II.

Is there a brute force solution for Combination Sum (repeating elements)?

Yes. Pick / not-pick with reuse takes O(2^(t/m)) time and O(t/m) space. At index i either use candidates[i] again (stay at i) or move on to i + 1.

Which edge cases should I test for Combination Sum (repeating elements)?

No combination possible; A single candidate repeated many times.