LeetCode0039.组合总和 Go语言AC笔记

时间复杂度:O(nlog n)

解题思路

回溯法,对每一个数字都有两种选择——放入和不放入。递归边界为target≤0即数组中的总和不小于target。

先对candidates数组由小到大排序,然后回溯法搜索每一种情况,尝试放入candidates数组每一个元素,但可以通过事先剪枝不放入那些如果放入数组后总和超过target的元素来提高效率。

AC代码

自己实现

func combinationSum(candidates []int, target int) [][]int {
    res:=[][]int{}
    var dfs func(int,int)
    nums:=[]int{}
    dfs=func (sum,start int){
        if sum>=target{
            if sum==target{
                res=append(res,append([]int{},nums...))
            }
            return
        }
        for i:=start;i<len(candidates);i++{
            nums=append(nums,candidates[i])
            dfs(sum+candidates[i],i)
            nums=nums[:len(nums)-1]
        }
    }
    dfs(0,0)
    return res
}

参考解法

func combinationSum(candidates []int, target int) [][]int {
    temp,res:=[]int{},[][]int{}
    sort.Ints(candidates)
    dfs(candidates,target,0,temp,&res)
    return res
}

func dfs(nums []int,target int,index int,temp []int,res *[][]int){
    //递归边界
    if target<0{
        return
    }
    //找到一个答案
    if target==0{
        t:=make([]int,len(temp))
        copy(t,temp)
        *res=append(*res,t)
        return
    }
    //尝试放入每个元素
    for i:=index;i<len(nums);i++{
        //剪枝
        if nums[i]>target{
            break
        }
        temp=append(temp,nums[i])//放入该元素
        dfs(nums,target-nums[i],i,temp,res)//注意下一次递归还是从当前的i开始,因为可以重复放入
        temp=temp[:len(temp)-1]//回溯消除影响
    }
}

 

感悟

看到这种寻找所有可行解的题一定要想到回溯法,递归搜索每种情况,搭配剪枝可以极大提升效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SwithunH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值