回溯算法(组合)

77,组合
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]请添加图片描述

回溯法解决的问题可以抽象为树形结构,因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,构成树的深度。
递归就要有终止条件,所以必然是一棵有限的树(N叉树)。

/**
 * @param {number} n
 * @param {number} k
 * @return {number[][]}
 */
var combine = function(n, k) {
    let result = []; //收集结果集
    let path = []; //存放符合条件的结果
    var clone = function (params) {
        let arr = [];
        for(let i = 0;i<params.length;i++){
            arr.push(params[i]);
        }
        return arr;
    }
    //n相当于树的宽度,k相当于树的深度
    var backtracking = function (n,k,startIndex) {
        if(path.length == k){
            result.push(clone(path));
            return;
        }
        for(let i = startIndex;i <= n-(k-path.length())+1;i++){ //剪枝优化
            path.push(i);
            backtracking(n,k,i+1);
            path.pop();
        }
    };

    backtracking(n,k,1);
    return result;
};

combine(4,2);

剪枝优化:
举一个例子,n = 4,k = 4的话,那么第一层for循环的时候,从元素2开始的遍历都没有意义了。 在第二层for循环,从元素3开始的遍历都没有意义了
请添加图片描述
如果for循环选择的起始位置之后的元素个数已经不足我们需要的元素的个数了,就没要搜索了。
1.已经选择的元素的个数:path.length;
2.所需元素个数为:k-path.length;
3.剩余元素(n-i)>= k-path.length

4.在集合n中至多要从该起始位置开始遍历, i <= n-(k-path.length)+1,,加1 因为包括起始位置;
例如 n =4,k =3,n -(k-0)+1 ,4-3+1=2,从2开始搜索,组合[2,3,4]是合理的;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值