LeetCode:102. Binary Tree Level Order Traversal

本文介绍了一种解决LeetCode上二叉树层次遍历问题的方法。通过使用辅助队列来保存每一层的元素,每次从队首出队的元素将其左右子节点入队,直至所有节点遍历完成。

LeetCode:102. Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
return its level order traversal as:
[
  [3],
  [9,20],
  [15,7]
]

二叉树的层次遍历。

思路:辅助队列

用一个辅助队列保存每一层的元素,每次从队首出队的元素将它的左右子节点入队。直到所有的节点遍历完成。

Python 实现代码

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

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = []
        if (root != None):
            queue = []
            queue.append(root)
            while(len(queue) > 0):
                item = []
                tmp = []
                while(len(queue) > 0):
                    x = queue.pop(0)
                    if(x.left != None):
                        tmp.append(x.left)
                    if(x.right != None):
                        tmp.append(x.right)
                    item.append(x.val)
                res.append(item)
                queue = tmp
                
        return res

THE END.

<think>我们有一个二叉树,需要实现层序遍历,即按层次从上到下,从左到右访问每个节点,并将每层的节点值分别存储在一个列表中,最终返回一个二维列表。 代码分析如下: 1. 导入:代码中使用了`deque`,它是`collections`模块中的双端队列,用于高效地执行队列操作(popleft和append)。 2. 类定义:题目给出了二叉树的节点定义(注释部分),每个节点有值、左子节点和右子节点。 3. 方法`levelOrder`: - 输入:二叉树的根节点`root`,类型为`Optional[TreeNode]`(即可能是`TreeNode`或`None`)。 - 输出:一个二维列表,每个子列表表示一层的节点值。 4. 具体步骤: a. 首先判断根节点是否为空,如果为空,直接返回空列表`[]`。 b. 初始化一个空列表`ans`用于存储结果。 c. 初始化一个队列`q`(使用`deque`),并将根节点加入队列。 d. 开始循环,条件是队列不为空: - 在每一层开始前,初始化一个空列表`vals`用于存储当前层的节点值。 - 使用一个内层循环,循环次数为当前队列的长度(即当前层的节点数): * 从队列左侧弹出一个节点`node`。 * 将`node`的值`val`添加到`vals`中。 * 如果该节点有左子节点,将左子节点加入队列。 * 如果该节点有右子节点,将右子节点加入队列。 - 内层循环结束后,当前层的所有节点值已经存储在`vals`中,将`vals`添加到`ans`中。 e. 当队列为空时,所有层遍历完毕,返回`ans`。 5. 关键点: - 使用队列实现广度优先搜索(BFS)。 - 内层循环的次数是当前层的节点数(即一开始队列的长度),这样能确保每次内层循环处理完一层。 - 在处理当前层节点的同时,将下一层的节点按顺序加入队列。 6. 示例: 考虑二叉树: 3 / \ 9 20 / \ 15 7 步骤: 初始:q = [3] 第一层:处理节点3,vals=[3],然后将9和20加入队列,q=[9,20] -> ans=[[3]] 第二层:处理节点9(弹出9,vals=[9];然后处理20,vals=[9,20]),将20的左子节点15和右子节点7加入队列,q=[15,7] -> ans=[[3],[9,20]] 第三层:处理节点15(vals=[15])和节点7(vals=[15,7]),没有子节点,q变为空 -> ans=[[3],[9,20],[15,7]] 7. 时间复杂度:O(n),其中n是节点个数,每个节点恰好被访问一次。 8. 空间复杂度:O(n),队列中元素个数最多为n(最坏情况,即最后一层的节点数)。 这个算法是标准的BFS层序遍历。 相关问题: §§相关问题§§: 1. 如果要求按层序遍历的顺序,但是要求从下到上输出每一层(即自底向上),如何修改代码? 2. 如何实现锯齿形层序遍历(即先从左到右,再从右到左,交替进行)? 3. 除了使用队列,还可以用哪些方法实现二叉树的层序遍历? 4. 如何只使用一个循环(不使用内层循环)实现层序遍历?这样做的缺点是什么?</think># 二叉树层序遍历(LeetCode 102)代码分析 ## 代码功能 这段代码实现了二叉树的**层序遍历**(Level Order Traversal),即逐层从左到右访问所有节点,并将每层的节点值存储在一个单独的列表中,最终返回二维列表。 ## 逐行代码分析 ```python from collections import deque # 导入双端队列用于高效实现队列操作 class Solution: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: # 边界条件处理:空树直接返回空列表 if root is None: return [] ans = [] # 存储最终结果的二维列表 q = deque([root]) # 初始化队列,将根节点加入队列 # 主循环:当队列不为空时继续处理 while q: vals = [] # 存储当前层的节点值 # 关键点:处理当前层的所有节点 for _ in range(len(q)): # 当前层的节点数量 node = q.popleft() # 从队列左侧取出节点(先进先出) vals.append(node.val) # 将节点值加入当前层列表 # 将子节点加入队列(下一层节点) if node.left: q.append(node.left) if node.right: q.append(node.right) # 将当前层的结果加入最终结果 ans.append(vals) return ans # 返回层序遍历结果 ``` ## 关键算法原理:广度优先搜索(BFS) 1. **队列的作用**: - 使用双端队列(`deque`)实现先进先出(FIFO)的队列 - 确保节点按层级顺序处理(先处理上层节点,再处理下层节点) 2. **核心循环逻辑**: ```python for _ in range(len(q)): # 当前层的节点数量 ``` - **关键技巧**:在开始处理当前层前,队列长度即为当前层的节点数 - 通过固定循环次数,确保每次只处理一层节点 3. **处理流程**: - 从队列取出节点 → 记录节点值 → 将子节点加入队列 - 完美实现层级递进:处理当前层时,同时准备下一层节点 ## 时间复杂度与空间复杂度 - **时间复杂度**:O(n) - 每个节点恰好入队和出队各一次 - 每个节点只被访问一次 - **空间复杂度**:O(n) - 队列最大空间需求为最宽层的节点数 - 最坏情况(完美二叉树)最后一层有 ⌈n/2⌉ 个节点 ## 示例执行流程 假设二叉树结构: ``` 3 / \ 9 20 / \ 15 7 ``` 执行步骤: 1. 初始队列:`[3]` 2. 处理第1层:vals=[3] → ans=[[3]] - 加入子节点后队列:`[9, 20]` 3. 处理第2层:vals=[9,20] → ans=[[3],[9,20]] - 加入子节点后队列:`[15,7]` 4. 处理第3层:vals=[15,7] → ans=[[3],[9,20],[15,7]] 5. 返回结果:`[[3],[9,20],[15,7]]` ## 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值