问题
https://leetcode.com/problems/combination-sum-ii/
解法
回溯法,此题与39不同在于一个数可能出现了多次,此时我们需要制定规则。
首先对所有数从小到大排序,接着回溯法枚举选择和不选择每个数,对于相同数出现多次,我们规定只有第一个数被选择,之后的数才能被选择。
例如 111333444第一个1被选择第二,三个1才可以被选择。这样就不会出现重复。
class Solution {
public:
void dfs(vector<vector<int>> & ret, vector<int> &now, vector<int> & cand, int target, int i, int ds) // duplicate start;
{
if (target == 0)
{
ret.push_back(now);
return;
}
if (i== cand.size())
return;
if (cand[i] <= target)
{
if (ds != i && cand[ds] != cand[i])
ds = i;
int cnt = i-ds;
if (cnt==0 || now.size() >= cnt && now[now.size() -cnt] == cand[i])
{
now.push_back(cand[i]);
dfs(ret, now, cand, target-cand[i], i+1, ds);
now.pop_back();
}
dfs(ret, now, cand, target, i+1, ds);
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<vector<int>> ret;
vector<int> now;
dfs(ret, now, candidates, target, 0, 0);
return ret;
}
};