题目:
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
抛砖引玉
思路
本题逻辑的重点在不允许 candidates 的元素重复使用,但是 candidates 元素本身可能存在重复元素
在前两天的题目中分别用:
两种形式处理了递归回溯子元素组合的问题
结合本题的要求:
实现
/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum2 = function (candidates, target) {
let _result = []
candidates = candidates.sort((a, b) => a - b)
function dfs(i, item, sum) {
if (sum === target) {
_result.push(item)
return
}
for (let x = i; x < candidates.length; x++) {
if (target - sum - candidates[x] >= 0) {
// i指针所在元素如果后面还有与其相同的元素,则不再选择i处元素,因为此时已回溯,再次选择i处元素则形成了重复的组合
if (x != i && candidates[x] == candidates[x - 1]) continue
item.push(candidates[x])
dfs(x + 1, [...item], sum + candidates[x])
item.pop()
}
}
}
dfs(0, [], 0)
return _result
}