Binary Tree Zigzag Level Order Traversal medium
Problem Statement
Given the root
of a binary tree, return the zigzag level order traversal of its nodes' values. (i.e., from left to right, then right to left for the next level and alternate between).
Example 1
Input: root = [3,9,20,null,null,15,7] Output: [[3],[20,9],[15,7]]
Example 2
Input: root = [1] Output: [[1]]
Steps
-
Initialization: Create an empty array
result
to store the zigzag traversal levels. Initialize a queuequeue
with the root node. Initialize a variablelevel
to 0 to track the current level. Initialize a boolean variableleftToRight
totrue
to indicate the traversal direction. -
Level Order Traversal: While the queue is not empty:
- Get the number of nodes
levelSize
at the current level. - Create an empty array
levelNodes
to store the nodes at the current level. - Iterate
levelSize
times:- Dequeue a node from the queue.
- If
leftToRight
istrue
, append the node's value tolevelNodes
. - Otherwise (if
leftToRight
isfalse
), prepend the node's value tolevelNodes
. - Enqueue the node's left and right children (if they exist).
- Append
levelNodes
to theresult
array. - Toggle
leftToRight
for the next level. - Increment
level
.
- Get the number of nodes
-
Return: Return the
result
array.
Explanation
The algorithm uses a level-order traversal (breadth-first search) to process the tree level by level. The leftToRight
flag controls the order in which nodes are added to the levelNodes
array for each level. By toggling this flag, we achieve the zigzag pattern. Using a queue ensures that we process nodes at each level before moving to the next. Prepending and appending to levelNodes
efficiently handles the direction change.
Code
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
function zigzagLevelOrder(root: TreeNode | null): number[][] {
if (!root) return [];
const result: number[][] = [];
const queue: TreeNode[] = [root];
let level = 0;
let leftToRight = true;
while (queue.length > 0) {
const levelSize = queue.length;
const levelNodes: number[] = [];
for (let i = 0; i < levelSize; i++) {
const node = queue.shift()!;
if (leftToRight) {
levelNodes.push(node.val);
} else {
levelNodes.unshift(node.val);
}
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
result.push(levelNodes);
leftToRight = !leftToRight;
level++;
}
return result;
}
Complexity
- Time Complexity: O(N), where N is the number of nodes in the tree. We visit each node once.
- Space Complexity: O(W), where W is the maximum width of the tree. In the worst case (a complete binary tree), W can be equal to N, but in general it's less than N. The space is used by the queue.