Bottom View of Binary Tree in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find the bottom view of a binary tree changes as the tree grows.
How does the number of nodes affect the work done to get the bottom view?
Analyze the time complexity of the following code snippet.
void bottomView(Node* root) {
if (!root) return;
map hdNodeMap; // horizontal distance to node data
queue> q;
q.push({root, 0});
while (!q.empty()) {
auto nodePair = q.front(); q.pop();
Node* node = nodePair.first;
int hd = nodePair.second;
hdNodeMap[hd] = node->data; // overwrite for bottom view
if (node->left) q.push({node->left, hd - 1});
if (node->right) q.push({node->right, hd + 1});
}
for (auto& [hd, val] : hdNodeMap) {
cout << val << " ";
}
}
This code finds the bottom view of a binary tree by level order traversal and tracking horizontal distances.
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 in the tree (n times).
- Inside the loop, updating the map is done for each node.
As the number of nodes (n) increases, the number of times we visit nodes and update the map grows linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits and map updates |
| 100 | About 100 visits and map updates |
| 1000 | About 1000 visits and map updates |
Pattern observation: The work grows directly with the number of nodes, doubling nodes roughly doubles work.
Time Complexity: O(n log n)
This means the time grows a bit more than linearly because each node insertion into the map takes logarithmic time.
[X] Wrong: "The time complexity is O(n) because we visit each node once."
[OK] Correct: Although each node is visited once, updating the map takes O(log n) time, so total time is O(n log n).
Understanding how tree traversal combined with data structure operations affects time helps you explain your approach clearly and confidently.
"What if we used an unordered_map instead of map? How would the time complexity change?"
Practice
bottom view of a binary tree represent?Solution
Step 1: Understand the bottom view concept
The bottom view shows nodes visible when looking from the bottom of the tree, meaning the lowest nodes at each horizontal distance.Step 2: Compare with other views
Top view shows nodes visible from above, left and right views show nodes from sides, so bottom view is unique for bottom visibility.Final Answer:
Nodes visible when the tree is viewed from the bottom -> Option AQuick Check:
Bottom view = nodes visible from bottom [OK]
- Confusing bottom view with top view
- Thinking bottom view shows all leaf nodes
- Mixing bottom view with side views
Solution
Step 1: Identify data structure needs
We need to map horizontal distances (int) to node values (int) and keep them sorted by horizontal distance.Step 2: Choose container
std::map keeps keys sorted and allows key-value pairs, perfect for horizontal distance mapping.Final Answer:
std::map -> Option BQuick Check:
Use map for sorted key-value pairs [OK]
- Using vector which is index-based, not key-based
- Using stack or queue which don't map keys to values
- Not sorting horizontal distances
20
/ \
8 22
/ \ \
5 3 25
/ \
10 14
Solution
Step 1: Assign horizontal distances (HD) to nodes
Root 20 at HD=0; 8 at HD=-1; 22 at HD=1; 5 at HD=-2; 3 at HD=0; 25 at HD=2; 10 at HD=-1; 14 at HD=1.Step 2: Determine bottom view nodes by HD
At HD=-2: 5; HD=-1: 10 (lower than 8); HD=0: 3 (lower than 20); HD=1: 14 (lower than 22); HD=2: 25.Final Answer:
[5, 10, 3, 14, 25] -> Option CQuick Check:
Bottom view nodes by HD = [5,10,3,14,25] [OK]
- Choosing top nodes instead of bottom nodes
- Mixing horizontal distances incorrectly
- Ignoring nodes at same horizontal distance but lower level
void bottomView(Node* root) {
if (!root) return;
std::map hdNodeMap;
std::queue> q;
q.push({root, 0});
while (!q.empty()) {
auto p = q.front(); q.pop();
Node* node = p.first;
int hd = p.second;
if (hdNodeMap.find(hd) == hdNodeMap.end()) {
hdNodeMap[hd] = node->data;
}
if (node->left) q.push({node->left, hd - 1});
if (node->right) q.push({node->right, hd + 1});
}
for (auto it : hdNodeMap) {
std::cout << it.second << " ";
}
}
Solution
Step 1: Analyze node storage logic
The code stores node data only if horizontal distance is not already in map, so it keeps first node encountered at that HD.Step 2: Understand bottom view requirement
Bottom view requires the lowest node at each HD, so we must update map with nodes at lower levels, not just first.Final Answer:
It stores only the first node at each horizontal distance, not the bottom-most -> Option AQuick Check:
Bottom view needs last node at HD, not first [OK]
- Not updating map for lower level nodes
- Assuming BFS order guarantees bottom view
- Ignoring horizontal distance updates
Solution
Step 1: Understand the problem with same HD and depth
When nodes share horizontal distance and depth, bottom view should show the rightmost node.Step 2: Modify BFS approach
Use BFS to traverse level by level, and update map if current node's depth is greater or equal to stored node's depth, ensuring rightmost node replaces leftmost at same depth.Step 3: Implement depth tracking
Track depth along with horizontal distance, update map accordingly during BFS.Final Answer:
Use BFS and update map only if node depth is greater or equal, replacing existing node -> Option DQuick Check:
Update map on equal or greater depth for rightmost node [OK]
- Ignoring depth when updating map
- Using DFS which doesn't guarantee level order
- Not handling equal depth nodes properly
Ready to prove it?
Pass the test and this pattern moves unknown
