回溯算法理论基础
文章讲解 视频讲解
- 回溯是递归的副产品,只要有回溯就会有递归
- 回溯的本质是琼剧,所以效率不高
回溯法可以解决的问题
- 组合问题
- 切割问题
- 子集问题
- 排列问题
- 棋盘问题
如何理解回溯
- 回溯算法的问题都可以抽象为树形结构
- 集合的大小就构成了书的快读,递归的深度就构成了树的深度
回溯法模板
回溯三部曲
-
回溯函数返回值及参数
返回值一般为void,参数通常不固定,先写逻辑需要什么参数再传什么参数void backtracking(参数)
-
回溯函数终止条件
一般来说搜索到叶子节点就可以回溯了if(终止条件) {存放结果;return; }
-
回溯搜索的遍历过程
for(选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果 }
-
整体框架
void backtradking(参数) {if(终止条件) {存放结果;return;}for(选择:本层集合中的元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果} }
77.组合
题目链接 文章讲解 视频讲解
class Solution {
public:vector<vector<int>> combine(int n, int k) {vector<int> path;vector<vector<int>> ans;backtracking(n, k, path, ans, 1);return ans;}void backtracking(int n, int k, vector<int>& path, vector<vector<int>>& ans, int startIndex) {// 终止条件if(path.size() == k) {ans.push_back(path);return ;}for(int i = startIndex; i <= n; ++i) {// 处理节点path.push_back(i);// 递归backtracking(n, k, path, ans, i + 1);// 回溯path.pop_back();}}
};