Go中的组合总和

时间:2017-04-01 15:59:19

标签: recursion go

/*
Given an array: [1,2] and a target: 4
Find the solution set that adds up to the target
in this case:
[1,1,1,1]
[1,1,2]
[2,2]
*/
import "sort"
func combinationSum(candidates []int, target int) [][]int {
    sort.Ints(candidates)
    return combine(0, target, []int{}, candidates)
}
func combine(sum int, target int, curComb []int, candidates []int) [][]int {
    var tmp [][]int
    var result [][]int
    if sum == target {
        fmt.Println(curComb)
        return [][]int{curComb}
    } else if sum < target {
        for i,v := range candidates {
            tmp = combine(sum+v, target, append(curComb, v), candidates[i:])
            result = append(result,tmp...)
        }
    }
    return result
}

这是Leetcode中的一个问题,我使用递归来解决它。

在第18行中,当总和等于目标时,我打印每个案例。 输出是:

[1,1,1,1]
[1,1,2]
[2,2]

这就是我想要的答案! 但为什么是最终答案(二维):

[[1,1,1,2],[1,1,2],[2,2]]

预期答案是:[[1,1,1,1],[1,1,2],[2,2]]

请帮我在代码中找到错误。谢谢你的时间。

1 个答案:

答案 0 :(得分:2)

这是因为切片的工作方式。切片对象是对基础数组的引用,以及切片的长度,指向数组中切片起点的指针以及切片的容量。切片的容量是从切片的开头到数组末尾的元素数。附加到切片时,如果新元素有可用容量,则会将其添加到现有数组中。但是,如果没有足够的容量,const int num_of_strings = 255; //argc ? const int num_of_chars = 1000; int i; char** strarr =(char**)malloc(sizeof(char*)*num_of_strings); if(strarr == NULL) return 0; for (i = 0; i < num_of_strings; i++) strarr[i] = (char*)malloc(sizeof(char)*num_of_chars); 将分配一个新数组并复制元素。新数组分配了额外的容量,因此每个追加都不需要分配。

append循环中,当forcurComb时,其容量为4.在循环的连续迭代中,您追加1然后追加2,这两者都不会导致重新分配因为数组中有足够的空间用于新元素。当[1, 1, 1]curComb时,它会被放在结果列表中,但在[1, 1, 1, 1]循环的下一次迭代中,for会将最后一个元素更改为2(请记住它是相同的底层数组),所以这就是你在最后打印结果时所看到的。

解决方法是在总和等于目标时返回append的副本:

curComb

This article可以很好地解释切片是如何工作的。