1:问题描述
来源:LeetCode
难度:简单
问题详情:
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回:
[
[3],
[9,20],
[15,7]
]
2:问题分析
2.1 时间复杂度和空间复杂度
在真正开始介绍各种算法前,先以表格形式展示各自的时间复杂度和空间复杂度,其中 N N N表示二叉树的节点数。
算法 | 时间复杂度 | 空间复杂度 |
---|---|---|
栈 | O ( N ) O(N) O(N) | O ( N ) O(N) O(N) |
2.2 栈
2.2.1 方法解释
题目中的按层遍历二叉树中的节点,其实就是 广度优先搜索(Breadth First Search,BFS),BFS 通常借助 队列 的先入先出特性来实现。
一般的BFS流程如下:
- 首先将根节点加入队列
- 然后进入循环
- 将当前队列的队首节点弹出,并将该节点的值添加至列表中
- 然后将该节点的左右节点(如果存在的话)添加至队尾
- 直至队列为空退出循环
然而以如下二叉树为例:
3
/ \
9 20
/ \
15 7
上述的流程返回的结果只能是[3,9,20,15,7]
,(这也是剑指 Offer 32 - I. 从上到下打印二叉树的解法).
要想做到给出的每一层用一个列表存储的效果,那就需要将每一层的节点中输出到一个临时列表中,然后等这一层节点遍历完成,再将这个临时列表添加至大列表中。
2.2.2 代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
from collections import deque
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
q = deque()
result_list = []
q.append(root)
while q:
row_tmp = []
# q的长度表示该层有多少节点,因为每遍历一层,当前节点就被弹出队列,而其左右节点就会被添加至队列中,因此当前q中的元素数量就是这一次层遍历的次数
for _ in range(len(q)):
node = q.popleft()
row_tmp.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
result_list.append(row_tmp)
return result_list
复杂度分析:
时间复杂度 O ( N ) O(N) O(N): N N N为二叉树的节点数量,即 BFS 需循环 N N N次。
空间复杂度 O ( N ) O(N) O(N): 最差情况下,即当树为平衡二叉树时,最多有 N / 2 N/2 N/2个树节点同时在 队列q
中,使用 O ( N ) O(N) O(N) 大小的额外空间。
注:
Python 中使用 collections
中的双端队列 deque()
,其 popleft()
方法可达到 O ( 1 ) O(1) O(1) 时间复杂度;列表 list
的 pop(0)
方法需要将后续元素向前平移一位,因此时间复杂度为 O ( N ) O(N) O(N)。