给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其自底向上的层次遍历为:[ [15,7], [9,20], [3] ]
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
LeetCode
树结构
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
需求:
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
可知:左优先于边节点, 下优先于上
给出的demo, 让人感到很困惑,所以尝试调试[3,9,20,2,3,15,7]
发现原来是同一层的组成一个数组,从左到右排序,然后数组在由下向上。
从树结构发现,直接从底部输出当前层值,很难从底部返回到顶部,反而每次都需要从顶部遍历到指定层,如果按这个思路实现,会发现很难实现代码,而且实现起来,性能开销也有些大 ,时间复杂度为 O(n * n)。
那该怎么处理好?
我们发现,从上到下排列的时候, 只要最左边的数值优先进入当层的数组,然后一层一层往下遍历的时候,实现的结果,刚好是结论的反序。
[3,9,20,null,null,15,7]
=>[ [3], [9,20],[15,7] ]
只需反序就可以变为 [ [15,7], [9,20], [3] ]
于是开始编码
var res[][]intfunc levelOrderBottom(root *TreeNode) [][]int { depht(root, 0) l := len(res); end := l / 2; for i:=0; i < end ; i++{ res[i], res[l - i - 1] = res[l - i - 1], res[i] } return res;}func depht(root *TreeNode, n int){ if root == nil { return ; } if len(res) == n { res = append(res, []int{}) } res[n] = append(res[n], root.Val); depht(root.Left, n+1) depht(root.Right, n+1)}
调试完成没问题:
可是提交就:
(⊙_⊙)? 一下子就懵逼了,没输入,怎么有输出值,然后连续提交了几次, 一直被打脸。
LeetCode出现bug了?恰好又没人发现?
突然发现,返回的值是第一次测试的值。这个时候才注意到,LeetCode有可能是在一个程序里面,然后进行所有例子测试,而代码里面的var res[][]int ,又刚好声明在全局变量里面。所以代码就改为
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */var res[][]intfunc levelOrderBottom(root *TreeNode) [][]int { res = [][]int{}; depht(root, 0) l := len(res); end := l / 2; for i:=0; i < end ; i++{ res[i], res[l - i - 1] = res[l - i - 1], res[i] } return res;}func depht(root *TreeNode, n int){ if root == nil { return ; } if len(res) == n { res = append(res, []int{}) } res[n] = append(res[n], root.Val); depht(root.Left, n+1) depht(root.Right, n+1)}
这次小心翼翼的提交了
终于成功了。
原来LeetCode的测试用例都是在同一个程序里面执行,所以用到全局变量事,要记得清空