组合问题·回溯法
题目
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
思路
从简单的开始。
假设k = 2,那么需要两层循环:
for(int i = 1; i <= n; i++) {
for(int j = i+1; j <= n; j++) {
printf("%d, %d\n", i, j);
}
}
假设k = 3, 那么需要三层循环:
for(int i = 1; i <= n; i++) {
for(int j = i+1; j <= n; j++) {
for(int k = j+1; k <= n; k++) {
printf("%d, %d, %d\n", i, j, k);
}
}
}
…
所以组合问题相当于在一个树状结构(自行想象)中进行了DFS搜索。
回溯问题的解决模板
循环中递归。。。
backtracking(...) {
if(...) {
... //返回结果
return;
}
for(...) {
// 处理当前节点
backtracking(...); // 递归处理
// 回溯到上一个作出选择的地方~
}
}
题目解答
class Solution {
private:
vector<vector<int>> res; // 最后的结果集合
vector<int> path; //可能的结果路径
void backtracking(int n, int k, int start_idx) {
if(this->path.size() == k) {
res.push_back(this->path); // 找到可能的结果啦
return;
}
for(int i = start_idx; i <= n; i++) {
this->path.push_back(i); // 处理当前节点
backtracking(n, k, i + 1);
this->path.pop_back(); // 回溯
}
}
public:
vector<vector<int>> combine(int n, int k) {
backtracking(n, k, 1);
return this->res;
}
};