当前位置: 首页 > news >正文

回溯算法!!

只要有递归就会有回溯,回溯隐藏在递归函数的下面

回溯算法是回溯搜索算法,是纯暴力的搜索算法

一般用于解决以下问题

  • 组合问题:N个数里面按一定规则找出k个数的集合,组合是不强调元素顺序的,排列是强调元素顺序
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

 一般的回溯问题是将问题抽象成一个n叉树进行递归,所以需要递归三部曲,集合的大小就构成了树的宽度,递归的深度就构成了树的深度

  • 确定参数列表返回类型
  • 确定终止条件
  • 确定单层逻辑
  • 模板
    void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
    }

组合问题;是无序,不重复的

1.给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。你可以按 任何顺序 返回答案。

如果n=4,k=2。那么可以用简单的两层for循环来解决,可是当n=100,k=50的时候就需要用50层for循环来解决,非常的繁琐

for(int i=1;i<n;i++){for(int j=i+1;j<n;j++){return [i,j];}
}

然后,我们将上述问题抽象成一个树形结构,看出for循环用来横向遍历,递归的过程是纵向遍历。

回溯三部曲

  • 确定递归函数参数和返回值:void backpacking(n,k,startindex),然后确定一维数组path,即n叉树中的路径(1,2)、(1,3).....和二维数组result记录所有的path结果,其中参数n,k,startindex,其中startindex是记录开始索引,即每一次从哪一个数开始组合
    void backpacking(n,k,startindex)
  • 确定终止条件:即每一次递归的结束条件就是到达叶子节点,也就是path.size = k,k就是n叉树的深度
    if(path.size == k)result.add(path);
  • 确定单层搜索逻辑:每一次的中间节点就是一次for循环,即从startindex开始遍历到n,比如这是startindex = 1,n=4,将1压入,进入回溯
    for (int i = startIndex; i <= n; i++) { // 控制树的横向遍历path.push_back(i); // 处理节点backtracking(n, k, i + 1); // 递归:控制树的纵向遍历,注意下一层搜索要从i+1开始path.pop_back(); // 回溯,撤销处理的节点
    }
class Solution {List<Integer> path = new ArrayList<>();List<List<Integer>> result = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {backpacking(n,k,1);return result;}void backpacking(int n,int k,int startindex){if(path.size() == k){result.add(new ArrayList<>(path));return;}for(int i = startindex;i<=n;i++){path.add(i);backpacking(n,k,i+1);path.removeLast();}}
}

完整代码如下:其中第一遍的过程是:

1.startindex=1,path.size = 0,进入for循环,i=1,path={1} ,然后进入递归si+1=2,path.size=1,进入for循环,i=2,2入队,path={1,2},进入递归si+1=3,达到终止条件,返回(1,2),这时将2移除path,path={1},i=3,3入队,path={1,3},进入递归si=4,达到结束条件,将(1,3)返回,将3移除,i=4,4入队,path={1,4},进入递归,达到终止条件,返回(1,4),这是退出i=1进行遍历的for循环.。。

2.进入i=2的for循环,即从2开始遍历组合的for循环。。。。

startIndex = 1
└── i = 1 → path = [1]└── i = 2 → path = [1,2] ✅ → result += [1,2]└── i = 3 → path = [1,3] ✅ → result += [1,3]└── i = 4 → path = [1,4] ✅ → result += [1,4]
└── i = 2 → path = [2]└── i = 3 → path = [2,3] ✅ → result += [2,3]└── i = 4 → path = [2,4] ✅ → result += [2,4]
└── i = 3 → path = [3]└── i = 4 → path = [3,4] ✅ → result += [3,4]
└── i = 4 → path = [4]└── i = 5 > n → 不执行

相关文章:

  • Fashion-MNIST LeNet训练
  • 个人用户进行LLMs本地部署前如何自查和筛选
  • PHY6222 基本文件操作
  • 2023ICPC杭州题解
  • 设计模式——组合设计模式(结构型)
  • Spring如何实现组件扫描与@Component注解原理
  • 【Hexo】4.Hexo 博客文章进行加密
  • ArcGIS Pro 创建渔网格网过大,只有几个格网的解决方案
  • 智能制造之精读——RPA制造行业常见场景【附全文阅读】
  • STM32F407寄存器操作(ADC非连续扫描模式)
  • python打卡day42@浙大疏锦行
  • Adobe LiveCycle ES、LiveCycle DS 与 BlazeDS 关系解析与比较
  • java ExecutorService线程池使用(ExecutorService/Completable异步+ExecutorService线程池)
  • MATLAB实战:人脸检测与识别实现方案
  • vue3动态路由的实现以及目录权限的设置
  • 湖北理元理律师事务所:个人债务管理的温度与精度
  • C++输入与输出技术详解
  • LeetCode 热题 100 208. 实现 Trie (前缀树)
  • 机器学习算法-逻辑回归
  • 【计算机系统结构】习题2
  • 安徽 两学一做 网站/手游免费0加盟代理
  • 外网有哪些有趣的网站/优化落实疫情防控
  • 网站开发都是模板/360站长
  • 广东深圳疫情严重吗/seo网站推广怎么做
  • 网站建设和优化的步骤/不收费的小说网站排名
  • 2022年河北邢台疫情/江北seo综合优化外包