40. 组合总和 II
力扣链接(中等):https://leetcode.cn/problems/combination-sum-ii
给定一个候选人编号的集合 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
示例 1:
Text Only |
---|
| 输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
|
示例 2:
Text Only |
---|
| 输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
|
提示:
1 <= candidates.length <= 100
1 <= candidates[i] <= 50
1 <= target <= 30
个人题解
注意一定要思考一下如何判断当前层元素是否重复使用:
C++ |
---|
| // 先排序,这样才能让相同元素相邻,方便判断
sort(candidates.begin(), candidates.end());
// ...
// 为什么要首先判断 i > begin ?
if(i > begin && candidates[i] == candidates[i - 1]) {
continue;
}
|
C++ |
---|
| class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int> &candidates, int target, int sum, int begin) {
if(sum >= target) {
if(sum == target) result.push_back(path);
return;
}
for(int i = begin; i < candidates.size(); i++) {
// 判断在当前层中,当前元素是否已经使用
// i > begin 很关键,因为每往下递归一层,begin 都会 + 1(题目要求每个元素在每条路径中只能使用一次)
// 如果不判断 i > begin,那么就会误把递归过程中 i == begin (当前层第一次遍历的情况)
// 做 candidates[i] == candidates[i - 1] 判断,这是逻辑错误的,因为 i == begin (是当前层遍历到第一个元素)
// 第一个元素自然不存在重复使用当前层元素的情况
if(i > begin && candidates[i] == candidates[i - 1]) {
continue;
}
path.push_back(candidates[i]);
sum += candidates[i];
backtracking(candidates, target, sum, i + 1);
path.pop_back();
sum -= candidates[i];
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
// 先排序,这样才能让相同元素相邻,方便判断
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0);
return result;
}
};
|