OK,这边也是成功进入回溯算法了,递归往往伴随着回溯,回溯算法一般用于那些只能暴力解决的问题,并且还需要剪枝。
记住回溯算法模板:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
第77题. 组合
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
按着上面那个模板,我们可以写出以下代码:
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backtracing(int n,int k,int stindex){
if(path.size()==k)
{
res.push_back(path);
return;
}
for(int i=stindex;i<=n;i++)
{
path.push_back(i);
backtracing(n,k,i+1);
path.pop_back();
}
return;
}
vector<vector<int>> combine(int n, int k) {
backtracing(n,k,1);
return res;
}
};
如果后面的数字已经不够K个了,那么说明根本不用遍历了,这时就可以剪枝:
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backtracing(int n,int k,int stindex){
if(path.size()==k)
{
res.push_back(path);
return;
}
for(int i=stindex;i<=n-(k-path.size())+1;i++)
{
path.push_back(i);
backtracing(n,k,i+1);
path.pop_back();
}
return;
}
vector<vector<int>> combine(int n, int k) {
backtracing(n,k,1);
return res;
}
};