题目
给定一个数组 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]
]
方案(回溯)
func combinationSum2(candidates []int, target int) [][]int {
sort.Ints(candidates)
var res [][]int
dfs(candidates, []int{}, 0, target, 0, &res)
return res
}
// sum - sum(path)
// i - 遍历到的索引
func dfs(candidates, path []int, sum, target, i int, res *[][]int) {
if sum > target {
return
}
if sum == target {
dst := make([]int, len(path))
copy(dst, path)
*res = append(*res, dst)
return
}
for i < len(candidates) {
sum += candidates[i]
path = append(path, candidates[i])
i += 1
dfs(candidates, path, sum, target, i, res)
sum -= candidates[i-1]
path = path[:len(path)-1]
// 剪枝,回溯之后,如果数字出现重复则结果也会出现重复
for i > 0 && i < len(candidates) && candidates[i] == candidates[i-1] {
i += 1
continue
}
}
}