解题思路
参考代码随想录
1.跟之前组合求和不同的一点是这里允许同一个数字使用多次,在代码中递归中有体现。
2.for循环是从选择集中遍历所有元素选择元素;处理过程是对sum求和、path添加元素;递归是往深度探索;回溯与处理过程一一对应。
3.这里一个剪枝操作是在for循环的条件语句中加的预判断,如果sum加上当前位置对应的候选元素小于等于目标值target,则需要进行处理递归回溯操作,否则没必要进行。
作者:jasscical
链接:https://leetcode-cn.com/problems/combination-sum/solution/39zu-he-zong-he-by-jasscical/
class Solution {
public:
vector<vector<int>> res; //总结果
vector<int> path; //子结果集
void backtracking(vector<int>& candidates, int sum, int target, int startIndex){
if(sum > target) return;
if(sum == target){
res.push_back(path); //往深度探索,得到一条符合的路径
return;
}
for(int i=startIndex; i<candidates.size() && candidates[i]+sum<=target; i++){ //条件进行了剪枝
sum += candidates[i]; //处理
path.push_back(candidates[i]); //处理
backtracking(candidates, sum, target, i); //递归,允许同一个数字使用多次,所以传入的是i,之前的题目是传入i+1
sum -= candidates[i]; //回溯
path.pop_back(); //回溯
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
res.clear();
path.clear();
sort(candidates.begin(), candidates.end()); //先排序,对剪枝有帮助
backtracking(candidates, 0, target, 0);
return res;
}
};