【发布时间】:2019-12-14 20:09:53
【问题描述】:
我有以下函数可以生成给定数组的所有子集。
这个想法很简单 - 我从一个包含空集(切片)的结果数组开始,对于输入数组 nums 中的每个元素,遍历所有先前生成的集合,将 nums 的当前元素添加到它们并将生成的新集合添加回结果数组。没什么特别有趣的。
func subsets(nums []int) [][]int {
result := [][]int{{}}
for _, n := range nums {
newSets := [][]int{}
for _, set := range result {
newSets = append(newSets, append(set, n))
}
result = append(result, newSets...)
}
return result
}
问题是使用append(newSets, append(set, n)) 会破坏result 切片,set 是其中的成员。我用一些调试代码(见下文)稍微修改了函数,还找到了一个不会导致相同行为的解决方法(注释代码)。
我非常怀疑这是由通过引用传递而不是被复制的东西引起的(我将newSets 的元素附加到result)。问题是我找不到它。 :( 我从不在循环中更改结果
func subsets(nums []int) [][]int {
result := [][]int{{}}
for _, n := range nums {
newSets := [][]int{}
var before, after []int
for _, set := range result {
lastResultIdx := len(result)-1
if lastResultIdx > 0 {
before = make([]int, len(result[lastResultIdx]))
copy(before, result[lastResultIdx])
}
//ns := []int{}
//for _,v := range set {
// ns = append(ns, v)
//}
//ns = append(ns, n)
//newSets = append(newSets, ns)
newSets = append(newSets, append(set, n))
if lastResultIdx > 0 {
after = result[lastResultIdx]
if before[len(before)-1]!=after[len(after)-1] {
fmt.Println(n, "before", before, "after", after)
}
}
}
result = append(result, newSets...)
}
return result
}
func main() {
subsets([]int{0, 1, 2, 3, 4})
}
【问题讨论】: