Skip to content

216. Combination Sum III Medium ​

Find all valid combinations of k numbers that sum up to n such that the following conditions are true:

  • Only numbers 1 through 9 are used.
  • Each number is used at most once.

Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.

Example 1:
Input: k = 3, n = 7
Output: [[1,2,4]]
Explanation:
1 + 2 + 4 = 7
There are no other valid combinations.

Example 2:
Input: k = 3, n = 9
Output: [[1,2,6], [1,3,5], [2,3,4]]
Explanation:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
There are no other valid combinations.

Example 3:
Input: k = 4, n = 1
Output: []
Explanation: There are no valid combinations.
Using 4 different numbers in the range [1,9], the smallest sum we can get is 1+2+3+4 = 10 and since 10 > 1, there are no valid combinations.

Approach ​

Input: Two integers k and n, requiring us to pick k distinct numbers between 1 and 9 that sum to n.

Output: Return all possible combinations (order doesn't matter, but numbers cannot be reused).

This problem belongs to Combination Backtracking problems.

  • We start from 9 (because available numbers are 1~9 and can't be repeated) and try adding numbers to our path.
  • Every time a number j is picked, place it in path, and update the current sum t.
  • Continue recursively picking numbers j-1 and below.
  • If the current path length equals k and the sum equals n, we found a valid combination, and we append it to ans.
  • If the current sum goes over n, or the remaining pool of usable numbers is insufficient to achieve the sum, we prune the search branch straight away.

Three Questions of Backtracking ​

  1. Current Operation?

    • At current index i (representing the maximum available number), attempt to choose current number j (j ∈ [i, 1]) and add into traversal path.
    • Meaning placing number j inside the array tracking choices made, indicating "I picked it".
  2. Sub-problem?

    • After choosing j, continue to pick among the available downstream values (j-1 to 1) to fill the rest of the combinations.
    • Concurrently maintain the sum value tracking t, looping recursively until exactly k numbers are collected.
  3. Next Sub-problem?

    • The next recursive drill runs dfs(j-1, t+j), indicating we look sequentially at components starting from j-1 and keeping record of our aggregated sum.

Pruning Conditions ​

  • If current sum t is strictly larger than our target sum n, we can aggressively branch off and return back immediately.
  • If the remaining pool of items just isn't mathematically fit enough to satisfy the remainder formula (i.e. (i - d + 1 + i) * d // 2 < n - t), prune returning.

Implementation ​

python
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        ans = []       # Store final results
        path = []      # The current combination traversal path

        # Backtracking worker
        def dfs(i, t):
            # Pruning 1: If current accumulated payload exceeds expected sum n, prune immediately
            if t > n:
                return

            # Pruning 2: If selecting all remaining maximal allowed digits is less than what is needed to reach target n
            # Calculation logic corresponds to summing an arithmetic progression
            d = k - len(path)
            min_sum = (i - d + 1 + i) * d // 2  # The sum of numbers ranging from i-(d-1) to i
            if min_sum < n - t:
                return

            # Condition met: Handpicked exact target quantity summing neatly exactly
            if len(path) == k and t == n:
                ans.append(path.copy())
                return

            # Process candidates branching down from large digits to smallest recursively
            for j in range(i, 0, -1):
                path.append(j)            # Pick candidate `j`
                dfs(j - 1, t + j)        # Branch down selecting components with limits adjusted beneath candidate
                path.pop()               # Take pick out of consideration recursively

        dfs(9, 0)  # Recurse starting from upper bounds `9`
        return ans
javascript
/**
 * @param {number} k
 * @param {number} n
 * @return {number[][]}
 */
const combinationSum3 = function(k, n) {
    const ans = [];
    const path = [];

    function dfs(i, t) {
        if (t > n) return;

        const d = k - path.length;
        if ((i - d + 1 + i) * d / 2 < n - t) return;

        if (path.length == k && t == n) {
            ans.push([...path]);
            return;
        }

        for (let j = i; j > 0; j --) {
            path.push(j);
            dfs(j - 1, t + j);
            path.pop()
        }
    }
    dfs(9, 0);
    return ans;
};

Complexity Analysis ​

  • Time Complexity: O(k * 9^k) (Actually O(C(9,k) * k) which is very small)
  • Space Complexity: O(k)

216. Combination Sum III (English)

216. 组合总和 III (Chinese)