持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
回溯算法学习笔记
概念
回溯算法其实是一种用来搜索的算法。再二叉树中我们就多次潜在的运用到了回溯的思想。
回溯是递归的副产品,只要有递归就会有回溯。
所以说回溯函数就是递归函数,指的都是一个函数。
递归完函数 ,得到返回值,在对某些值进行其他的操作,就是一种回溯的体现
回溯算法的效率
回溯算法本质上是一种 穷举的搜索方式 效率肯定是不高的
用于解决的一些只能使用暴力穷举的题目
例如
- 组合问题:N个数里面按一定规则找出k个数的集合
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 棋盘问题:N皇后,解数独等等
回溯算法的模板
通常是以这样的情况出现的
当我们把问题的集合抽象为一棵树的话。大家可以从图中看出for循环可以理解是横向遍历,backtracking(递归)就是纵向遍历,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。
集合问题解决方案
昨天做了集合相关的题目,总结了一些东西
集合相对于排列不同,结果中一般不包含相同的 元素 例如 [[1,2,3],[2,3,1]]
在集合中是不允许的。而在排列中是可以出现的。
我们像以前学数学时一样画出响应的图解
响应的昨天做题时有三种套路
- 元素无重不可复选,即
nums
中的元素都是唯一的,每个元素最多只能被使用一次 - 元素可重不可复选,即
nums
中的元素可以存在重复,每个元素最多只能被使用一次 - 元素无重可复选,即
nums
中的元素都是唯一的,每个元素可以被使用若干次
元素无重不可复选
这是最基础的一种
我们看一些解题思路
以这道题为例
标准模板就是注释的部分
有几个需要注意的点
startIndex
是 组合题的关键,它可以保证横向遍历,不遍历以前出现的结果
这类题是最基本的模板,其他两种都是在这基础上进行一些改变
元素可重不可复选
即 nums
中的元素可以存在重复,每个元素最多只能被使用一次
以这道题为例
这道题的关键就在修剪掉相同的部分。我们就可以按照上图中白色框中的内容理解一下。
需要先对数据进行排序,然后在一层中如果一层中出现相邻的相同元素,就跳过这个循环过程,做到不重复的功能。
元素无重可复选
即 nums
中的元素都是唯一的,每个元素可以被使用若干次
相比起第一种方法
这种 元素无重可复选 的就是相当于在上面那种加上了一条自己的枝杈
代码上面的区别也不是很大
区别就在这里的 递归没有进行 i+1 的操作。