【leet-code清晰解题思路💯✅】40. 组合总和 II

69 阅读1分钟

题目描述

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

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

注意: 解集不能包含重复的组合。 

示例 1:

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

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示:

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

解题思路

  • 这一题和39很像,限制就算是每个数只能使用一次。还是老样子用dfs搜索。这里要注意去重,例如我有两个1一个3,1、3和1、3是重复的,这里用一个1的话只能用一个。为了去重我们先把数组排序,例如113,如果第一个1用,第二个1可以用也可以不用,如果第一个1不用,则后面的也不用,防止重复。
func combinationSum2(candidates []int, target int) [][]int {
   sort.Ints(candidates)
   ans := make([][]int, 0)
   tmp := make([]int, 0)
   ans = dfs(0, target, 0, candidates, tmp, ans)
   return ans
}

func dfs(n, target, k int, nums, tmp []int, ans [][]int) [][]int {
   fmt.Printf("%v %v %v \n", n, k, tmp)
   if n == target {
      t := make([]int, len(tmp))
      copy(t, tmp)
      ans = append(ans, t)
      return ans
   }
   if k >= len(nums) || n > target {
      return ans
   }
   // 不取第k个
   t := k
   // 直接去重
   for t+1 < len(nums) && nums[t+1] == nums[t] {
      t++
   }
   ans = dfs(n, target, t+1, nums, tmp, ans)
   // 取第k个
   tmp = append(tmp, nums[k])
   ans = dfs(n+nums[k], target, k+1, nums, tmp, ans)
   tmp = tmp[0 : len(tmp)-1]
   return ans
}

image.png