前端算法系列-回溯01

23 阅读1分钟

77. 组合

var combine = function(n, k) {
    let res = []
    let path = []
    let fn = (n,k,index) => {
        if(path.length === k){
            res.push([...path])
            return
        }
        for(let i=index;i<=n;i++){
            path.push(i)
            fn(n,k,i+1)
            path.pop()
        }
    }
    fn(n,k,1)
    return res
};

加上剪枝操作

var combine = function(n, k) {
    let res = []
    let path = []
    let fn = (n,k,index) => {
        if(path.length === k){
            res.push([...path])
            return
        }
        for(let i=index;i<=n - (k-path.length) + 1;i++){
            path.push(i)
            fn(n,k,i+1)
            path.pop()
        }
    }
    fn(n,k,1)
    return res
};

216. 组合总和 III

var combinationSum3 = function(k, n) {
    let result = []
    let path = []
    let fn = (k,n,index) => {
        if(path.length === k){
            let num = path.reduce((pre,cur) => pre + cur)
            if(num === n){
                result.push([...path])
            }
            return
        }
        for(let i = index;i<=9;i++){
            path.push(i)
            fn(k,n,i+1)
            path.pop()
        }
    }
    fn(k,n,1)
    return result
};

加上剪枝操作,在for循环开始如果已经超过n了,后面直接剪掉

看了题解之后想道不用每次都reduce求和,可以把总和sum放在形参里,动态计算节省时间

var combinationSum3 = function(k, n) {
    let result = []
    let path = []
    let fn = (k,n,index) => {
        if(path.length === k){
            let num = path.reduce((pre,cur) => pre + cur)
            if(num === n){
                result.push([...path])
            }
            return
        }
        for(let i = index;i<=9;i++){
            // 如果这个时候已经超了,剪掉
            if(path.length > 0 && path.reduce((pre,cur) => pre + cur) >= n){
                return 
            }
            path.push(i)
            fn(k,n,i+1)
            path.pop()
        }
    }
    fn(k,n,1)
    return result
};

17. 电话号码的字母组合

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]]) {
            path.push(v);
            backtracking(n, k, a + 1);
            path.pop();
        }
    }
};