题解:
回溯三部曲:
1、确定回溯函数参数
2、确定回溯终止条件
当总和等于目标和时,将该数组加入结果集,返回,当总和大于目标和,直接返回
3、确定单层搜索逻辑
依然for循环横向遍历,递归纵向遍历,如下(代码随想录讲解图):
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates,int target,int startIndex,int sum){
//终止条件
if(sum>target){
return;
}
if(sum == target){
result.push_back(path);
return ;
}
//单层搜索过程
for(int i = startIndex;i<candidates.size();i++){
//处理
path.push_back(candidates[i]);
sum+=candidates[i];
//回溯 startIndex 还是从i开始 表示可以重复选取
backtracking(candidates,target,i,sum);
sum-=candidates[i];
path.pop_back();
}
return;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
};
剪枝:对于下一层递归总和超过目标值的没有必要进入下一层递归,如此,对原数组排个序(为什么排序,如上图,第二层取了3发现超过目标值 没有必要再取5来判断),由此在for循环中增加一个判断
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates,int target,int startIndex,int sum){
//终止条件
if(sum == target){
result.push_back(path);
return ;
}
//单层搜索过程
for(int i = startIndex;i<candidates.size()&&sum+candidates[i]<=target;i++){
//处理
path.push_back(candidates[i]);
sum+=candidates[i];
//回溯 startIndex 还是从i开始 表示可以重复选取
backtracking(candidates,target,i,sum);
sum-=candidates[i];
path.pop_back();
}
return;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,0,0);
return result;
}
};