回溯算法的理论基础
1、纯暴力的搜索
2、回溯法函数可以理解为递归函数
3、解决以下的问题:
(组合是不用强调元素的位置,排列需要强调元素的位置
例如:{1, 2} 和 {2, 1} 在组合上,就是一个集合,因为不强调顺序,而要是排列的话,{1, 2} 和 {2, 1} 就是两个集合了。)
- 组合问题(例如给一个整数集合,求大小为2的子集合)
- 切割问题(例如给一个字符串,求切割方式的种类数,或者给定的一些特定条件再求切割之后的字符串数)
- 子集问题(例如给一个集合,求它的子集)
- 排列问题(与组合问题类似)
- 棋盘问题(N皇后和解数独问题)
4、如何理解回溯法
回溯法解决的问题都可以抽象为树形结构
5、回溯法的模板
- 回溯法是没有返回,一般起名叫 backtracking
- 一般的参数是很多,所以一开始可能无法确定参数的大小。所以我们可以在后面需要什么参数再添加参数即可。
- 终止条件:收集结果的时候。不同的问题不同的结果集。if——return
- 单层搜索逻辑:一个for循环,其下参数是遍历集合的元素,循环内容是处理节点,然后递归,再然后回溯
力扣题目 77.组合
class Solution {
//结果集
List<List<Integer>> result = new ArrayList<>();
//一位数组,储存结果集里面的元素
List<Integer> path = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
backTracking(n,k,1);
return result;
}
//确定返回值和传入参数————可以先写逻辑再加参数
private void backTracking(int n, int k, int startIndex){
//确定终止条件
if(path.size() == k){
result.add(new ArrayList(path));
return ;
}
//单层遍历逻辑
for(int i=startIndex; i<=n; i++){
path.add(i);
backTracking(n,k,i+1);
path.removeLast();
}
}
}