题目描述
给定一个候选人编号的集合 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 <= 1001 <= candidates[i] <= 501 <= 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
}