Vertical Order Traversal of Binary Tree in DSA Rust - Time & Space Complexity
We want to understand how the time needed grows when we do a vertical order traversal of a binary tree.
Specifically, how the number of nodes affects the work done to group nodes by their vertical columns.
Analyze the time complexity of the following code snippet.
use std::collections::{BTreeMap, VecDeque};
fn vertical_order(root: Option<&Box>) -> Vec> {
let mut map: BTreeMap> = BTreeMap::new();
let mut queue: VecDeque<(&Box, i32)> = VecDeque::new();
if let Some(node) = root {
queue.push_back((node, 0));
}
while let Some((node, col)) = queue.pop_front() {
map.entry(col).or_default().push(node.val);
if let Some(left) = &node.left {
queue.push_back((left, col - 1));
}
if let Some(right) = &node.right {
queue.push_back((right, col + 1));
}
}
map.values().cloned().collect()
}
This code visits each node in the tree once, grouping node values by their vertical column index.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that visits each node once.
- How many times: Exactly once per node, so n times for n nodes.
As the number of nodes grows, the code visits each node once and adds its value to a map.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits and insertions |
| 100 | About 100 visits and insertions |
| 1000 | About 1000 visits and insertions |
Pattern observation: The work grows linearly with the number of nodes.
Time Complexity: O(n log k)
This means the time grows a bit more than linearly because inserting into the map takes extra time, but overall it scales well with the number of nodes.
[X] Wrong: "The traversal is just O(n) because we visit each node once, so no extra cost."
[OK] Correct: While visiting nodes is O(n), inserting into a sorted map (BTreeMap) takes O(log k) per insertion, making total time O(n log k), where k is the number of distinct columns.
Understanding this complexity helps you explain how tree traversals combined with data structures affect performance, a common topic in interviews.
What if we used a hash map instead of a BTreeMap for grouping columns? How would the time complexity change?
Practice
Solution
Step 1: Understand vertical order traversal
Vertical order traversal groups nodes by their vertical position (column) relative to the root.Step 2: Compare with other traversals
Unlike level order or inorder, vertical order focuses on columns from left to right.Final Answer:
Nodes are grouped by their vertical columns from left to right -> Option AQuick Check:
Vertical order = group by vertical columns [OK]
- Confusing vertical order with level order traversal
- Thinking vertical order is preorder or inorder
- Ignoring horizontal distance from root
Solution
Step 1: Identify grouping need
We need to group nodes by their vertical column index (an integer key).Step 2: Choose suitable Rust structure
HashMap maps column indices to lists of node values, perfect for grouping.Final Answer:
HashMap -> Option BQuick Check:
Use HashMap for key-value grouping [OK]
- Using Vec alone without keys
- Using BinaryHeap which is for priority queues
- Using LinkedList which is inefficient here
1
/ \
2 3
/ \
4 5
What is the vertical order traversal output?Solution
Step 1: Assign vertical columns
Root 1 is column 0; left child 2 is -1; left child of 2 (4) is -2; right child 3 is +1; right child of 3 (5) is +2.Step 2: Group nodes by columns
Column -2: [4], -1: [2], 0: [1], 1: [3], 2: [5].Final Answer:
[[4], [2], [1], [3], [5]] -> Option AQuick Check:
Group nodes by horizontal distance [OK]
- Mixing vertical order with level order
- Grouping nodes incorrectly by level
- Ignoring negative column indices
fn vertical_order(root: Option) -> Vec {
let mut map = std::collections::HashMap::new();
fn dfs(node: &Option, col: i32, map: &mut HashMap) {
if let Some(n) = node {
map.entry(col).or_insert(vec![]).push(n.val);
dfs(&n.left, col - 1, map);
dfs(&n.right, col + 1, map);
}
}
dfs(&root, 0, &mut map);
map.values().cloned().collect()
}
What is the main bug causing incorrect output?Solution
Step 1: Analyze map usage
HashMap stores columns but values() returns in arbitrary order, not sorted by column.Step 2: Understand output order requirement
Vertical order requires columns sorted from left to right, so keys must be sorted before collecting values.Final Answer:
map.values() does not guarantee sorted column order -> Option DQuick Check:
Sort keys before output [OK]
- Assuming HashMap preserves order
- Thinking BFS is mandatory for vertical order
- Starting column index incorrectly
Solution
Step 1: Understand sorting by depth need
Nodes in same vertical column must be ordered by their depth (distance from root).Step 2: Choose data structure to store depth info
Store (depth, value) pairs in HashMap for each column, then sort by depth before output.Final Answer:
Use a HashMap> and sort each vector by depth before output -> Option CQuick Check:
Store depth info and sort before output [OK]
- Ignoring depth and outputting unsorted nodes
- Using BinaryHeap without depth key
- Appending nodes without sorting
Ready to prove it?
Pass the test and this pattern moves unknown
