代码随想录Day27 | 回溯:回溯理论 77. 组合
理论基础
随想录
代码结构:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
77. 组合
题目链接
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
经典回溯方法
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtrack(int n , int k, int cur) {
if (path.size() == k) {
res.push_back(path);
return;
}
for (; cur <= n; cur ++) {
path.push_back(cur);
backtrack(n, k, cur +1);
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
backtrack(n, k, 1);
return res;
}
};
剪枝
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtrack(int n , int k, int cur) {
if (path.size() == k) {
res.push_back(path);
return;
} else {
for (; cur <= n - (k - path.size())+ 1 ; cur ++) {
path.push_back(cur);
backtrack(n, k, cur +1);
path.pop_back();
}
}
}
vector<vector<int>> combine(int n, int k) {
backtrack(n, k, 1);
return res;
}
};
回溯法的打印日志
如何debug
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtrack(int n , int k, int cur) {
if (path.size() == k) {
res.push_back(path);
return;
} else {
for (; cur <= n - (k - path.size())+ 1 ; cur ++) {
path.push_back(cur);
cout<< "回溯之前=>";
for (auto i : path) cout<< i << " ";
cout<< endl;
backtrack(n, k, cur +1);
path.pop_back();
cout<< "回溯之后=>";
for (auto i : path) cout<< i << " ";
cout<< endl;
}
}
}
vector<vector<int>> combine(int n, int k) {
backtrack(n, k, 1);
return res;
}
};
回溯之前=>1
回溯之前=>1 2
回溯之前=>1 2 3
回溯之后=>1 2
回溯之前=>1 2 4
回溯之后=>1 2
回溯之后=>1
回溯之前=>1 3
回溯之前=>1 3 4
回溯之后=>1 3
回溯之后=>1
回溯之后=>
回溯之前=>2
回溯之前=>2 3
回溯之前=>2 3 4
回溯之后=>2 3
回溯之后=>2
回溯之后=>