【LeetCode】 组合总和 (标准dfs)
力扣 组合总和(标准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
}
    心之所向,素履以往

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号