Lesson 102 of 164
Binary Tree Zigzag Level Order Traversal
Given a binary tree, return its values level by level. The first level is read left to right, the next right to left, and so on, alternating.
LeetCode: 103. Binary Tree Zigzag Level Order Traversal
Example
3
/ \
9 20 Output: [[3], [20, 9], [15, 7]]
/ \
15 7
1
/ \
2 3 Output: [[1], [3, 2], [4, 5, 6, 7]]
/ \ / \
4 5 6 7Level order, reversing every other level
Run a normal breadth-first traversal one level at a time, and reverse the odd-numbered levels before saving them. ArrayDeque is Java's array-backed double-ended queue: add appends at the back and poll removes from the front. A tree node is an object with left and right references, and an empty subtree is null.
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
public class Main {
static class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
static TreeNode leaf(int val) {
return new TreeNode(val, null, null);
}
static List<List<Integer>> zigzag(TreeNode root) {
List<List<Integer>> levels = new ArrayList<>();
if (root == null) return levels;
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
TreeNode n = queue.poll();
level.add(n.val);
if (n.left != null) queue.add(n.left);
if (n.right != null) queue.add(n.right);
}
if (levels.size() % 2 == 1) {
Collections.reverse(level);
}
levels.add(level);
}
return levels;
}
public static void main(String[] args) {
System.out.println(zigzag(new TreeNode(3, leaf(9), new TreeNode(20, leaf(15), leaf(7)))));
System.out.println(zigzag(new TreeNode(1,
new TreeNode(2, leaf(4), leaf(5)),
new TreeNode(3, leaf(6), leaf(7)))));
}
}[[3], [20, 9], [15, 7]]
[[1], [3, 2], [4, 5, 6, 7]]Time: O(n): every node is visited once, and the reversals touch each value once more. Space: O(w) for the widest level.
Two stacks
A stack reverses the order of whatever is pushed onto it. Pop the current level from one stack, and push the children onto the other. ArrayDeque also serves as the stack: push and pop work on the front, so the last value pushed is the first popped.
- On a left-to-right level, push each node's left child, then its right child. The next level pops right to left.
- On a right-to-left level, push the right child first, then the left. The next level pops left to right.
The zigzag order comes out directly, with no reversing.
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
public class Main {
static class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
static TreeNode leaf(int val) {
return new TreeNode(val, null, null);
}
static List<List<Integer>> zigzag(TreeNode root) {
List<List<Integer>> levels = new ArrayList<>();
if (root == null) return levels;
Deque<TreeNode> current = new ArrayDeque<>();
current.push(root);
boolean leftToRight = true;
while (!current.isEmpty()) {
Deque<TreeNode> next = new ArrayDeque<>();
List<Integer> level = new ArrayList<>(current.size());
while (!current.isEmpty()) {
TreeNode n = current.pop();
level.add(n.val);
TreeNode first = leftToRight ? n.left : n.right;
TreeNode second = leftToRight ? n.right : n.left;
if (first != null) next.push(first);
if (second != null) next.push(second);
}
levels.add(level);
current = next;
leftToRight = !leftToRight;
}
return levels;
}
public static void main(String[] args) {
System.out.println(zigzag(new TreeNode(3, leaf(9), new TreeNode(20, leaf(15), leaf(7)))));
System.out.println(zigzag(new TreeNode(1,
new TreeNode(2, leaf(4), leaf(5)),
new TreeNode(3, leaf(6), leaf(7)))));
System.out.println(zigzag(null));
}
}[[3], [20, 9], [15, 7]]
[[1], [3, 2], [4, 5, 6, 7]]
[]Time: O(n). Space: O(w).
Both approaches have the same complexity. The two-stack version saves the reversal work and shows why the order alternates; the BFS version is easier to get right in an interview.
Edge cases
- Empty tree: an empty list.
- Skewed tree: one node per level, so the direction doesn't matter.
