Zigzag Level Order Traversal in DSA Javascript - Time & Space Complexity
We want to understand how the time needed grows when we do a zigzag level order traversal of a tree.
How does the number of steps change as the tree gets bigger?
Analyze the time complexity of the following code snippet.
function zigzagLevelOrder(root) {
if (!root) return [];
const result = [];
const queue = [root];
let leftToRight = true;
while (queue.length) {
const levelSize = queue.length;
const levelNodes = [];
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;
}
return result;
}
This code visits each node level by level, switching direction each level to create a zigzag pattern.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop runs once per tree level, and inside it, the for loop visits every node at that level.
- How many times: Every node in the tree is visited exactly once by the inner for loop.
As the number of nodes (n) grows, the code visits each node once, so the total steps grow roughly in direct proportion to n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The number of operations grows linearly with the number of nodes.
Time Complexity: O(n)
This means the time needed grows directly with the number of nodes in the tree.
[X] Wrong: "Because we use unshift inside the loop, the time complexity becomes quadratic O(n²)."
[OK] Correct: Although unshift can be costly, it is done only for nodes at each level, and since each node is processed once, the total work remains proportional to n.
Understanding this traversal's time complexity helps you explain how tree traversals work efficiently, a common topic in interviews.
"What if we replaced the array used for levelNodes with a deque to avoid unshift? How would the time complexity change?"
Practice
Solution
Step 1: Understand normal level order traversal
Normal level order traversal visits nodes level by level from left to right.Step 2: Understand zigzag traversal difference
Zigzag traversal alternates direction: left to right on one level, then right to left on the next, and so on.Final Answer:
Zigzag traversal alternates the direction of node visits at each level. -> Option BQuick Check:
Zigzag = alternate directions [OK]
- Thinking zigzag skips levels
- Assuming zigzag always reverses order
- Confusing zigzag with normal level order
Solution
Step 1: Identify correct queue initialization in JavaScript
JavaScript arrays can be used as queues with push and shift methods.Step 2: Check each option
const queue = []; queue.push(root); uses an array and push method correctly. Options B, C, and D use incorrect data structures or methods for queue behavior.Final Answer:
const queue = []; queue.push(root); -> Option CQuick Check:
Array with push = queue [OK]
- Using Set or Map instead of array for queue
- Using non-existent enqueue method
- Initializing queue as an object
1 / \ 2 3 / \ \ 4 5 6
Solution
Step 1: Traverse level 0 left to right
Level 0 nodes: [1]Step 2: Traverse level 1 right to left
Level 1 nodes: [2, 3] reversed to [3, 2]Step 3: Traverse level 2 left to right
Level 2 nodes: [4, 5, 6]Final Answer:
[[1], [3, 2], [4, 5, 6]] -> Option AQuick Check:
Zigzag levels alternate direction [OK]
- Not reversing the order on odd levels
- Reversing all levels
- Mixing node values order
while(queue.length) {
let levelSize = queue.length;
let levelNodes = [];
for(let i = 0; i < levelSize; i++) {
let node = queue.shift();
levelNodes.push(node.val);
if(node.left) queue.push(node.left);
if(node.right) queue.push(node.right);
}
if(reverse) levelNodes.reverse();
result.push(levelNodes);
reverse = !reverse;
}
What is the bug in this code?Solution
Step 1: Check variable initialization
The variable 'reverse' is used but not declared or initialized before the loop, causing a ReferenceError.Step 2: Verify other code parts
queue.shift() is valid for arrays, reversing after collecting nodes is correct, and pushing children before reversing is standard.Final Answer:
The variable 'reverse' is not initialized before the loop. -> Option AQuick Check:
Uninitialized variable 'reverse' causes error [OK]
- Assuming shift() is invalid
- Reversing nodes before collecting children
- Pushing children after reversing level nodes
Solution
Step 1: Understand reversing avoidance
Reversing arrays costs extra time and space; using two stacks can avoid this by controlling push order.Step 2: Analyze options
Use two stacks, one for current level and one for next level, alternating push order. uses two stacks and alternates push order to get zigzag without reversing. Use a deque and insert nodes at front or back depending on direction. needs a deque which is not native in JS. Use a queue and reverse the entire result array at the end. reverses at the end, not avoiding reversing. Use recursion and collect nodes in normal order only. does not handle zigzag properly.Final Answer:
Use two stacks, one for current level and one for next level, alternating push order. -> Option DQuick Check:
Two stacks alternate push order = no reverse [OK]
- Using queue and reversing result at end
- Trying recursion without direction control
- Assuming deque is native in JavaScript
Ready to prove it?
Pass the test and this pattern moves unknown
