代码随想录刷题|回溯算法理论 LetCode 77.组合

简介: 代码随想录刷题|回溯算法理论 LetCode 77.组合

回溯算法理论

  • 回溯和递归式相辅相成的,只要有递归就会有回溯
  • 一般 递归函数的下面就是 回溯的逻辑
  • 回溯相当于穷举搜索的巧妙实现    

  • 回溯算法常解决的问题:
  • 组合
  • 切割
  • 子集
  • 排列
  • 棋盘
  • 回溯代码的框架
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

77.组合

题目链接:力扣

思路


首先应该先到的就是双层循环,,很难写,因为求的是组合,根据参数的不同,组合也不相同,无法用循环的方式覆盖所有可能,单纯的循环是行不通的


       这道题的本质是对[1,n]中的数字进行 k 个数的穷举,就是要将所有满足条件的收集起来,此时就要想起来使用回溯算法,回溯算法的本质就是穷举


       其实回溯算法就是通过递归控制有多少层for循环,递归里得每一层就是一个for循环


       以求取 [1,2,3,4] 中所有可能出现的 2 个数的组合为例:


186845656cd34401af0889434ce2ce7b.png


    收集结果的集合nums在不断回溯

组合

class Solution {
    List<Integer> nums = new ArrayList<>();
    List<List<Integer>> result = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return result;
    }
    void backtracking(int n,int k, int startIndex) {
        // 终止条件
        if (nums.size() == k) {
            // 记录结果
            result.add(new ArrayList(nums));
            // 返回
            return;
        }
        for (int i = startIndex; i <= n; i++) {
            nums.add(i);
            backtracking(n,k,i+1);
            nums.remove(nums.size()-1);
        }
    }
}

回溯法的本质是穷举,对回溯唯一能做的优化就是剪枝,减去那些根本不需要的遍历,比如说这道题目的n = 4,k = 4


每递归一层,集合中的元素就添加一次,所以集合中有的元素个数就是nums.size(),还需要的元素数目是 k - nums.size()


所以在[1,n]中至多从该起始位置  n - (k - nums.size()) + 1 开始遍历  

class Solution {
    List<Integer> nums = new ArrayList<>();
    List<List<Integer>> result = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return result;
    }
    void backtracking(int n,int k, int startIndex) {
        // 终止条件
        if (nums.size() == k) {
            // 记录结果
            result.add(new ArrayList(nums));
            // 返回
            return;
        }
        for (int i = startIndex; i <= n - (k - nums.size())  + 1; i++) {
            nums.add(i);
            backtracking(n,k,i+1);
            nums.remove(nums.size()-1);
        }
    }
}
相关文章
|
18天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
7天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
18天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
18天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
19天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
19 3
|
17天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
18天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
18天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
18天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
18天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明