zhe回溯算法理论基础
回溯算法的本质是穷举,列举出各种可能,主要用于解决5种问题:组合问题、切割问题、子集问题、排列问题、棋盘问题。回溯法的基本模板如下:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
处理回溯问题一般采取三步:1、确定递归函数的返回值和参数 2、 回溯函数终止条件 3、单层搜索的过程
组合问题
这道题使用回溯思想来进行解题。具体思想就不解释了,重点在剪枝操作。
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
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) {
backtracking(n,k,1);
return result;
}
};
这道题可以进行剪枝操作,我们发现当n=4,k=4的时候,最后的结果只有一个[1,2,3,4],但是在使用上述代码进行执行的时候会持续遍历,从2开始遍历的时候这白费操作了,因此我们可以进行剪枝操作。我们知道path.size()就是已经选取的元素的大小,那么k-path.size()就是还需选取元素的数量。那么i至多要从n-(k-path.size())+1进行搜索。