给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次
注意: 解集不能包含重复的组合。
示例 1:

  1. 输入: candidates = [10,1,2,7,6,1,5], target = 8,
  2. 输出:
  3. [
  4. [1,1,6],
  5. [1,2,5],
  6. [1,7],
  7. [2,6]
  8. ]

示例 2:

  1. 输入: candidates = [2,5,2,1,2], target = 5,
  2. 输出:
  3. [
  4. [1,2,2],
  5. [5]
  6. ]

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30

    解法一:回溯

    1. function combinationSum2(candidates: number[], target: number): number[][] {
    2. let res: Array<Array<number>> = []
    3. candidates.sort((a, b) => a -b)
    4. let n = candidates.length
    5. let used = Array(n).fill(false)
    6. function recursion(total: number, path: Array<number>, idx: number) {
    7. if (total > target) {
    8. return
    9. }
    10. if (total === target) {
    11. res.push([...path])
    12. return
    13. }
    14. for (let i = idx; i < n; i++) {
    15. const tmp = candidates[i]
    16. if (total + tmp > target) {
    17. break
    18. }
    19. if (i > 0 && tmp === candidates[i-1] && !used[i-1]) {
    20. continue
    21. }
    22. total += tmp
    23. path.push(tmp)
    24. used[i] = true
    25. recursion(total, path, i + 1)
    26. path.pop()
    27. total -= tmp
    28. used[i] = false
    29. }
    30. }
    31. recursion(0, [], 0)
    32. return res
    33. };