代码随想录第二十四天|回溯基础、组合问题

代码随想录第二十四天|回溯第一天:懵逼

Leetcode 77. 组合

题目链接: 组合
自己的思路:第一天开回溯,感觉和递归很像,因为我都不会!多做多练!!!

正确思路:回溯就是for循环里面套递归,这个题很好理解,但是不好写代码,我们假设n=4,k=2来处理,第一次从n里面挑一个1,然后再把234拿出来,只拿比1大的,然后再从234里面拿,分别拿2、3、4,这样就构成了[1,2]、[1,3]、[1,4],其他的也是同理,说明终止条件就是数组大小满足k的时候就加入进来,for循环里面从1到n,每次的起始点也不同;但是这道题我们还可以做剪枝操作,因为后面有些数组的长度是永远都没法到k的,我们假设现在路径中有了path.size()个元素,那k-path.size()就是我们还需要多少元素,那n-(k-path.size())+1就是我们最大能开始的起始点,这里加1是为了刨去当前元素,从当前元素的后一个元素开始,因为后面的起始点所产生的数组的长度不会等于k,所以剪枝!!!
回溯三部曲:1、终止条件:当path的数组大小满足k的时候,将路径加入到结果当中,然后返回;2、传入参数:n、k和当前元素的起始值;3、单层逻辑:for循环用于指定不同的初始值,先把当前初始值加入进来,然后使用递归函数进行递归,然后再把当前值去除掉(回溯)!!!

代码:

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return res;
    }

    public void backtracking(int n,int k,int startindex){
        if (path.size()==k){
            //满足条件则加入进来
            res.add(new ArrayList(path));
            return;
        }
        //剪枝操作
        //把后面不满足数组长度的都剪掉
        for (int i = startindex;i<=n-(k-path.size())+1;i++){
            path.add(i);
            backtracking(n,k,i+1);
            path.removeLast();
        }
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值