美文网首页
leetcode的Combination Sum题补充切片的传递

leetcode的Combination Sum题补充切片的传递

作者: fjxCode | 来源:发表于2018-11-04 10:18 被阅读0次

    Combination Sum以go 切片的传递

    内容:
    回溯法。
    切片切为形参,为值传递。如果需要引用传递,要加指针。
    切片作为append参数是引用传递。
    前拷贝copy方法,要求dst的len大于len(src)。
    append则没有这个要求,只要在cap以内。
    区别make()切片的len参数和cap参数。
    回溯法的curRes无论传值,还是传址的,都要清理数据,以准备下次迭代。

    题目:

    Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
    
    The same repeated number may be chosen from candidates unlimited number of times.
    
    Note:
    
    All numbers (including target) will be positive integers.
    The solution set must not contain duplicate combinations.
    Example 1:
    
    Input: candidates = [2,3,6,7], target = 7,
    A solution set is:
    [
      [7],
      [2,2,3]
    ]
    Example 2:
    
    Input: candidates = [2,3,5], target = 8,
    A solution set is:
    [
      [2,2,2,2],
      [2,3,3],
      [3,5]
    ]
    

    思路:

    • 回溯法的递归和非递规实现
    • 重点:切片是个引用传递,curRes加入res需要拷贝。但是作为参数传递是值传递,需要传res *[][]int
    • 执行前拷贝要给足len。
    • 回溯递归调用前后,要注意curRes的添加和清理。虽然无论是递归方法的值传递不会改变curRes(引用一定会改变),但至少循环当中的app()就改变了curRes。
    • 重点:去掉重复解的方法,在递归中加一个形参idx。允许重复从idx遍历,不允许重复从idx+1遍历。

    解:(这个解有重复解)

    func combinationSum(candidates []int, target int) [][]int {
        res := make([][]int,0)
        var curRes []int
        backtraceCombinationSum(candidates,target,curRes,&res)
        return res
    }
    
    func backtraceCombinationSum(candidates []int, target int,curRes []int,res *[][]int)  {
        if target<0{
            return
        }
        if target==0{
            curRes1 := make([]int,len(curRes))
            copy(curRes1,curRes)
            *res = append(*res,curRes1)
            return
        }
    
        for _,elem := range candidates{
            curRes = append(curRes,elem)
            backtraceCombinationSum(candidates,target-elem,curRes,res)
            curRes = curRes[0:len(curRes)-1]
        }
    }
    

    解:(修复了重复解问题)

    func combinationSum(candidates []int, target int) [][]int {
        res := make([][]int,0)
        var curRes []int
        backtraceCombinationSum(candidates,target,0,curRes,&res)
        return res
    }
    
    func backtraceCombinationSum(candidates []int, target int,idx int,curRes []int,res *[][]int)  {
        //必须要引用传递*res
        if target<0{
            return
        }
        if target==0{
            //需要深复制,copy不同于append,要给足len
            curRes1 := make([]int,len(curRes))
            copy(curRes1,curRes)
            *res = append(*res,curRes1)
            return
        }
    
        for i := idx;i<len(candidates);i++{
            curRes = append(curRes,candidates[i])
            backtraceCombinationSum(candidates,target-candidates[i],i,curRes,res)
            //需要清理数据,准备下次迭代
            curRes = curRes[0:len(curRes)-1]
        }
    }
    

    尾声,可以在循环体for中加一个target<0直接continue的判断,减少一次递归调用。增加执行效率。

    相关文章

      网友评论

          本文标题:leetcode的Combination Sum题补充切片的传递

          本文链接:https://www.haomeiwen.com/subject/wprrxqtx.html