Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1,a2,…,ak) must be in non-descending order. (ie, a1≤a2≤…≤ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5
and target 8
,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
解题思路
依然采用回溯法求解。 、
先对数组进行排序。
注意数组中的每个数 candidates[i] 不允许被使用多次,但如果一个数在数组中出现多次的话,就可以使用多次(比如 candidates[i]=candidates[j]=10,i≠j,则 10
可以使用 2 次)。
在递归之前,我们需要跳过重复的数字,并统计该数字重复的次数。
代码如下:
class Solution {
private:
void internalCombinationSum2(vector<int> &candidates, int idx, int target,
vector<int> &path, vector<vector<int>> &res) {
if ((target < 0) || (idx >= candidates.size() && target > 0)) return;
if (target == 0) {
// 找到了一个组合之和等于 target
res.push_back(path);
return;
}
// 统计每个数字可以重复的次数
int repeate = 1;
while ((idx < candidates.size() - 1) && (candidates[idx] == candidates[idx+1])) {
repeate++;
idx++; // Note
}
for (int r = 0; r <= repeate; ++r) {
path.insert(path.end(), r, candidates[idx]);
// 递归
internalCombinationSum2(candidates, idx + 1,
target - r * candidates[idx], path, res);
path.erase(path.end() - r, path.end());
}
}
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<int> path;
vector<vector<int>> result;
sort(candidates.begin(), candidates.end()); // 排序
internalCombinationSum2(candidates, 0, target, path, result);
return result;
}
};