描述
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
提示:
1 <= candidates.length <= 100
1 <= candidates[i] <= 50
1 <= target <= 30
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/combination-sum-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
C++代码
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<vector<int>> res;
vector<int> cur; // 存储当前组合
sort(candidates.begin(), candidates.end()); // 排序,方便后面去重
dfs(candidates, target, 0, cur, res);
return res;
}
private:
void dfs(vector<int>& candidates, int target, int start, vector<int>& cur, vector<vector<int>>& res) {
if (target == 0) { // 如果当前组合的和等于目标数,将其加入结果集
res.push_back(cur);
return;
}
for (int i = start; i < candidates.size() && candidates[i] <= target; i++) { // 遍历数组,从 start 开始遍历,避免重复
if (i > start && candidates[i] == candidates[i - 1]) { // 如果当前数与前一个数相同,跳过
continue;
}
cur.push_back(candidates[i]); // 将当前数加入当前组合
dfs(candidates, target - candidates[i], i + 1, cur, res); // 递归,搜索下一个数
cur.pop_back(); // 回溯,将当前数从当前组合中删除
}
}
};
Python代码
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
result = []
path = []
def dfs(start, target_):
if target_ == 0:
result.append(path[:])
return
for i in range(start, len(candidates)):
if candidates[i] > target_:
break
if i > start and candidates[i] == candidates[i-1]:
continue
path.append(candidates[i])
dfs(i+1, target_-candidates[i])
path.pop()
candidates.sort()
dfs(0, target)
return result