算法思想:
这段代码实现了 二叉树的锯齿形层序遍历,其核心思想是基于广度优先搜索(BFS)进行层序遍历,并根据当前层数决定从左到右或从右到左的顺序来组织每一层的节点值。
level.add
和 level.addFirst
有点类似单链表的头插法和尾插法
详细步骤:
-
树节点定义:
定义了一个TreeNode
类来表示二叉树的节点,每个节点包含:val
:节点的值left
:左子节点right
:右子节点
-
主算法逻辑:
- 定义了一个
zigzagLevelOrder
方法,用来执行锯齿形层序遍历。 - 输入:二叉树的根节点
root
。 - 输出:一个嵌套的列表
List<List<Integer>>
,表示每一层的节点值,按照锯齿形排列。
- 定义了一个
-
初始化:
- 如果
root
为空,直接返回空列表。 - 创建一个
Queue
(队列)用来辅助进行层序遍历,并将根节点入队。 - 定义一个布尔变量
leftToRight
,初始为true
,用来表示当前层是否按从左到右的顺序进行。
- 如果
-
按层遍历(循环处理每一层):
- 在队列不为空的情况下,每次处理一整层的节点:
- 获取当前层的节点数
size
(队列长度)。 - 创建一个
LinkedList
来存储当前层的节点值。 - 遍历当前层的所有节点:
- 从队列中取出节点。
- 如果是从左到右(
leftToRight
为true
),直接将节点值追加到列表末尾。 - 如果是从右到左,将节点值插入到列表头部(通过
addFirst
方法实现)。 - 将当前节点的左右子节点(如果存在)加入队列,供下一层遍历使用。
- 获取当前层的节点数
- 将当前层的列表加入最终结果
result
。 - 翻转布尔变量
leftToRight
,切换到下一层的遍历顺序。
- 在队列不为空的情况下,每次处理一整层的节点:
-
返回结果:
- 最后返回
result
,包含每一层的节点值。
- 最后返回
核心优化点:
- 锯齿形插入:
- 通过
LinkedList
的add
和addFirst
方法灵活控制节点值的插入顺序,而无需额外对结果进行反转操作。
- 通过
- 层序遍历的 BFS 实现:
- 利用队列实现按层处理,每一层结束后通过
leftToRight
切换方向,确保按照锯齿形顺序遍历。
- 利用队列实现按层处理,每一层结束后通过
算法复杂度分析:
-
时间复杂度:
- 每个节点被访问一次,且每次访问操作的插入复杂度为 (O(1)) 或 (O(1))(在
LinkedList
的头部或尾部操作)。 - 总时间复杂度为 (O(N)),其中 (N) 是二叉树的节点数。
- 每个节点被访问一次,且每次访问操作的插入复杂度为 (O(1)) 或 (O(1))(在
-
空间复杂度:
- 主要由队列的存储和结果列表
result
决定。 - 在最坏情况下(例如完全二叉树的最后一层),队列可能需要存储 (O(N)) 个节点。
- 空间复杂度为 (O(N))。
- 主要由队列的存储和结果列表
示例运行过程(输入示例中的树):
输入树结构:
3/ \9 20/ \15 7
第1层:
queue
初始包含根节点[3]
。leftToRight = true
,从左到右读取当前层:- 输出
[3]
。
- 输出
- 下一层加入节点
[9, 20]
。 - 切换方向:
leftToRight = false
。
第2层:
queue
包含[9, 20]
。leftToRight = false
,从右到左读取当前层:- 输出
[20, 9]
。
- 输出
- 下一层加入节点
[15, 7]
。 - 切换方向:
leftToRight = true
。
第3层:
queue
包含[15, 7]
。leftToRight = true
,从左到右读取当前层:- 输出
[15, 7]
。
- 输出
最终结果为 [[3], [20, 9], [15, 7]]
。
如果有其他问题或需要进一步优化解释,请随时告诉我!
java 实现
class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {List<List<Integer>> result = new ArrayList<>();if(root == null) return result;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);boolean lefttoright = true;while(!queue.isEmpty()) {int levelsize = queue.size();// level 用于存放每层的遍历结果LinkedList<Integer> level = new LinkedList<>();for(int i = 0; i < levelsize; i++) {TreeNode node = queue.poll();if(lefttoright) {level.add(node.val);} else {level.addFirst(node.val);}if(node.left != null) {queue.offer(node.left);}if(node.right != null) {queue.offer(node.right);}}lefttoright = !lefttoright;result.add(level);}return result;}
}