这道题要求在普通层序遍历的基础上,加上一点"小花样":每一层的遍历方向要左右交替,因此也叫"之字形 / 锯齿形层序遍历"。
题目描述
给定一棵二叉树的根节点 root,返回其节点值的锯齿形层序遍历结果。
具体要求是:第一层从左到右,第二层从右到左,第三层再从左到右,如此交替进行。
示例 1:root = [3,9,20,null,null,15,7],输出 [[3],[20,9],[15,7]]。
示例 2:root = [1],输出 [[1]]。leetcode
示例 3:root = [],输出 []。leetcode
约束条件:
- 节点数量在 [0,2000] 范围内。
- 每个节点的取值范围为 [-100,100]。
思路分析
这道题的核心仍然是层序遍历 = BFS + 队列,只是在收集每一层结果时,需要根据当前层数的奇偶决定插入方向。
常见有两种写法,你的代码大概率是落在这两类之一:
写法一:正常按从左到右收集一层,然后在偶数层对当前层的数组做一次 reverse(时间稍差一点,但实现非常直观)。
写法二:不做 reverse,而是根据层数奇偶决定往当前层数组的尾部 push 还是头部 insert/unshift,一次遍历就得到目标顺序(时间、空间都比较漂亮)。
整体流程可以概括为:
- 如果根节点为空,直接返回空数组。
- 使用队列进行 BFS,把根节点入队。
- 维护一个布尔变量或层计数,用来表示当前层是"从左到右"还是"从右到左"。
- 对队列中当前层的所有节点:
- 依次弹出节点,加入当前层数组;
- 把它的左右孩子(如果存在)入队。
- 将当前层数组按方向处理后加入结果,并翻转方向标记,进入下一层。
与普通层序遍历的对比
| 特性 | 普通层序遍历(102)csdn | 锯齿形层序遍历(103) |
|---|---|---|
| 遍历顺序 | 每层都从左到右 | 奇数层左到右,偶数层右到左交替 |
| 使用的数据结构 | 队列(BFS)programmercarl | 队列 + 方向标记 / 双端结构 |
| 结果处理 | 直接按访问顺序加入 | 需要按层数奇偶翻转或前插 |
可以看到,本题本质还是层序遍历,只是多了一个"按层控制方向"的逻辑,相当于在模板题 102 的基础上稍作改动。
代码实现(替换成你的提交)
这一节请粘贴你在 LeetCode 上通过的代码,并简单标注关键步骤,比如:
- 如何维护队列;
- 如何判断当前层数奇偶;
- 在什么位置决定是 push 还是"从头插入 / reverse"。
示例结构(伪代码示意,仅用于说明结构,不要照抄源码):
text
// 在这里粘贴你的代码
// 关键逻辑说明:
// 1. 使用 queue 做 BFS
// 2. 用 level / flag 控制方向
// 3. 根据方向决定插入顺序(或最后 reverse)
复杂度分析
- 时间复杂度:每个节点仅进队、出队一次,除此只是少量数组操作,整体为 O(n)。
- 空间复杂度:队列在最宽的一层时最多容纳 O(n) 个节点,结果数组也为 O(n),整体为 O(n)。
小结与扩展
掌握本题之后,可以一并复习 102(普通层序遍历)和 107(自底向上的层序遍历),三题的写法高度相似,只是"结果如何组织"不同。
实战中,看到"按层""从上到下/从左到右/交替方向"这类关键词时,优先考虑 BFS + 队列,再在结果数组上做文章即可。
https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/