回溯算法模板

leetcode77

在这里插入图片描述
从前n个数中挑两个数

var combine = function(n, k) {

    const combineHepler = (n,k,startIndex)=>{
        for (let i = startIndex; i <= n-(k-path.length)+1; ++i) { //startIndex开始序列
            path.push(i);
            combineHepler(n, k, i + 1);
            path.pop();
    }
    if(path.length ==k){//终止条件
        result.push([...path])
        return
    }
}
 let result =[];//存所有结果的合集
 let path = [];//存1个结果
 combineHepler(n,k,1);
 return result;
};

1.确定终止条件
2.单层回溯逻辑,确定参数

leetcode 216

在这里插入图片描述

var combinationSum3 = function(k, n) {
    var combineHepler=function(k,n,sum,startIndex){
        if(path.length==k){
            if(n===sum) {
                result.push([...path]);
                return;
            }
        }
        for(let i=startIndex;i<=9;i++){
            sum+=i;
            path.push(i);
            combineHepler(k, n, sum, i+1);
            sum-=i;
            path.pop();
        }
    };
    let result=[];
    let path=[];
    combineHepler(k,n,0,1);
    return result;
};

leetcode 17

在这里插入图片描述

var letterCombinations = function(digits) {
     
    const k=digits.length;
    const mapValue=['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
    //两种特殊情况,为0和为1
    if(!k) return []; 
    if(k===1){ 
        return mapValue[digits].split("");
    }

    var letter=function(n,k,a){
            if(k===path.length){
                result.push(path.join("")) 
                return
            }
            for(var v of mapValue[n[a]]){
                path.push(v);
                letter(n,k,a+1)
                path.pop();
            }
        }

    const result=[],path=[];
    letter(digits,k,0)
    return result
};

字符串和映射需要注意

leetcode 39

在这里插入图片描述

var combinationSum = function(candidates, target) {
    const combine = function(candidates,target,sum,startIndex){
        if(sum>target) return;
        if(sum==target){
            res.push([...path])
            return;
        }
        for(let i = startIndex;i<candidates.length;i++){
            sum+=candidates[i]
            path.push(candidates[i])
            combine(candidates,target,sum,i)//因为可以重复,所以这里is i not i+1
            sum-=candidates[i]
            path.pop()
        }
    }
    let path=[],res=[];
    candidates.sort()
    combine(candidates,target,0,0);
    return res;
};

leetcode 40 组合总结II

在这里插入图片描述

/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
 //难点在于去除同一树层下的,用used标记,used=true是同一树枝,used=false是同一树层
var combinationSum2 = function(candidates, target) {
    let res=[],path=[];
    candidates.sort((a, b) => a - b);
    let used = new Array(candidates.length).fill(false);

    const back = function(candidates,target,sum,startindex,used){
    if(sum===target){
        res.push([...path])
    }    
    for(let i=startindex;i<candidates.length&&sum+candidates[i]<=target;i++){//sum+candidates[i]<=target剪枝不然会超出时间限制
        if(i>0 && candidates[i]==candidates[i-1]&&used[i-1]==false){
            continue;
        }
        sum+=candidates[i]
        path.push(candidates[i])
        used[i]=true
        back(candidates,target,sum,i+1,used);
        used[i]=false
        path.pop()
        sum-=candidates[i];
    }
}
    back(candidates,target,0,0,used)
    return res;
};

还是基于原来的模板,不同的是这里的解集不能包括同样的组合,比如[1,2,5]和[5,1,2]就是一样的,因此就要去除同一树层的数,而保留同一树枝的
在这里插入图片描述注意点:
1.candidates排序,因为是在candidates[i]==candidates[i-1]如果相同的情况下展开
升序candidates.sort((a, b) => a - b);
降序candidates.sort((a, b) =>b - a);

2.used数组初始化,并注意fill(false)
let used = new Array(candidates.length).fill(false);

3.剪枝操作
sum+candidates[i]<=target
必不可少,不然会超时

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值