剑指 Offer 32 - II. 从上到下打印二叉树 II(Python3解法)

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) 时间复杂度;列表 listpop(0) 方法需要将后续元素向前平移一位,因此时间复杂度为 O ( N ) O(N) O(N)

猜你喜欢

转载自blog.csdn.net/weixin_43490422/article/details/126832261