与前面的组合问题有所不同的是,本题是在一个给定数组candidates中,找到符合条件的组合,并且组合中允许出现重复的元素。
vector<int>& candidates: &表示引用
思路:使用回溯法,进入递归后,如果当前和大于目标和就跳出循环,如果当前和等于目标和就将当前组合压入答案栈,并跳出循环。递归函数的主循环是:从startIndex位置开始遍历,每遍历到一个数组元素就将元素压入中转栈(path),更新当前和的值,并开始下一次递归,注意下一次递归是从i开始,因为该题允许组合中有重复元素(如果不允许就应该从i+1开始)。完成下一层递归后,要记得弹出当前元素(从树形结构看就是退回上一个分支),中转栈的值也要更新。
我的代码:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backTracking(0,0,target, candidates);
return result;
}
vector<int> path;
vector<vector<int>> result;
void backTracking(int startIndex,int sum,int targetSum, vector<int>& candidates){
if(sum>targetSum){
return;
}
if(sum==targetSum){
result.push_back(path);
return ;
}
for(int i=startIndex;i<candidates.size();i++){
path.push_back(candidates[i]);
sum+=candidates[i];
backTracking(i,sum,targetSum,candidates);
sum-=candidates[i];
path.pop_back();
}
}
};
官方代码:
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backTracking(vector<int>& candidates , int target ,int startIndex)
{
if(target<0) return;
if(target == 0)
{
res.push_back(path);
return;
}
for(int i = startIndex ; i < candidates.size();i++)
{
path.push_back(candidates[i]);
target -= candidates[i];
backTracking(candidates,target ,i);
path.pop_back();
target += candidates[i];
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backTracking(candidates,target,0);
return res;
}
};