Combination Sum III

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

Combination Sum III is a medium recursion & backtracking problem solved with the pick / not-pick pattern. The best approach, optimal (backtracking with pruning), runs in O(C(9, k) · k) time and O(k) space. Below are 2 approaches in Java, from all k-combinations, then filter up.

Problem

Notehomework

Find all combinations of k distinct digits from 1 to 9 that add up to n. Each combination is listed once, in any order.

Examples

Example 1

Input
k = 3, n = 9
Output
[[1,2,6],[1,3,5],[2,3,4]]

Example 2

Input
k = 4, n = 1
Output
[]

Constraints

  • 2 <= k <= 9, 1 <= n <= 60
  • Only digits 1 to 9, each used at most once.

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
All k-combinations, then filterO(2⁹ · 9)O(k)
Optimal (backtracking with pruning)O(C(9, k) · k)O(k)

1All k-combinations, then filter

TimeO(2⁹ · 9)
SpaceO(k)

Generate every k-subset of 1..9 and keep those summing to n.

  1. Loop over 9-bit masks with k bits set; check the sum.
Java
class Solution {
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> out = new ArrayList<>();
        for (int mask = 0; mask < (1 << 9); mask++) {
            if (Integer.bitCount(mask) != k) continue;
            List<Integer> cur = new ArrayList<>();
            int sum = 0;
            for (int d = 1; d <= 9; d++) if ((mask >> (d - 1) & 1) == 1) { cur.add(d); sum += d; }
            if (sum == n) out.add(cur);
        }
        return out;
    }
}

2Optimal (backtracking with pruning)

TimeO(C(9, k) · k)
SpaceO(k)

Pick digits in increasing order starting from start. Stop when the path has k digits (record it if the remainder is 0), and break the loop as soon as a digit exceeds the remaining sum.

  1. If path.size() == k: record when remaining == 0; return.
  2. for d from start to 9: if d > remaining, break; add, recurse(d + 1, remaining - d), remove.
Java
class Solution {
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> out = new ArrayList<>();
        go(1, k, n, new ArrayList<>(), out);
        return out;
    }

    private void go(int start, int k, int remaining, List<Integer> path, List<List<Integer>> out) {
        if (path.size() == k) {
            if (remaining == 0) out.add(new ArrayList<>(path));
            return;
        }
        for (int d = start; d <= 9; d++) {
            if (d > remaining) break;
            path.add(d);
            go(d + 1, k, remaining - d, path, out);
            path.remove(path.size() - 1);
        }
    }
}

Edge cases to test

  • n too small or too large for k digits

Hints

Hint 1

It is Combinations (choose k from 1..9) with a sum constraint. Prune when the next digit already exceeds the remaining sum.

FAQ

What is the best time complexity for Combination Sum III?

Optimal (backtracking with pruning) runs in O(C(9, k) · k) time and O(k) extra space.

Which pattern does Combination Sum III 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 III?

Yes. All k-combinations, then filter takes O(2⁹ · 9) time and O(k) space. Generate every k-subset of 1..9 and keep those summing to n.

Which edge cases should I test for Combination Sum III?

n too small or too large for k digits.