Combination Sum III
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.
| Approach | Time | Space |
|---|---|---|
| All k-combinations, then filter | O(2⁹ · 9) | O(k) |
| Optimal (backtracking with pruning) | O(C(9, k) · k) | O(k) |
1All k-combinations, then filter
O(2⁹ · 9)O(k)Generate every k-subset of 1..9 and keep those summing to n.
- Loop over 9-bit masks with k bits set; check the sum.
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)
O(C(9, k) · k)O(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.
- If path.size() == k: record when remaining == 0; return.
- for d from start to 9: if d > remaining, break; add, recurse(d + 1, remaining - d), remove.
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.