1. 题目描述
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
2. 解题思路
这道题目可以使用回溯+剪枝来解决,和39题类似。在39题中,元素可以重复使用,这里不能重复。所以需要加上相应的条件来限制元素不能重复。
首先,给定的数组中是可以有重复元素的,所以对它进行排序,让那些相同的数字都相邻,这样便于后面的去重。
当选择中,遇到两个相同的元素,为了不重复选项,可以添加以下条件来进行限制:
if(candidates[i - 1] === candidates[i] && i - 1 >= start){
continue
}
3. 代码实现
/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum2 = function(candidates, target) {
candidates.sort()
const res = []
const dfs = (start, arr, sum) => {
if(sum >= target){
if(sum === target){
res.push([...arr])
}
return
}
for(let i = start; i < candidates.length; i++){
if(candidates[i - 1] === candidates[i] && i - 1 >= start){
continue
}
arr.push(candidates[i])
// i+1是为了避免元素重复
dfs(i + 1, arr, sum + candidates[i])
arr.pop()
}
}
dfs(0, [], 0)
return res
};