题目重点:用队列按深度组织二叉树节点,解释层边界、宽度空间和空树行为。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 练习输入是真正的二叉树,节点字段value/left/right,返回每层值列表,根为第0层,同层从左到右。输入无环、无共享子节点。
- 题目所问层序遍历可以辨识;同次出现的Path Sum未说明路径端点、目标或输出类型,不能用本题补全它。
解题路线
- 将根放入queue。每轮开始把当前len(queue)作为本层固定处理次数;弹出节点加入本层,依次把左、右孩子放到队尾。
- 层开始时queue恰好包含当前深度节点。处理完固定次数后,队列仅剩下一层节点;由归纳可知每个节点被放入正确层且左右顺序稳定。
- 不能把处理次数写成随孩子入队而变化的while len(queue),否则新层也在当前层被消费。Python range(len(queue))在创建时固定次数,符合本层快照。
- 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按层号改变结果顺序,不必改变节点扩展规则。
