Skip to content

Latest commit

 

History

History
78 lines (62 loc) · 2.58 KB

216-CombinationSumIII.md

File metadata and controls

78 lines (62 loc) · 2.58 KB

组合总和 III

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

只使用数字 1 到 9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。

示例 3:

输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

提示:

  • 2 <= k <= 9
  • 1 <= n <= 60

思路:

  1. 回溯函数:定义一个深度优先搜索(DFS)函数 dfs,它尝试在当前位置添加一个数字,并递归地尝试添加下一个数字。
  2. 剪枝:在 dfs 函数中,通过剪枝来减少不必要的搜索。如果当前组合的长度加上剩余数字的数量不足以达到 k,则没有必要继续搜索。同样,如果组合长度已经超过 k,也直接返回。
  3. 检查和:当组合长度达到 k 且组合的和等于 n 时,将当前组合添加到结果数组 res 中。
  4. 递归搜索:在 dfs 函数中,先尝试添加当前数字,然后递归地调用 dfs 函数尝试添加下一个数字。之后,回溯(即删除当前数字),尝试不添加当前数字的情况。
  5. 初始化和调用:初始化一个空数组 temp 来存储当前组合,一个空数组 res 来存储所有有效组合。然后调用 dfs 函数开始搜索。

时间复杂度:最坏情况下是 O(2^9),因为对于每个数字,你可以选择包含或不包含它,总共有 9 个数字。然而,由于剪枝的存在,实际的时间复杂度会小于这个上界。

空间复杂度:O(k),这是因为在最坏的情况下,递归栈的深度可以达到 k,同时 temp 数组最多包含 k 个元素。

var combinationSum3 = function (k, n) {
  const temp = [];
  const res = [];
  const dfs = (cur, n, k, sum, res) => {
    if (temp.length + (n - cur + 1) < k || temp.length > k) {
      return;
    }
    if (temp.length === k && temp.reduce((previous, value) => previous + value, 0) === sum) {
      res.push(temp.slice());
      return;
    }
    temp.push(cur);
    dfs(cur + 1, n, k, sum, res);
    temp.pop();
    dfs(cur + 1, n, k, sum, res);
  };

  dfs(1, 9, k, n, res);
  return res;
};