🧠
Brute Force (DFS with manual sorting)
💡 This approach exists to build intuition by collecting all nodes with their coordinates and then sorting them. It is straightforward but inefficient for large trees.
Intuition
Traverse the tree using DFS, record each node's (row, column) coordinates, then sort all nodes by column, then row, then value to get the vertical order.
Algorithm
- Traverse the tree with DFS, tracking row and column indices for each node.
- Store tuples of (column, row, node_value) in a list.
- Sort the list by column, then row, then node value.
- Group the sorted nodes by column to form the final output.
💡 The main challenge is understanding how to assign and use coordinates, and then how sorting simulates vertical order traversal.
from collections import defaultdict
def verticalOrder(root):
nodes = []
def dfs(node, row, col):
if not node:
return
nodes.append((col, row, node.val))
dfs(node.left, row + 1, col - 1)
dfs(node.right, row + 1, col + 1)
dfs(root, 0, 0)
nodes.sort()
res = defaultdict(list)
for col, row, val in nodes:
res[col].append(val)
return [res[x] for x in sorted(res)]
# Driver code example:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
root = TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7)))
print(verticalOrder(root))
Line Notes
nodes = []Initialize list to store nodes with coordinates
def dfs(node, row, col):DFS helper to traverse tree with row and column tracking
if not node:Base case to stop recursion at leaf's child
nodes.append((col, row, node.val))Record node with its column and row for sorting
dfs(node.left, row + 1, col - 1)Left child is one row down and one column left
dfs(node.right, row + 1, col + 1)Right child is one row down and one column right
nodes.sort()Sort nodes by column, then row, then value to get vertical order
res = defaultdict(list)Group nodes by column after sorting
for col, row, val in nodes:Populate groups for each column
return [res[x] for x in sorted(res)]Return columns in ascending order
import java.util.*;
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) { this.val = val; }
}
public class Solution {
static class NodeInfo implements Comparable<NodeInfo> {
int col, row, val;
NodeInfo(int c, int r, int v) { col = c; row = r; val = v; }
public int compareTo(NodeInfo other) {
if (this.col != other.col) return this.col - other.col;
if (this.row != other.row) return this.row - other.row;
return this.val - other.val;
}
}
public List<List<Integer>> verticalOrder(TreeNode root) {
List<NodeInfo> nodes = new ArrayList<>();
dfs(root, 0, 0, nodes);
Collections.sort(nodes);
List<List<Integer>> res = new ArrayList<>();
int prevCol = Integer.MIN_VALUE;
for (NodeInfo ni : nodes) {
if (ni.col != prevCol) {
res.add(new ArrayList<>());
prevCol = ni.col;
}
res.get(res.size() - 1).add(ni.val);
}
return res;
}
private void dfs(TreeNode node, int row, int col, List<NodeInfo> nodes) {
if (node == null) return;
nodes.add(new NodeInfo(col, row, node.val));
dfs(node.left, row + 1, col - 1, nodes);
dfs(node.right, row + 1, col + 1, nodes);
}
// Main method for testing
public static void main(String[] args) {
TreeNode root = new TreeNode(3);
root.left = new TreeNode(9);
root.right = new TreeNode(20);
root.right.left = new TreeNode(15);
root.right.right = new TreeNode(7);
Solution sol = new Solution();
System.out.println(sol.verticalOrder(root));
}
}
Line Notes
class NodeInfo implements Comparable<NodeInfo>Helper class to store node info and enable sorting
public int compareTo(NodeInfo other)Defines sorting order by column, then row, then value
dfs(root, 0, 0, nodes);Start DFS traversal with initial coordinates
if (node == null) return;Base case to stop recursion
nodes.add(new NodeInfo(col, row, node.val));Record node with coordinates
dfs(node.left, row + 1, col - 1, nodes);Traverse left child with updated coordinates
dfs(node.right, row + 1, col + 1, nodes);Traverse right child with updated coordinates
Collections.sort(nodes);Sort all nodes to simulate vertical order
if (ni.col != prevCol)Detect column change to start new group
res.get(res.size() - 1).add(ni.val);Add node value to current column group
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
struct NodeInfo {
int col, row, val;
NodeInfo(int c, int r, int v) : col(c), row(r), val(v) {}
bool operator<(const NodeInfo& other) const {
if (col != other.col) return col < other.col;
if (row != other.row) return row < other.row;
return val < other.val;
}
};
void dfs(TreeNode* node, int row, int col, vector<NodeInfo>& nodes) {
if (!node) return;
nodes.emplace_back(col, row, node->val);
dfs(node->left, row + 1, col - 1, nodes);
dfs(node->right, row + 1, col + 1, nodes);
}
vector<vector<int>> verticalOrder(TreeNode* root) {
vector<NodeInfo> nodes;
dfs(root, 0, 0, nodes);
sort(nodes.begin(), nodes.end());
vector<vector<int>> res;
int prevCol = INT_MIN;
for (auto& ni : nodes) {
if (ni.col != prevCol) {
res.emplace_back();
prevCol = ni.col;
}
res.back().push_back(ni.val);
}
return res;
}
// Driver code
int main() {
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(9);
root->right = new TreeNode(20);
root->right->left = new TreeNode(15);
root->right->right = new TreeNode(7);
auto res = verticalOrder(root);
for (auto& col : res) {
cout << "[";
for (int v : col) cout << v << ",";
cout << "] ";
}
cout << endl;
return 0;
}
Line Notes
struct NodeInfoStores node coordinates and value for sorting
bool operator<(const NodeInfo& other) constDefines sorting order by col, row, then val
void dfs(TreeNode* node, int row, int col, vector<NodeInfo>& nodes)DFS traversal with coordinate tracking
if (!node) return;Base case to stop recursion
nodes.emplace_back(col, row, node->val);Record node info for sorting
dfs(node->left, row + 1, col - 1, nodes);Traverse left child with updated coordinates
dfs(node->right, row + 1, col + 1, nodes);Traverse right child with updated coordinates
sort(nodes.begin(), nodes.end());Sort nodes to simulate vertical order
if (ni.col != prevCol)Detect column change to start new group
res.back().push_back(ni.val);Add node value to current column group
class TreeNode {
constructor(val=0, left=null, right=null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function verticalOrder(root) {
const nodes = [];
function dfs(node, row, col) {
if (!node) return;
nodes.push([col, row, node.val]);
dfs(node.left, row + 1, col - 1);
dfs(node.right, row + 1, col + 1);
}
dfs(root, 0, 0);
nodes.sort((a, b) => {
if (a[0] !== b[0]) return a[0] - b[0];
if (a[1] !== b[1]) return a[1] - b[1];
return a[2] - b[2];
});
const res = [];
let prevCol = Number.MIN_SAFE_INTEGER;
for (const [col, row, val] of nodes) {
if (col !== prevCol) {
res.push([]);
prevCol = col;
}
res[res.length - 1].push(val);
}
return res;
}
// Driver code
const root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7)));
console.log(verticalOrder(root));
Line Notes
const nodes = []Initialize array to store nodes with coordinates
function dfs(node, row, col)DFS helper to traverse tree with coordinate tracking
if (!node) return;Base case to stop recursion
nodes.push([col, row, node.val]);Record node with column and row for sorting
dfs(node.left, row + 1, col - 1);Traverse left child with updated coordinates
dfs(node.right, row + 1, col + 1);Traverse right child with updated coordinates
nodes.sort((a, b) => {...})Sort nodes by column, then row, then value
if (col !== prevCol)Detect column change to start new group
res.push([]);Create new group for new column
res[res.length - 1].push(val);Add node value to current column group
DFS visits all nodes once (O(n)), sorting all nodes takes O(n log n), grouping is O(n).
💡 For n=1000 nodes, sorting 1000 elements is about 1000*log2(1000) ≈ 10,000 operations, which is acceptable but not optimal.
Interview Verdict: Accepted but not optimal for very large trees
This approach works but sorting all nodes is costly; better BFS approaches exist that avoid sorting all nodes.