题目:
难度:Middle
相关话题:数组
、回溯算法
给定一个数组 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]
]
思路:
和NO.39
区别:
存在重复数字,需要去重。
每个数字只能用1次。
对于第一个区别,需要对数组排序,排序是为了能更方便的去重,每次遍历时,检查i>start && candidates[i]===candidates[i-1]
,其中start
是当前回溯的开始索引, 如果条件成立,说明当前值和上一个值是相同的,因此跳过以避免重复。
对于第二个区别,下一次的回溯,都是从索引i+1
开始。
/**
* @来源: Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
* @介绍:一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum2 = function(candidates, target) {
let result=[]
candidates.sort()
backtrack([],0,target)
return result
function backtrack(temp,start,rest){
if(rest<0)return
if(rest===0)result.push(temp.slice())
for(let i=start;i<candidates.length;i++){
if(i>start && candidates[i]===candidates[i-1])continue
temp.push(candidates[i])
backtrack(temp,i+1,rest-candidates[i])
temp.pop()
}
}
};