day24-1 回溯算法理论基础
- 递归函数下面一般紧跟的就是回溯算法
- 回溯算法一般是纯暴力搜索
- 回溯法解决的问题都可以抽象为树形结构(N叉树)
- 能够解决哪些问题?
- 组合问题:N个数里面按一定的规则找出k个数的组合
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里面有多少符号条件的子集
- 排列问题:强调顺序
- 棋盘问题:N皇后和解数独
- 过程:
- 终止条件:收集结果
- 单层搜索逻辑:处理结点+递归函数+回溯操作
void backtracking(参数){
if(终止条件){
存放结果;
return;
}
for(选择:本层集合中的元素(数中节点孩子的数量就是集合的大小)){
处理结点;
backtracking(路径,选择列表);
回溯,撤销处理的结果
}
}
day24-2 77.组合
为啥要用回溯算法?
树形结构
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/03b2a9938afc4662b05ddf8ba67241f9.png)
回溯三部曲
- 递归函数的参数和返回值
- 确定函数的终止条件
- 单层递归逻辑
代码实现
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
combineHelper(n,k,1);
return result;
}
void combineHelper(int n, int k, int startIndex){
if(path.size() == k){
result.add(new ArrayList<>(path));
return;
}
for(int i = startIndex; i <= (n - (k - path.size()) + 1); i++){
path.add(i);
combineHelper(n, k, i + 1);
path.removeLast();
}
}
}
剪纸操作树形结构
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7467583b865c4432917723dbdac1b771.png)
耗时