1.<tag-回溯和组合及其剪枝>lt.77.组合 +剪枝

回溯模板

让一让了啊, 回溯模板又来了;

// 路径path, 是回溯递归树中每一条从根节点到叶子结点的路径
//选择列表, 是回溯需要的一个基础数组/列表
//1. 递归函数
public void backTracking(路径, 选择列表){
    //2. 递归出口
    //当我们走完递归树中的一条路径时, 就可以向上返回一层递归, 
    if(递归结束条件: path.size() == 基础数组长度){
        回溯结果result.add(一条结果集 path);
        return;
    }
    
    //3. 单层递归逻辑
    for(选择 in 选择列表){
        做选择, 把节点添加到path: path.add(节点);
        
        backTracking(路径, 选择列表);
        
        撤销选择, 移除当前层的节点, 返回到上一层: path.remove(path.size() - 1);
    }
}

lt.77.组合

摘自: 代码随想录, 卡子哥讲的还是相当不错的!

[思路分析]

img

利用递归三部曲来解决回溯问题

img

[未优化的代码一]

class Solution {
    List<List<Integer>> lists = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    
    public List<List<Integer>> combine(int n, int k) {
        //n是取值的范围, 即树的宽度
        //k是子结果的个数, 即树的深度
        backTracking(n, k, 1);
        return lists;
    }

    //1. 递归函数: 
    //参数:  //n是取值的范围, 即树的宽度
        //k是子结果的个数, 即树的深度
        //可以看到, startIndex是去重的关键
    public void backTracking(int n, int k, int startIndex){
        //2. 递归出口: 当一条子路径遍历完了, 就可以满足出口
        if(k == path.size()){
            lists.add(new ArrayList<>(path));
            return;
        }

        //3. 单层递归逻辑
        for(int i = startIndex; i <= n; i++){
            path.add(i);
            backTracking(n, k, i + 1);
            path.remove(path.size() - 1);
        }
    }
}

img

[回溯的剪枝]

img

[剪枝优化的代码二]

class Solution {
    List<List<Integer>> lists = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    
    public List<List<Integer>> combine(int n, int k) {
        //n是取值的范围, 即树的宽度
        //k是子结果的个数, 即树的深度
        backTracking(n, k, 1);
        return lists;
    }

    //1. 递归函数: 
    //参数:  //n是取值的范围, 即树的宽度
        //k是子结果的个数, 即树的深度
        //可以看到, startIndex是去重的关键
    public void backTracking(int n, int k, int startIndex){
        //2. 递归出口: 当一条子路径遍历完了, 就可以满足出口
        if(k == path.size()){
            lists.add(new ArrayList<>(path));
            return;
        }

        //3. 单层递归逻辑
        for(int i = startIndex; i <= n - (k - path.size()) + 1; i++){
            path.add(i);
            backTracking(n, k, i + 1);
            path.remove(path.size() - 1);
        }
    }
}

img

posted @   青松城  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示