尝试解决 LeetCode 上的二叉树前序遍历(https://leetcode-cn.com/problems/binary-tree-preorder-traversal/submissions/)。
按照网上普遍教程的惯例,我的代码如下:
```go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var res []int
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return res
}
res = append(res, root.Val)
preorderTraversal(root.Left)
preorderTraversal(root.Right)
return res
}
```
使用官方的测试用例,能够成功【执行代码】并输出结果,而且对比之后,也无异样。请看下图中的蓝色框框部分:
但是【提交】后,就出现了问题。第一个测试用例都无法通过,请看下图中的红色框框部分:
![image.png](https://static.studygolang.com/210514/7161257473971a8a890bacf2c4c0d953.png)
我很纳闷的是:为什么给了一个空值,却输出了一个 `[1, 2, 3]` 的切片呢?我的代码里也没有硬编码 `1, 2, 3` 这样的值。
var res []int
这里定义了全局变量
preorderTraversal在提交时会被多次运行,第一次运行完后,第二次再运行,全局变量并没有没初始化
#1
更多评论
非要使用全局变量加递归的方法的话,再写一个方法,把处理逻辑放到新的方法在,然后在 preorderTraversal 中初始化 res 切片,就不会出现这个问题了
#2
感谢 <a href="/user/zerolinck" title="@zerolinck">@zerolinck</a> 大佬的指点,终于把问题想明白了。
在【提交】代码时,LeetCode 会把测试用例 `[1, null, 2, 3]` 执行一遍,等下一次再跑其他测试用例时,仍旧在使用这个全局变量的切片。如果继续跑下去,所有的结果都会往这个全局切片的后面追加,最终导致结果与预期不符。
最终实现的代码如下:
闭包中局部变量的方式:
```go
func preorderTraversal(root *TreeNode) []int {
var res []int
var prev func(node *TreeNode)
prev = func(node *TreeNode) {
if node == nil {
return
}
res = append(res, node.Val)
prev(node.Left)
prev(node.Right)
}
prev(root)
return res
}
```
全局变量方式:
```go
var res []int
func prev(node *TreeNode) {
if node == nil {
return
}
res = append(res, node.Val)
prev(node.Left)
prev(node.Right)
}
func preorderTraversal(root *TreeNode) []int {
res = make([]int, 0)
prev(root)
return res
}
```
#3