1. 问题描述
给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
2. 解题思路
3
/ \
9 20
/ \
15 7
规定二叉树的根节点所在层为第 0 层:
若当前层为偶数层,则从左到右输出当前层的节点值;
若当前层为奇数层,则从右到左输出当前层的节点值。
使用 BFS,对树进行逐层遍历,用队列 q 维护当前层的所有节点,当队列 q 不为空时,先记录当前队列的长度 size,每次从队列中取出 size 个节点进行拓展,然后进行下一次迭代。
⭐使用双端队列
来维护当前层节点值的输出顺序
在广度优先搜索遍历当前层节点拓展下一层节点的时候,仍然从左往右按顺序拓展,但是对于当前层节点值的存储,考虑维护一个变量 isOrderLeft 记录是否按照从左往右的顺序。
如果从左往右,每次将遍历到的元素插入双端队列的末尾;
如果从右往左,每次将遍历到的元素插入双端队列的头部。
3. 代码实现
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution103 {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
// 双端队列
Deque<TreeNode> q = new LinkedList<>();
q.offer(root);
boolean isOrderLeft = true;
while (!q.isEmpty()) {
// 记录当前层节点的值
List<Integer> levelList = new ArrayList<>();
int size = q.size();
for (int i = 0; i < size; i++) {
// 从左往右
if (isOrderLeft) {
TreeNode t = q.removeFirst();
levelList.add(t.val);
if (t.left != null) {
q.addLast(t.left);
}
if (t.right != null) {
q.addLast(t.right);
}
} else { // 从右往左
TreeNode t = q.removeLast();
levelList.add(t.val);
if (t.right != null) {
q.addFirst(t.right);
}
if (t.left != null) {
q.addFirst(t.left);
}
}
}
isOrderLeft = !isOrderLeft;
res.add(levelList);
}
return res;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(3);
TreeNode node2 = new TreeNode(9);
TreeNode node3 = new TreeNode(20);
TreeNode node4 = new TreeNode(15);
TreeNode node5 = new TreeNode(17);
root.left = node2;
root.right = node3;
node3.left = node4;
node3.right = node5;
Solution103 solution103 = new Solution103();
System.out.println(solution103.zigzagLevelOrder(root));
}
}
[[3], [20, 9], [15, 17]]