GeeksforGeeks Medium

Bottom View of Binary Tree

Values visible from below: for each column, the last node in level order.

treebfshash-table
Open on GeeksforGeeks ↗
02

Intuition

Same column trick as vertical order, but per column you keep only the deepest (and among equals, latest-visited) node. BFS makes 'latest = lowest' automatic: just overwrite the column entry on every visit.

How to spot this pattern

Same column indexing as top view, opposite rule: top view keeps the first node seen per column, bottom view keeps the last. With BFS, later writes are automatically lower in the tree, so an unconditional overwrite gives the bottom view for free.

03

Approach

1

BFS with column index

Queue carries (node, col). Left −1, right +1.

2

Overwrite per column

map[col] = node.val unconditionally — BFS visits top-down, so the final write per column is the bottom-most node.

3

Read columns in order

Output map values sorted by column key.

04

Solution & live demo

1from collections import deque
2 
3def bottom_view(root):
4 if not root: return []
5 seen = {}
6 q = deque([(root, 0)])
7 while q:
8 node, c = q.popleft()
9 seen[c] = node.val # last write per column wins
10 if node.left: q.append((node.left, c - 1))
11 if node.right: q.append((node.right, c + 1))
12 return [seen[c] for c in sorted(seen)]
05

Common pitfalls

Guarding the write like a top view

✗ Wrong
if c not in seen:
    seen[c] = node.val
✓ Right
seen[c] = node.val

That's exactly the top-view rule and produces the top view instead. Bottom view wants the deepest node per column, which BFS delivers as the last write.

Using DFS and overwriting blindly

✗ Wrong
def dfs(node, c):
    seen[c] = node.val
    dfs(node.left, c - 1); dfs(node.right, c + 1)
✓ Right
q = deque([(root, 0)])
# BFS, overwrite per column

DFS visits a deep left node before a shallower right one, so the last write isn't necessarily the deepest — the right subtree can overwrite a genuinely lower node. DFS works only if you also track and compare depth explicitly.

Returning values in insertion order

✗ Wrong
return list(seen.values())
✓ Right
return [seen[c] for c in sorted(seen)]

The output must run left to right by column. Insertion order follows the BFS visit sequence, which interleaves columns arbitrarily.

06

Edge cases

Two bottom nodes share a column

BFS order decides (the later one wins) — matching GFG's expected output.

Top view variant

Same code but write only if the column is unseen — first wins instead of last.

07

Complexity

Time
O(n log n)
Space
O(n)
BFS + sort of column keys.