携手创作,共同成长!这是我参与「掘金日新计划 · 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 <= 91 <= 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
}