今日任务
目录
总结
回溯总结:代码随想录
回溯是递归的副产品,只要有递归就会有回溯,所以回溯法也经常和二叉树遍历,深度优先搜索混在一起,因为这两种方式都是用了递归。
回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一下。
回溯法的模板:for循环横向遍历,递归纵向遍历,回溯不断调整结果集
void backtracking(参数) { if (终止条件) { 存放结果; return; } for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) { 处理节点; backtracking(路径,选择列表); // 递归 回溯,撤销处理结果 } }
回溯算法能解决如下问题:
- 组合问题:N个数里面按一定规则找出k个数的集合
- 组合:用递归控制for循环嵌套的数量;优化回溯算法只有剪枝一种方法,for循环在寻找起点的时候要有一个范围,如果这个起点到集合终止之间的元素已经不够题目要求的k个元素了,就没有必要搜索了
- 组合总和:已选元素总和如果已经大于n(题中要求的和)了,那么往后遍历就没有意义了,直接剪掉
- 组合总和(可重复元素):需要startIndex来控制for循环的起始位置,如果是一个集合来求组合的话,就需要startIndex;如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex
- 组合总和(元素重复,答复不重复):难在去重,“树枝去重”和“树层去重”
- 多个集合求组合:还是熟悉的模板题目,但是有一些细节
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 排列:每层都是从0开始搜索而不是startIndex,需要used数组记录path里都放了哪些元素了
- 去重排列:神奇的地方就是used[i - 1] == false也可以,used[i - 1] == true也可以;使用(used[i - 1] == false),即树层去重,效率更高;used数组既是记录path里都放了哪些元素,同时也用来去重,一举两得。
- 切割问题:一个字符串按一定规则有几种切割方式
- 切割问题其实类似组合问题
- 如何模拟那些切割线
- 切割问题中递归如何终止
- 在递归循环中如何截取子串
- 如何判断回文
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 子集:在树形结构中,要收集所有节点的结果
- 去重子集:去重套路
- 递增子序列:使用set针对同一父节点本层去重
- 棋盘问题:N皇后,解数独等等
去重:
使用set去重的版本相对于used数组的版本效率都要低很多:主要是因为程序运行的时候对unordered_set 频繁的insert,unordered_set需要做哈希映射(也就是把key通过hash function映射为唯一的哈希值)相对费时间,而且insert的时候其底层的符号表也要做相应的扩充,也是费时的。使用used数组在时间复杂度上几乎没有额外负担
使用set去重,不仅时间复杂度高了,空间复杂度也高了:组合,子集,排列问题的空间复杂度都是O(n),但如果使用set去重,空间复杂度就变成了O(n^2),因为每一层递归都有一个set集合,系统栈空间是n,每一个空间都有set集合。used数组可是全局变量,每层与每层之间公用一个used数组,所以空间复杂度是O(n + n),最终空间复杂度还是O(n)
332.重新安排行程 - Hard (跳过)
题目链接:力扣-332. 重新安排行程
给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。
所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。
例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。
51. N皇后 - Hard (跳过)
题目链接:力扣-51. N 皇后
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
37. 解数独 - Hard (跳过)
题目链接:力扣-37. 解数独
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sudoku-solver
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。