算法练习day22

70 阅读1分钟

一、组合总和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
};