「前端刷题」216.组合总和 III(MEDIUM)

98 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情

题目(Combination Sum III)

链接:https://leetcode-cn.com/problems/combination-sum-iii
解决数:1565
通过率:72.5%
标签:数组 回溯 
相关公司:amazon google bytedance 

找出所有相加之和为 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、终止条件:路径长度为k的同时,满足数字和为n 2、选择列表:因为组合是没有顺序,为了避免重复可以每次只选择比之前路径头部值大的数,并且本题的选择最大范围是1-9

var combinationSum3 = function(k, n) {
    let res = []
    if(k <= 0 || n <= 0) return ret

    // 回溯模板
    // sum记录之前路径的数字总和 start限制之后选择的起点避免重复
    function backtrack(k, n, sum, start, track) {
        // 终止条件
        if (track.length === k) {
            if (sum === n) {
                res.push([...track])
            }
            return
        }

        // 选择列表
        for (let i = start; i <= 9; i++) {
            track.push(i) // 做选择
            backtrack(k, n, sum + i, i + 1, track) // 回溯
            track.pop() // 撤销选择
        }
    }

    backtrack(k, n, 0, 1, [])

    return res
};

思路

const combinationSum3 = (k, n) => {
  const res = []; 
  // 基于当前已选的comb数组(和为sum),在数start到数9中继续选
  const dfs = (start, comb, sum) => { 
    if (comb.length == k) {     // 选够k个数 结束递归
      if (sum == n) {           // 组合中数之和等于n
        res.push(comb.slice()); // 将它的拷贝加入解集
      }
      return;
    }
    for (let i = start; i <= 9; i++) { // 枚举出所有的选择(选项)
      comb.push(i);                    // 作出一个选择i
      dfs(i + 1, comb, sum + i);       // 基于该选择i,往下递归
      comb.pop();                      // 撤销这个选择
    }
  };

  dfs(1, [], 0);  // 入口
  return res;
};
func combinationSum3(k int, n int) [][]int {
	res := [][]int{}

	var dfs func(start int, comb []int, sum int)
	dfs = func(start int, comb []int, sum int) {
		if len(comb) == k {
			if sum == n {
				tmp := make([]int, len(comb))
				copy(tmp, comb)
				res = append(res, tmp)
			}
			return
		}
		for i := start; i <= 9; i++ {
			comb = append(comb, i)
			dfs(i+1, comb, sum+i)
			comb = comb[:len(comb)-1]
		}
	}
	dfs(1, []int{}, 0)
	return res
}