backtrack——回溯算法总结

这几天着重在刷LeetCode有关回溯搜索算法的题,之前也写了一些博客,感觉当时清楚,但是原理上还是有点模糊。之前根据别人的模板,依葫芦画瓢,解决了一些问题,但是有的时候条件变了,就有点理不清楚了,特别是哪里该加一些限制条件,很懵逼。所以总结了一下。

1. 到底什么是回溯?

回溯算法,都知道是基于递归的算法。那为什么要用递归呢,可以用传统的写法代替嘛?之所以用递归,就是因为如果用传统的方式,很难写或者根本写不出来。举个例子,比如我们想知道用集合nums = [1, 2, 3]中的三个数字(可重复)一共能构成多少个不同的三位数,学过排列组合的都知道一共有27(3的3次方)种:(1,1,1), (1,1,2), (1,1,3), (2,1,1), (2,1,2), (2,1,3)…(3,3,3) 。用最传统的方式,都会写,用一个三层的for循环来写:

vector<vector<int>> res;
vector<int> path;
for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {for (int k = 0; k < 3; k++) {path.push_back({ nums[i], nums[j], nums[k] });res.push_back(path);}}
}

这个例子中,集合中的元素还很少。那么如果集合中有100个元素呢?传统方式是不是要写100层循环?1000呢?因此,这种情况下单靠循环是完成不了的。这种情况下,就需要递归出场了。上面的代码可以写为如下递归的形式:

vector<vector<int>> res;
vector<int> path;
void backtrack_0(vector<int>& nums,  vector<vector<int>> &res) {if (path.size() == nums.size()) {res.push_back(path);return;}// elsefor (int i = 0; i < nums.size(); i++) {path.push_back(nums[i);backtrack_0(nums, res);path.pop_back();}
}

上面的代码中,path的长度其实就是循环的深度,回溯递归里的每一层其实都是一个循环;而else部分,则相当于每层循环的方式(每层for循环该怎么写)。递归其实就模拟了上诉过程。

如果题目变成了三个数字加起来能构成不同的和的情况有多少(就是前面用过的数,后面不能再用。比如:112和211的和就是一样的)?那么该怎么改呢?
传统的写法:

for (int i = 0; i < 3; i++) {for (int j = i; j < 3; j++) {for (int k = j; k < 3; k++) {path.push_back({ nums[i], nums[j], nums[k] });res.push_back(path);}}
}

对应的递归写法:

vector<vector<int>> res;
vector<int> path;
void backtrack_1(vector<int>& nums,  vector<vector<int>> &res, int idx) {if (path.size() == nums.size()) {res.push_back(path);return;}// elsefor (int i = idx; i < nums.size(); i++) {path.push_back(nums[i);backtrack_1(nums, res, i);path.pop_back();}
}

最后的输出都一样:[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], , [3, 3, 3]。
同时,从这里可以看到:循环的起始范围变了:从0变成了上层循环的循环变量;而在回溯函数中,循环的起始值也从0变为了idx。说明,回溯跟多层循环有着非常密切的关系!终止条件跟循环层数有关系,递归函数里面的循环跟每层循环又有着非常紧密的联系!

