我先上代码
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func Solution199(root *TreeNode) []int {
return dfs199(root, []int{})
}
func dfs199(root *TreeNode,ans []int)[]int{
if root == nil{
return ans
}
new := append(ans,root.Val)
right := dfs199(root.Right,new)
left := dfs199(root.Left,new)
fmt.Println(root.Val,":")
if root.Right != nil{
fmt.Println(root.Right.Val,right)
}
if root.Left != nil{
fmt.Println(root.Left.Val,left)
}
result := right
if len(left) > len(right){
result = append(result,left[len(right):]...)
}
fmt.Println(result)
return result
}
func main() {
root := &tree.TreeNode{
Val: 1,
Left: nil,
Right: &tree.TreeNode{
Val: 5,
Left: &tree.TreeNode{
Val: 3,
Left: &tree.TreeNode{
Val: 2,
Left: nil,
Right: nil,
},
Right: &tree.TreeNode{
Val: 4,
Left: nil,
Right: nil,
},
},
Right: nil,
},
}
fmt.Println(tree.Solution199(root))
}
我发现 当递归到 3 这个节点的时候,right 这个数组 通过 dfs199 函数递归后得到是 1534 ,但是当下一个 left 这个数组 通过 dfs199 函数递归后得到 1532 的时候,right 也会跟着变成 1532 这是为什么呢?
1
sagaxu 97 天前
猜谜语啦,OP 代码的意图是什么?
|
2
zzhaolei 97 天前
这就是 go 的 bug 了?有没有简化的最小复现版?
|
3
kingcanfish 97 天前
为啥不先怀疑自己有没有语法错误或者解法错误,而怀疑是 go 有 bug
还有你这二叉树右视图解法不对吧 ```` func rightSideView(root *TreeNode) []int { var ans []int dfs(root, 0, &ans) return ans } func dfs(root *TreeNode, level int, ans *[]int) { if root == nil { return } if level == len(*ans) { *ans = append(*ans, root.Val) } dfs199(root.Right, level+1, ans) dfs199(root.Left, level+1, ans) } ``` |
4
LittleYangYang 97 天前
不明白 OP 是什么意图,但盲猜一个是 Slice 底层数组共享了
参考 func Test(t *testing.T) { base := []int{1, 2, 3} base1 := append(base, 4) base2 := append(base1, 5) fmt.Println("Before:") fmt.Println(base) fmt.Println(base1) fmt.Println(base2) base1[0] = 0 base2[1] = 0 fmt.Println("After:") fmt.Println(base) fmt.Println(base1) fmt.Println(base2) } === RUN Test Before: [1 2 3] [1 2 3 4] [1 2 3 4 5] After: [1 2 3] [0 0 3 4] [0 0 3 4 5] --- PASS: Test (0.00s) |
5
Kinnice 97 天前 via Android 9
放心,粗看了一下代码,你的技术水平还不至于可以发现 go 的 bug.
|
6
husher123 97 天前
回答这种问题应该 gpt 很擅长呀~
你遇到的问题是由于 Go 中的切片 (slice) 的底层实现导致的。切片是指向底层数组的引用,因此在函数中对切片的修改会影响到其他引用该切片的变量。具体来说,当你在递归函数中对 right 进行递归调用时,right 和 new 共享同一个底层数组。于是当 left 再次使用 new 时,会改变同一个底层数组,导致 right 的值也被修改。 为了避免这个问题,可以在递归调用前创建新的切片,这样 right 和 left 就不会共享同一个底层数组。 以下是修改后的代码: https://go.dev/play/p/pHLut5kz-uu 通过使用 make 和 copy 函数,我们创建了一个新的切片 newAns ,从而避免了对同一底层数组的引用。这将解决你所遇到的问题。 |
7
cmdOptionKana 97 天前
OP 是担心不这样问就没人回答问题?
|
8
SmartLeo 97 天前
```
func dfs199(root *TreeNode, ans []int) []int { if root == nil { return ans } new := append(ans, root.Val) right := dfs199(root.Right, new) left := dfs199(root.Left, new) fmt.Printf("t: ans:%p new:%p\n", ans, new) fmt.Printf("t: Cap(ans):%d Cap(new):%d\n", cap(ans), cap(new)) fmt.Printf("t: L(ans):%d L(new):%d\n", len(ans), len(new)) fmt.Println(root.Val, ":") if root.Right != nil { fmt.Printf("%d %v %p\n", root.Right.Val, right, right) } if root.Left != nil { fmt.Printf("%d %v %p\n", root.Left.Val, left, left) } result := right if len(left) > len(right) { result = append(result, left[len(right):]...) } fmt.Println() fmt.Println(result) fmt.Printf("t: result:%p\n\n", result) return result } ``` 肯定不是 go 的问题啦,是你代码逻辑问题。 你没有完整地了解 slice 的一些特性。 你可以用这段代码看看。 具体到你的问题,显然到 3 那个节点的时候,左右的 slice 是同一个 slice ,而这个 slice 因为调用关系,被最后 left 的处理逻辑最后覆写了。 |
9
deplives 97 天前 via iPhone 1
众所周知,自认为发现主流语言 bug 的都是_____
学艺不精(俗称菜狗) |
10
PTLin 96 天前
go 虽然很简单,但是还没简单到学一天就能让你了解到所有 go 的小坑。
|
11
dingawm 96 天前 1
错误的提问:求大家帮忙看看我的代码有啥问题
正确的提问:我发现 go 好像有个 bug 开个玩笑,楼主也许真的以为是 bug |
12
honjow 96 天前 via iPhone 1
在 v2 看到好几个刚学习就嚷嚷发现语言 bug 的帖子了。结果都是自己没搞清楚,大多都是引用相关问题
|
13
guanzhangzhang 96 天前
|
14
xiaozirun 77 天前
怀疑题主是想找人帮他找出他写的 bug🤣
|