一、题干
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
二、思路及代码
这道题是典型的回溯问题,回溯问题关键在于考虑好边界条件。为了寻找到所有的解,我们需要依次找到排列,直观的想法是每次遍历一个数,并找到所求目标和target减去该数的所有的组合。当剩余值小于等于0时结束,为0时将路径加入到结果中。
为了能够避免重复,我们还需要保证每个子问题寻找的起始值是当前遍历的坐标,这样就不会出现[2,3,2],[2,2,3]的重复结果。
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> res;
vector<int> path;
sort(candidates.begin(),candidates.end());//只是为了和结果对应
if(candidates.size()==0) return res;
dfs(candidates,target,path,res,0);
sort(res.begin(),res.end());
return res;
}
void dfs(vector<int>& candidates,int value,vector<int> &path,vector<vector<int>> &res,int begin)
{
if(value<0) return;
if(value==0)
{
res.push_back(path);
return ;
}
for(int i=begin;i<candidates.size();i++)
{
if(value-candidates[i]>=0)
{
path.push_back(candidates[i]);
dfs(candidates,value-candidates[i],path,res,i);//注意下一子部分是从i下标开始的
path.pop_back();//注意这里的push和pop的操作,相当于从一支跳转到另一支
}
}
}
};