1. 题目描述

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

  1. 输入: candidates = [10,1,2,7,6,1,5], target = 8,
  2. 所求解集为:
  3. [
  4. [1, 7],
  5. [1, 2, 5],
  6. [2, 6],
  7. [1, 1, 6]
  8. ]

示例 2:

  1. 输入: candidates = [2,5,2,1,2], target = 5,
  2. 所求解集为:
  3. [
  4. [1,2,2],
  5. [5]
  6. ]

2. 解题思路

这道题目可以使用回溯+剪枝来解决,和39题类似。在39题中,元素可以重复使用,这里不能重复。所以需要加上相应的条件来限制元素不能重复。

首先,给定的数组中是可以有重复元素的,所以对它进行排序,让那些相同的数字都相邻,这样便于后面的去重。

当选择中,遇到两个相同的元素,为了不重复选项,可以添加以下条件来进行限制:

  1. if(candidates[i - 1] === candidates[i] && i - 1 >= start){
  2. continue
  3. }

3. 代码实现

  1. /**
  2. * @param {number[]} candidates
  3. * @param {number} target
  4. * @return {number[][]}
  5. */
  6. var combinationSum2 = function(candidates, target) {
  7. candidates.sort()
  8. const res = []
  9. const dfs = (start, arr, sum) => {
  10. if(sum >= target){
  11. if(sum === target){
  12. res.push([...arr])
  13. }
  14. return
  15. }
  16. for(let i = start; i < candidates.length; i++){
  17. if(candidates[i - 1] === candidates[i] && i - 1 >= start){
  18. continue
  19. }
  20. arr.push(candidates[i])
  21. // i+1是为了避免元素重复
  22. dfs(i + 1, arr, sum + candidates[i])
  23. arr.pop()
  24. }
  25. }
  26. dfs(0, [], 0)
  27. return res
  28. };

4. 提交结果

40. 组合总和 II - 图1