【Python实战】LeetCode102:二叉树的层序遍历

题目描述

在这里插入图片描述
如何遍历一棵树,通用的两种策略是:深度优先搜索和广度优先搜索。

解法一:广度优先搜索 BFS

这道题最容易想到的最法就是 BFS了,因为 BFS的定义本身就很类似按层遍历的思路,只不过对于这题目我们要注意的是,最后返回的是一个二维数组,每个子数组存放每一层的所有节点,因为我们在 BFS的遍历过程中要记下当前节点属于哪一层,从而存放到对应的子数组中。

BFS一般采用的数据结构是队列,但是 Python 中的 Queue 结构是为多线程之间安全交换而设计的,所以使用了锁,会导致性能不佳。下面借助的是 Python标准库 collections中提供的双端队列 deque 模块,它提供了两端都可以操作的序列。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        #---广度优先搜索---
        if not root: return [] # 如果树为空,返回空

        from collections import deque
        q = deque()  # 申请一个双端队列
        q.append(root) # 加入根节点,从根节点开始按层遍历

        res = []

        while q:
            level_size = len(q) # 获取当前层的节点个数
            current_level = [] # 新建一个 list,存放当前层遍历到的节点
            # for循环中,队列只弹出当前层的节点,下一层的节点若不为空会入队,但不在当前循环中弹出
            for _ in range(level_size):
                node = q.popleft() # 每次从队列的左边弹出节点
                current_level.append(node.val)
                if node.left: # 如果节点的左孩子不为空就入队
                    q.append(node.left)
                if node.right: # 如果节点的右孩子不为空就从入队
                    q.append(node.right)
            res.append(current_level)

        return res # 最后返回一个二维数组

实际上,也可以不必用到双端队列,借助 Python中最简单的 list 也可以实现一个普通的队列,只要保证其先入先出的特性即可。

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:return []
        queue = []
        queue.append(root)
        res = []

        while queue:
            level_size = len(queue)
            current_level = []
            while level_size:
                node = queue.pop(0) # 每次从最左边弹出节点
                current_level.append(node.val)
                if node.left: queue.append(node.left) # 每次节点是从右边入队
                if node.right: queue.append(node.right)
                level_size -= 1
            res.append(current_level)
        
        return res

解法二:深度优先搜索 DFS

DFS 的实现上一般就要借助递归了,因此我们需要定义一个递归函数。

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root: return []
        res = [] # 注意:由于res是二维数组,len(res)实际上就等于当前遍历过的最高层数

        # 定义递归函数
        def helper(node, level):
            if len(res) <= level: # 若当前访问的节点所在的层次超过了当前最高层次,就向 res中添加一个空列表。
                res.append([])
            res[level].append(node.val) # 将当前节点插入到对应层的列表 res[level]中。
            if node.left:
                helper(node.left, level+1) # 递归遍历左孩子
            if node.right:
                helper(node.right, level+1) # 递归遍历右孩子

        helper(root, 0) # 调用递归,初始传入根节点和第0层
        return res

另一种写法

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root: return []
        self.res = []
        self.dfs(root, 0) # 从根节点开始,层数为0
        return self.res

    def dfs(self, node, level):
        if len(self.res) <= level: # 若当前节点所在的层次超过了当前最高层次,就向 res中添加一个空列表。
            self.res.append([])
        self.res[level].append(node.val) # 将当前节点插入到对应层的列表 res[level]中。
        # 递归遍历孩子节点
        if node.left:
            self.dfs(node.left, level+1)
        if node.right:
            self.dfs(node.right, level+1)

最后,如果大家有更好的Python解法,欢迎在评论区分享下您的解法,一起进步,感谢^ o ^~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值