持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情🚀🚀
216. 组合总和 III - 力扣(LeetCode)
回溯
var combinationSum3 = function(k, n) {
let res = [];
let path = [];
let sum = 0;
const dfs = (path,index) =>{
// 剪枝操作
if(sum > n){
return
}
if(path.length == k){
if(sum == n){
res.push([...path]);
return
}
}
for(let i = index; i <= 9 - (k-path.length) + 1;i++){
path.push(i);
sum = sum + i;
index += 1;
dfs(path,index);
sum -= i
path.pop()
}
}
dfs(path,1);
return res
};
这道题和上一道组合总和很像,唯一不一样的就是回溯的依赖值多了一项
sum,以及剪枝的优化
注意
- 回溯:1.
sum -= i; 2.path.pop()
容易把第一种情况遗忘
-
剪枝:
- 当前sum值大于n值,后面就不需要遍历了
- 如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。
17. 电话号码的字母组合 - 力扣(LeetCode)
回溯
var letterCombinations = function(digits) {
const k = digits.length;
const map = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"];
if(!k) return [];
if(k === 1) return map[digits].split("");
const res = [], path = [];
backtracking(digits, k, 0);
return res;
function backtracking(n, k, a) {
if(path.length === k) {
res.push(path.join(""));
return;
}
for(const v of map[n[a]]) {
console.log(map[n[0]])
console.log(v)
path.push(v);
backtracking(n, k, a + 1);
path.pop();
}
}
};
注意
- 这里用了
map做了映射,这里还不是很熟,需要多加记忆多加练习~ for of遍历字符串,可以将每个字符单独遍历出来。
const message = 'hello';
for (const character of message) {
console.log(character);
}
// 'h'
// 'e'
// 'l'
// 'l'
// 'o'
3.最后将当前path数组加入到res结果数组,需要转换成数组,不能使用[...path]
收获
今天的题难度适中,感觉这类题的套路也出来了,就是用一种特殊的方式处理暴力搜索。