backtrack-回溯搜索算法总结相关推荐

  1. c语言全排列算法_一文学会回溯搜索算法解题技巧

    点击上方蓝字设为星标 下面开始今天的学习- 本文向大家介绍了回溯算法的基础知识,以帮助大家更好地理解回溯算法. 回溯搜索算法简介 维基百科中关于回溯算法的介绍是: 回溯算法(backtracking) ...

  2. backtrack回溯算法

    转自台湾师范大学acm课程 Enumerate all n-tuples 列舉重複排列.這裡示範:列舉出「數字 1 到 10 選擇五次」全部可能的情形. 製作一個陣列,用來存放一組可能的排列(數據). ...

  3. 自适应学习率算法.基于阿米霍步长准则的线性回溯搜索算法

    解决在梯度下降等算法中,学习率步长的问题. 二分精确搜索法把梯度转化为和学习率的函数,问题转化为找学习率的问题, 然后寻找梯度最低的时候的学习率是多少,在此过程中用了二分法查找学习率.是一种精确搜索方 ...

  4. 算法设计与分析 实验三 回溯法求解地图填色问题

    回溯法求解地图填色问题 一.实验目的与要求 1.实验基本要求: 2.实验亮点: 二.实验内容与方法 三.实验步骤与过程 1.未优化的回溯: (1)算法描述: (2)编程实现 (3)运行并测试: 2.对 ...

  5. python回溯算法

    回溯算法:一种优先搜索算法(试探法):按优条件向前搜索,以达目标:当试探到某步,发现原来选择并不好(走不通),就退回重新选择. 回溯算法的一般步骤:1:定义问题的解空间(搜索中动态生成):2:确定易搜 ...

  6. 数据结构与算法(一)回溯

    数据结构与算法(一)回溯(backtrack) 回溯算法是对树形或者图形结构执行一次深度优先遍历,实际上类似枚举的搜索尝试过程,在遍历的过程中寻找问题的解. 深度优先遍历有个特点:当发现已不满足求解条 ...

  7. [Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]

    [问题描述][中等] [解答思路] 1. 回溯搜索算法 + 剪枝 ,直接来到叶子结点 时间复杂度:O(N^2) 空间复杂度:O(N) import java.util.Arrays;public cl ...

  8. Kali与 BackTrack的区别

    (一)BackTrack BackTrack是基于Ubuntu的自启动运行光盘,它包含了一套安全及计算机取证工具.它其实是依靠融合Auditor Security Linux和WHAX(先前的Whop ...

  9. Kali Linux 与 BackTrack Linux

    (一)BackTrack BackTrack是基于Ubuntu的自启动运行光盘,它包含了一套安全及计算机取证工具.它其实是依靠融合Auditor Security Linux和WHAX(先前的Whop ...

  10. 4.6 Heuristics for Backtracking Algorithms回溯算法的启发式

    当使用回溯搜索解决CSP时,必须对要分支或实例化的变量以及要给该变量的值做出一系列决策.这些决策称为变量和值排序.已有研究表明,对于许多问题,变量的选择和值的排序对于有效解决问题是至关重要的(如[5, ...

最新文章

  1. Java开发中Websocket的技术选型参考
  2. Linux驱动设计之信号量
  3. Linux关于文件的权限笔记
  4. python中赋值运算符有哪些_Python代码中有哪些赋值运算符呢?
  5. 必须Mark下,2019 年度中国质量协会质量技术优秀奖
  6. Windows下配置Squid反向代理服务器
  7. ios调用系统的短信和发送邮件功能,实现短信分享邮件分享
  8. Intel-VT 与虚拟化限制
  9. python爬虫学习(1)爬取微软必应翻译(中英互译)
  10. SQL注入攻击及防御详解
  11. Android中TextView中文字体粗体的设置方法
  12. python正则表达式代码_python正则表达式实例代码
  13. 计算机的内存储器应用范围,计算机的内存储器可与cpu什么交换信息
  14. JeecgBoot全套开发环境搭建
  15. python海龟画笔速度_【判断题】Python海龟绘图中,设置画笔绘制速度的函数是speed()。...
  16. 在ASP.NET Core中如何将各种文档合并为PDF?Aspose快速搞定!
  17. NDK开发QQ语音变声
  18. Macbook Pro 鼠标卡顿问题
  19. UML常用的基本图形简介
  20. 【Lilishop商城】No4-1.业务逻辑的代码开发,涉及到:会员B端第三方登录使用及后端接口(微信、QQ等)

热门文章

  1. oracle面试上机题,Oracle面试题附带答案
  2. 南广学院计算机清考,请问下中国传媒大学南广学院补考和重修要收费吗
  3. 服务器提供各种服务 包括文件服务器,服务器提供各种服务,包括文件服务器、邮件服务器、Web服务器等。...
  4. java 清空文件夹_java 删除文件夹中的所有文件及文件夹
  5. python接收前端post数据_python实现通过flask和前端进行数据收发
  6. Linux系统如何安装网易云音乐
  7. 【长期更新】Linux学习笔记
  8. dda算法_C和C ++中的DDA线图绘制算法
  9. ezcad旋转轴标刻参数_激光打标机软件ezcad中菜单下的多文档标刻功能介绍及其操作设置...
  10. 关于java实习报告周记_2019年度热门关于java实习报告周记优秀七篇