SWE · Coding

Meta 树的层序遍历:队列分层与固定层宽

用队列按深度组织二叉树节点,解释层边界、宽度空间和空树行为。

题目重点:用队列按深度组织二叉树节点,解释层边界、宽度空间和空树行为。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 练习输入是真正的二叉树,节点字段value/left/right,返回每层值列表,根为第0层,同层从左到右。输入无环、无共享子节点。
  • 题目所问层序遍历可以辨识;同次出现的Path Sum未说明路径端点、目标或输出类型,不能用本题补全它。

解题路线

  1. 将根放入queue。每轮开始把当前len(queue)作为本层固定处理次数;弹出节点加入本层,依次把左、右孩子放到队尾。
  2. 层开始时queue恰好包含当前深度节点。处理完固定次数后,队列仅剩下一层节点;由归纳可知每个节点被放入正确层且左右顺序稳定。
  3. 不能把处理次数写成随孩子入队而变化的while len(queue),否则新层也在当前层被消费。Python range(len(queue))在创建时固定次数,符合本层快照。
  4. DFS按depth分组也可完成同一输出,但递归栈由高度决定;BFS更直观呈现层边界。若输入改成图,必须定义去重与最短深度,再加visited。

手动走一遍

根1,左2右3,2仅有右孩子4,结果[[1],[2,3],[4]]。None返回[];单节点返回[[value]]。所有节点同值仍保留全部节点。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from collections import deque

def level_order(root):
    """Binary tree, root depth0; return value lists per level, left-before-right."""
    if root is None:return []
    queue=deque([root]);result=[]
    while queue:
        level=[]
        for _ in range(len(queue)):
            node=queue.popleft();level.append(node.value)
            if node.left is not None:queue.append(node.left)
            if node.right is not None:queue.append(node.right)
        result.append(level)
    return result

复杂度

O(N)时间;队列O(B)空间,B为最大层宽,处理中可能同时含本层剩余和下一层部分,仍O(B)。返回结果O(N)额外空间;退化链队列O(1),满树最后层可能Θ(N)。

易错点与追问

容易失分的边界

  • 队列长度动态增长时继续当前层循环。
  • 把树高O(H)误当BFS队列空间。
  • 以value作visited标识,错误合并同值节点。

继续深挖

  • 若只需要每层平均值,可在层内累计sum/count,减少返回结果但保留队列。
  • 若需要从底层向上返回,保留分层结果后逆序;zigzag按层号改变结果顺序,不必改变节点扩展规则。
✓已复制微信号!