40. 组合总和 II
难度中等1200
给定一个候选人编号的集合 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
通过次数382,058
提交次数63
方法一:used数组
var(
path []int
res [][]int
used []bool
)
func combinationSum2(candidates []int, target int) [][]int {
path,res,used=make([]int,0,len(candidates)),make([][]int,0),make([]bool,len(candidates))
sort.Ints(candidates)
dfs(candidates,target,0,0)
return res
}
func dfs(candidates []int,target int,sum int,startindex int){
if target==sum{
tmp:=make([]int,len(path))
copy(tmp,path)
res=append(res,tmp)
return
}
if target<sum{
return
}
for i:=startindex;i<len(candidates);i++{
if candidates[i] > target { // 剪枝,提前返回
break
}
if i>0 && candidates[i]==candidates[i-1] && used[i-1]==false{//去重
continue
}
sum+=candidates[i]
path=append(path,candidates[i])
used[i]=true
dfs(candidates,target,sum,i+1)
used[i]=false
sum-=candidates[i]
path=path[:len(path)-1]
}
}
方法二:
var (
res [][]int
path []int
)
func combinationSum2(candidates []int, target int) [][]int {
res, path = make([][]int, 0), make([]int, 0, len(candidates))
sort.Ints(candidates) // 排序,为剪枝做准备
dfs(candidates, 0, target)
return res
}
func dfs(candidates []int, start int, target int) {
if target == 0 { // target 不断减小,如果为0说明达到了目标值
tmp := make([]int, len(path))
copy(tmp, path)
res = append(res, tmp)
return
}
for i := start; i < len(candidates); i++ {
if candidates[i] > target { // 剪枝,提前返回
break
}
// i != start 限制了这不对深度遍历到达的此值去重
if i != start && candidates[i] == candidates[i-1] { // 去重
continue
}
path = append(path, candidates[i])
dfs(candidates, i+1, target - candidates[i])
path = path[:len(path) - 1]
}
}
标签:target,int,res,40,II,candidates,len,path,总和
From: https://www.cnblogs.com/suehoo/p/17041226.html