一、组合总和3
/**
* @param {number} k
* @param {number} n
* @return {number[][]}
*/
var combinationSum3 = function(k, n) {
let result = []
let path = []
function backtracking(startIndex, sum = 0) {
// 剪枝,如果sum大于n,没必要向下走了
// if(sum > n) {
// return
// }
if(path.length === k) {
if(sum === n) {
result.push([...path])
}
return
}
// for(let i = startIndex; i <= 9 - (k - path.length) + 1;i++) { 剪枝,剩下的不够k个数,可以不用遍历了
for(let i = startIndex; i <=9;i++) {
path.push(i)
backtracking(i + 1, sum + i)
path.pop()
}
}
backtracking(1)
return result
};
二、电话号码的字母组合
数字和字母要有个映射,根据数字决定遍历深度,每个数字映射的字母列表决定遍历宽度,每个字母列表都是不用的集合,跟之前的组合问题不同,所以不需要startIndex来防止重复
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
let map = {
2: 'abc',
3: 'def',
4: 'ghi',
5: 'jkl',
6: 'mno',
7: 'pqrs',
8: 'tuv',
9: 'wxyz',
}
let result = []
function backtracking(index, s = '') {
if(index === digits.length) {
s && result.push(s)
return
}
let letters = map[digits[index]]
if(!letters) {
return
}
for(let i = 0; i < letters.length; i++) {
backtracking(index + 1, s + letters[i])
}
}
backtracking(0)
return result
};