剑指 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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

little student

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值