๐ณ Vertical Order Traversal of Binary Tree โ Complete Guide with Java, C++, and Python Solutions


๐ Problem Overview
In Vertical Order Traversal of a Binary Tree, we need to:
Print nodes column-wise from left to right.
Sort nodes in each column top to bottom.
If two nodes share the same position, sort their values in ascending order.
๐ก Thought Process
We can imagine the binary tree as plotted on a 2D grid:
The root node starts at
(0, 0)
.Left child: moves to
(verticalIndex - 1, level + 1)
Right child: moves to
(verticalIndex + 1, level + 1)
We must:
Group nodes by vertical index (columns).
Sort nodes by level (rows).
Sort overlapping nodes (same vertical and level) by value.
โจ Example
Letโs consider this tree:
3
/ \
9 20
/ \
15 7
Vertical Index Mapping:
Vertical Index | Nodes |
-1 | 9 |
0 | 3, 15 |
1 | 20 |
2 | 7 |
Final Vertical Order Traversal:
[
[9],
[3, 15],
[20],
[7]
]
Why?
Vertical -1: Only 9.
Vertical 0: 3 is on top, 15 is below โ [3, 15].
Vertical 1: Only 20.
Vertical 2: Only 7.
๐ Approach
Weโll use:
TreeMap<verticalIndex, TreeMap<level, PriorityQueue<node values>>>
โ This helps automatically sort verticals, levels, and node values.DFS traversal to map each node to its (verticalIndex, level).
โ Java Solution
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> verticalTraversal(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
TreeMap<Integer, TreeMap<Integer, PriorityQueue<Integer>>> map = new TreeMap<>();
traverse(root, map, 0, 0);
for (TreeMap<Integer, PriorityQueue<Integer>> levels : map.values()) {
List<Integer> col = new ArrayList<>();
for (PriorityQueue<Integer> nodes : levels.values()) {
while (!nodes.isEmpty()) {
col.add(nodes.poll());
}
}
result.add(col);
}
return result;
}
private void traverse(TreeNode root, TreeMap<Integer, TreeMap<Integer, PriorityQueue<Integer>>> map, int level, int verticalIndex) {
if (root == null) return;
map.putIfAbsent(verticalIndex, new TreeMap<>());
map.get(verticalIndex).putIfAbsent(level, new PriorityQueue<>());
map.get(verticalIndex).get(level).offer(root.val);
traverse(root.left, map, level + 1, verticalIndex - 1);
traverse(root.right, map, level + 1, verticalIndex + 1);
}
}
โ C++ Solution
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
map<int, map<int, multiset<int>>> nodes;
void dfs(TreeNode* node, int verticalIndex, int level) {
if (!node) return;
nodes[verticalIndex][level].insert(node->val);
dfs(node->left, verticalIndex - 1, level + 1);
dfs(node->right, verticalIndex + 1, level + 1);
}
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> result;
dfs(root, 0, 0);
for (auto& p : nodes) {
vector<int> col;
for (auto& q : p.second) {
col.insert(col.end(), q.second.begin(), q.second.end());
}
result.push_back(col);
}
return result;
}
};
โ Python Solution
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
from collections import defaultdict
import heapq
class Solution:
def verticalTraversal(self, root):
nodes = defaultdict(lambda: defaultdict(list))
def dfs(node, verticalIndex, level):
if not node:
return
heapq.heappush(nodes[verticalIndex][level], node.val)
dfs(node.left, verticalIndex - 1, level + 1)
dfs(node.right, verticalIndex + 1, level + 1)
dfs(root, 0, 0)
result = []
for verticalIndex in sorted(nodes.keys()):
col = []
for level in sorted(nodes[verticalIndex].keys()):
while nodes[verticalIndex][level]:
col.append(heapq.heappop(nodes[verticalIndex][level]))
result.append(col)
return result
๐ Key Notes
We use TreeMap (Java), map/multiset (C++), and dict/heapq (Python) to maintain sorting.
DFS traversal is essential to track vertical and level positions.
๐ Complexity
Time Complexity: O(N log N)
- Sorting verticals, levels, and node values.
Space Complexity: O(N)
- Additional space for maps and priority queues.
๐ Final Thoughts
Vertical Order Traversal is a great problem to strengthen:
Binary Tree Traversal
Coordinate Mapping in Grids
Efficient Sorting using Maps and Priority Queues
If youโre aiming to master tree problems, this one will give you a solid foundation!
๐ข Tags:
#LeetCode #Java #C++ #Python #DSA #BinaryTree #VerticalOrderTraversal #100DaysOfCode #Algorithms
Subscribe to my newsletter
Read articles from Virendra Jadhav directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
