理论基础
回溯,其实是递归的“副产品”。有递归就会有相应的回溯过程。而回溯的本质是穷举,所以他并不是高效的算法。它可以理解为树形结构。他解决问题的操作是在集合中递归寻找子集。而集合的大小就是构成树的宽度,递归的深度构成了树的深度。
回溯法可以解决的问题:
1.组合问题
2.切割问题
3.子集问题
4.排列问题
5.棋盘问题
回溯算法模板:
void backTracking(定义参数) { if( 终止条件 ) { 存放结果; return ; } for(选择:本层集合中的元素) { 处理节点; backTracking( 路径,选择列表);//递归所在 回溯,撤销处理结果; } }
组合
class Solution {
private:
vector<int> path;//存放符合条件的结果
vector<vector<int>> result;//“模板类的模板类”——存放符合条件的结果 的集合
void backTracking(int n,int k,int startIndex){
if( path.size() == k){
result.push_back(path);
return ;
}
for(int i = startIndex; i <= n; i++)
{
path.push_back(i);//处理节点
backTracking(n, k, i + 1);//递归
path.pop_back();//回溯,撤销处理的节点
}
}
public:
vector<vector<int>> combine(int n, int k) {
result.clear();
path.clear();
backTracking(n,k,1);
return result;
}
};