力扣 组合总和(标准dfs)
题目链接:https://leetcode-cn.com/problems/combination-sum/
题目的大致意思就是从一个没有重复元素的数组中,抽取任意个数其和要等于target,让你列出所有的组合方式
需要注意的是可选择多个同样的数组元素,无单个限制
解析:
-
target=7,选一个2,target=7-2=5,此时意思就是已经选了一个2了,求target等于5时的组合
-
target=7,选一个3,target=7-3=4,此时意思就是已经选了一个3了,求target等于4时的组合
这就是一个标准的dfs搜索,当target恰好等于0时,就找到了一个合法的组合
当target小于0时,没有必要往下继续搜索了,可以当做剪枝条件
给数组元素从小到大排序,当减去某个元素时target小于0了,也没有必须横向搜索了,也是一种剪枝
var nums []int
var result [][]int
// 判断两个数组是否相等
func check(a1,a2 []int) bool{
if len(a1)!=len(a2){
return false
}
for i:=0;i<len(a1);i++{
if a1[i]!=a2[i]{
return false
}
}
return true
}
func dfs(ans []int,x int){
if x<0{ // 小于0则没必要继续往下搜索了
return
}
if x==0{ // 等于0则代表是一种合法组合
// 对组合排序,并且看result中是否有这个组合,有就不必加入了
sort.Ints(ans)
flag:=true
for i:=0;i<len(result);i++{
if check(result[i],ans)==true{
flag=false
break
}
}
if flag==true{
result = append(result, ans)
}
return
}
// 针对每个数组元素都做dfs
for i:=0;i<len(nums);i++{
value:=x-nums[i]
newArr:=make([]int,len(ans)+1)
for j:=0;j<len(ans);j++{
newArr[j]=ans[j]
}
newArr[len(ans)]=nums[i]
if value>=0{
dfs(newArr,value)
}else {
break
}
}
}
func combinationSum(candidates []int, target int) [][]int {
nums=candidates
sort.Ints(nums)
result=[][]int{}
dfs([]int{},target)
return result
}