Day24——回溯算法Ⅰ
- 77.组合
今日内容:
● 理论基础
● 77. 组合
理论:代码随想录
77.组合
思路:k层for循环,不会
回溯,将组合问题抽象成n叉树,for循环控制宽度,递归的深度控制二叉树的深度
循环终止条件:集合中存在k个数
vector<vector<int>> res;
vector<int> path;
public:
void backtracking(int n, int k, int startIndex) {
// 递归终止——深度控制
if(path.size() == k) {
res.push_back(path);
return;
}
// 宽度控制,已访问元素不再访问
for(int i = startIndex; i <= n; i++) {
path.push_back(i);
// 递归访问其余元素直到数组大小达标
backtracking(n, k, i + 1);
// 回溯,已访问叶子节点拿出
path.pop_back();
}
return;
}
vector<vector<int>> combine(int n, int k) {
backtracking(n, k, 1);
return res;
}
剪枝:
上述代码在进行递归时,必须要保证至少存在k个元素,即path.size()(集合中已有元素)+ (n - i + 1) (剩余可访问元素)>= k; 这样集合的元素个数才是满足k个的。
i <= n - k + path.size() + 1
void backtracking(int n, int k, int startIndex) {
// 递归终止——深度控制
if(path.size() == k) {
res.push_back(path);
return;
}
// 宽度控制,已访问元素不再访问
for(int i = startIndex; i <= n - k + path.size() + 1; i++) {
path.push_back(i);
// 递归访问其余元素直到数组大小达标
backtracking(n, k, i + 1);
// 回溯,已访问叶子节点拿出
path.pop_back();
}
return;
}