216. 组合总和 III
链接
文章链接
题目链接
第一想法
还是套公式,为了防止一个数用多次,所以需要用startIndex来控制,同时需要一个sum来记录总和,代码如下:
function combinationSum3(k: number, n: number): number[][] {
let res:number[][]=[]
const dfs=(arr:number[],startIndex:number,sum:number)=>{
if(arr.length>=k){
if(sum===n) res.push(Array.from(arr))
return
}
for(let i=startIndex;i<=9;i++){
arr.push(i)
sum+=i
dfs(arr,i+1,sum)
arr.pop()
sum-=i
}
}
dfs([],1,0)
return res
};
看完文章后的想法
文章的想法和我的想法是一致的,看完文章后主要来讲讲剪枝的思路,如何剪枝? 存在这么一种情况,arr.length未达到k但是sum已经大于n了,这种情况下就需要剪枝:
代码如下:
function combinationSum3(k: number, n: number): number[][] {
let res:number[][]=[]
const dfs=(arr:number[],startIndex:number,sum:number)=>{
if(sum>n) return
if(arr.length>=k){
if(sum===n) res.push(Array.from(arr))
return
}
for(let i=startIndex;i<=9;i++){
arr.push(i)
sum+=i
dfs(arr,i+1,sum)
arr.pop()
sum-=i
}
}
dfs([],1,0)
return res
};
思考
由于昨天做过组合,所以今天做这道题的时候很容易上手,但是没有想到剪枝操作,目前做了两道题,都是可以写出解题但是优化剪枝想不到.
17. 电话号码的字母组合
链接
文章链接
题目链接
第一想法
首先要想如何数组和字母映射,所以准备了一个数组array用于映射,同是由于ts无法删除字符,所以换了一种回溯,其中蕴含着回溯,代码如下:
function letterCombinations(digits: string): string[] {
let array:string[][]=[['a','b','c'],['d','e','f'],['g','h','i'],['j','k','l'],['m','n','o'],['p','q','r','s'],['t','u','v'],['w','x','y','z']]//映射表
let res:string[]=[]
let len:number=digits.length
const dfs=(str:string,digits: string,index:number)=>{
if(str.length==len){
str&&res.push(str) //防止str为""的情况
return
}
for(let i=0;i<array[Number(digits[index])-2].length;i++){
let s:string=str
s+=array[Number(digits[index])-2][i] //s这里是隐藏回溯的
dfs(s,digits,index+1)
}
}
dfs('',digits,0)
return res
};
看完文章后的想法
文章的想法和我的想法是一致的,不过文章中不是用隐含回溯,而是用的是数组,这样的回溯就比较明显了,同时映射表我用的是二维数组,也可以用一位数组+字符串就可以了,也可以用对象的形式,映射表代码如下:
const strMap: { [index: number]: string[] } = {
2: ['a', 'b', 'c'],
3: ['d', 'e', 'f'],
4: ['g', 'h', 'i'],
5: ['j', 'k', 'l'],
6: ['m', 'n', 'o'],
7: ['p', 'q', 'r', 's'],
8: ['t', 'u', 'v'],
9: ['w', 'x', 'y', 'z']
}
思考
这道题和组合那种题是不一样的,因为数字是可以重复的,所以循环是可以从0开始的,其次,由于在ts&js中是无法直接去字符串的某个字符删除的,所以有两种方法,一种是我那种创建一个s:string进行隐式回溯,另一种就是按照文章中用数组arr,这样可以很明显的看出是有回溯存在的
今日总结
今日耗时2小时,两道题都不算难,但是两道题有所差别,第一道考了如何不重复数字,第二道题是可以重复(有无startIndex),同时由于ts&js无法删减字符,所以考了如何利用字符进行回溯,总体来说不难.