1 问题
给定一个节点数为 n 二叉树,要求从上到下按层打印二叉树的 val 值,同一层结点从左至右输出,每一层输出一行,将输出的结果存放到一个二维数组中返回。
例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树多行打印层序遍历的结果是
[
[1],
[2,3],
[4,5]
]
数据范围:二叉树的节点数 0≤n≤1000,0≤val≤1000
要求:空间复杂度 O(n),时间复杂度 O(n)
输入描述:给定一个二叉树的根节点
示例1
输入:{1,2,3,#,#,4,5}
返回值:[[1],[2,3],[4,5]]
示例2
输入:{8,6,10,5,7,9,11}
返回值:[[8],[6,10],[5,7,9,11]]
示例3
输入:{1,2,3,4,5}
返回值:[[1],[2,3],[4,5]]
示例4
输入:{}
返回值:[]
2 答案
自己写的,队列
class Solution:
def Print(self , pRoot: TreeNode) -> List[List[int]]:
if not pRoot:
return []
ls = []
ls.append(pRoot)
res = []
while ls:
level = []
for _ in range(len(ls)):
cur = ls.pop(0)
level.append(cur.val)
if cur.left: # 如果后面还会用到这个节点对象,就不要用.val
ls.append(cur.left)
if cur.right:
ls.append(cur.right)
if level:
res.append(level)
return res
官方解
- 非递归层次遍历,相同
题目要求将二叉树按行打印,即按层打印,其中每层分开。不难想到,要使用层次遍历,但是难点在于如何每层分开存储,从哪里知晓分开的时机?在层次遍历的时候,我们通常会借助队列(queue),事实上,队列中的值大有玄机,让我们一起来看看:
- 当根节点进入队列时,队列长度为1,第一层节点数也为1
- 若是根节点有两个子节点,push进队列后,队列长度为2,第二层节点数也为2;若是根节点一个子节点,push进队列后,队列长度为为1,第二层节点数也为1.
- 由此,我们可知,每层的节点数等于进入该层时队列长度,因为刚进入该层时,这一层每个节点都会push进队列,而上一层的节点都出去了。
综上,反过来,每次只要在队列长度内循环,必定是一层,一层访问完毕再更新队列长度即可。
具体做法:
- step 1:如果树为空,则返回空数组,没有任何打印结果。
- step 2:使用队列辅助层次遍历,优先加入二叉树的根节点。
- step 3:从根节点开始,每次进入一层的时候,记录队列的长度即本层的节点数,然后访问相应节点数全在同一个数组中,子节点加入队列中继续排队。
- step 4:每次访问完一层将数组加入二维数组中再进入下一层。
class Solution:
def Print(self , pRoot: TreeNode) -> List[List[int]]:
res = []
if pRoot is None:
#如果是空,则直接返回空数组
return res
#队列存储,进行层次遍历
q = [pRoot]
while q:
#记录二叉树的某一行
row = []
n = len(q)
#因先进入的是根节点,故每层节点多少,队列大小就是多少
for i in range(n):
#取出队首
node = q.pop(0)
row.append(node.val)
#若是左右孩子存在,则存入左右孩子作为下一个层次
if node.left:
#加入队尾
q.append(node.left)
if node.right:
q.append(node.right)
res.append(row)
return res
- 递归层次遍历
除了用队列非递归可以实现二叉树的层次遍历,我们也可以使用递归。但是递归前序遍历访问二叉树不是按照层次的顺序,但是因为“根左右”的次序,我们能保证每一层一定左边的元素先访问,后面再访问到同一层右边的元素。
要找到这个节点是第几层的,只是需要在函数中加入记录深度的变量,每往下一层深度加1,同时保存结果的数组正好对应每层一个数组,因此数字的大小正好是遍历的深度,由此可以实现递归。
- step 1:记录输出的二维数组初始化为空,每到一层里面填出一个一维数组。
- step 2:从根节点开始,深度为1开始进行递归,当前节点有值递归内容才继续进行,否则返回。
- step 3:如果记录输出的二维数组长度小于当前层数,说明要新到了一层,我们新开辟一个一维数组加到最后。
- step 4:因为“根左右”的顺序,同一层左边必定先访问,只需要根据层数在二维数组中找到相应的行号,添加在该行末尾就一定是层次遍历的次序。
class Solution:
def traverse(self, root: TreeNode, res: List[List[int]], depth: int):
if root:
if len(res) < depth:
res.append([])
res[depth - 1].append(root.val)
self.traverse(root.left, res, depth + 1)
self.traverse(root.right, res, depth + 1)
#层次遍历
def Print(self , pRoot: TreeNode) -> List[List[int]]:
res = []
#树的层级从1开始递归计数
#这样调用,res也是有改变的
self.traverse(pRoot, res, 1)
return res
https://www.nowcoder.com/share/jump/9318638301700994523042