Day24 | 77. 组合
回溯模板
回溯算法
整体思路
回溯其实可以看作是一种暴力搜索的方法,递归的一种操作,在每次递归到深处后如果得到结果便进行返回,然后向上递归时通过回溯删去下游的信息,去另一个范围进行迭代。
因此整体的模板构造三部曲也和递归类似,不同的地方在于,回溯因为要对一个集合不断的压入和弹出新元素,并维护一个更大的集合,因此返回值为void,主要维护几个引用集合。终止条件与递归类似,但应该压入集合元素而非返回值。
在递归过程中,通过一个for循环进行所有元素的遍历。
模板代码如下:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
组合
LeetCode题目:https://leetcode.cn/problems/combinations
解题思路
这道题目很简单,进行递归遍历即可,值得注意的是,如果全部进行回溯,势必会存在一些无效的情况,因此,可以提前进行判定剩余的值是否可以填满数组,进行剪枝的操作。
代码:
class Solution {
public:
void backtracking(vector<vector<int>>& result,vector<int> &combination, int n,int k,int begin){
if(k==0){
result.push_back(combination);
return;
}
for(int i=begin;i<=n;i++){
if(n-i<k-1){
continue;
}
combination.push_back(i);
backtracking(result,combination,n,k-1,i+1);
combination.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> result;
vector<int> combination;
backtracking(result,combination,n,k,1);
return result;
}
};