回溯算法之组合的和
回溯算法之组合的和
算法原理
回溯法的基本思想是按照输入数组的顺序,每一层递归处理一个元素,当处理到最后一层的时候,也就是把数组中的所有元素都处理完的时候,把当前结果加入到最后的返回结果中。值得注意的是,每次在递归到下一层之前,我们加入了某个要处理的元素X,在下一层递归返回之后,我们要把之前加入的元素X从当前结果中取出来。如果我们不把元素X取出来,那么在下一次循环中,我们还会加入新的元素Y。那么在这一层递归中就相当于处理了不止一个新元素。
例如下面的一个递归树(例题一)
原图地址:https://blog.****.net/jaster_wisdom/article/details/80683651
例题:
class Solution {
vector<int>path;
vector<vector<int>>res;
public:
vector<vector<int>> combinationSum(vector<int>& can, int target) {
sort(can.begin(), can.end());
dfs(can, 0, target);
return res;
}
void dfs(vector<int>& can ,int u, int target){
if(target < 0){
return;
}
if(target == 0){
res.push_back(path);
return ;
}
for(int i = u; i < can.size(); i++){
path.push_back(can[i]);
dfs(can,i,target - can[i]);
path.pop_back();
}
}
};
class Solution {
vector<int>path;
vector<vector<int>>res;
public:
vector<vector<int>> combinationSum2(vector<int>& can, int target) {
sort(can.begin(), can.end());
dfs(can, 0, target);
return res;
}
void dfs(vector<int>& can ,int u, int target){
if(target < 0){
return;
}
if(target == 0){
res.push_back(path);
return ;
}
for(int i = u; i < can.size(); i++){
if (i != u && can[i] == can[i-1]) continue;
path.push_back(can[i]);
dfs(can,i+1,target - can[i]);//不包含重复的元素,故从下一位开始
path.pop_back();
}
}
};
class Solution {
vector<int>path;
vector<vector<int>>res;
public:
vector<vector<int>> combinationSum3(int k, int n) {
dfs(1,k ,n);
return res;
}
void dfs(int u ,int k ,int n){
if(k == 0&&0 == n){
res.push_back(path);
return;
}
for(int i = u ; i < 10 && i <= n;i++){
path.push_back(i);
dfs(i+1,k-1,n-i);
path.pop_back();
}
}
};