回溯本质就是递归,和递归相辅相成。回溯法,一般可以解决如下几种问题:
组合问题:N个数里面按一定规则找出k个数的集合
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
排列问题:N个数按一定规则全排列,有几种排列方式
棋盘问题:N皇后,解数独等等
回溯三部曲:
回溯函数模板返回值以及参数
回溯函数终止条件
回溯搜索的遍历过程
和之前的递归的逻辑其实是一样的
递归函数返回值以及参数
确定递归终止条件
单层递归逻辑
![](https://i-blog.csdnimg.cn/blog_migrate/540cc086fa6153313b4963a73035e234.png)
(以上内容摘录于代码随想录)
77.组合
回溯法解决的问题都可以抽象为树形结构(N叉树),用树形结构来理解回溯就容易多了
![](https://i-blog.csdnimg.cn/blog_migrate/efbb2caa726eb7725ce18cca3f8cbf4d.png)
图中可以发现n相当于树的宽度,k相当于树的深度。代码如下
![](https://i-blog.csdnimg.cn/blog_migrate/a2490a76101836e1fbc36bd7bf2c15ba.png)
顺带回顾几个语法基础,因为我们要用到removeLast()移除list最后一个元素,所以path定义LinkedList<Integer> path = new LinkedList<>();
list接口下没有remove()方法的,arrayList类也没有,这里不能写错
![](https://i-blog.csdnimg.cn/blog_migrate/06967978ea395a218dad662c92e491f9.png)