↓Skip to main content
  1. LeetCode/

LeetCode 987: Vertical Order Traversal of a Binary Tree

·2 mins· ·
LeetCode Hard Tree Binary-Tree Bfs Sorting
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-09-12

  • Submissions: Accepted (first try)

Approach
#

Every node has a coordinate: the root is (row 0, col 0), a left child is col - 1, a right child is col + 1, and row grows by 1.

The output order:

  1. Columns from left to right.
  2. Within a column, top to bottom.
  3. Same column and row: by value, ascending.

That is exactly lexicographic order on (col, row, val). Collect each node’s triple, sort once, then group by column.

The difficulty is the ordering rule, not the traversal: BFS or DFS both work for collecting.

My Solution
#

from collections import deque

class Solution:
    def verticalTraversal(self, root: Optional[TreeNode]) -> List[List[int]]:
        q = deque([(root, 0, 0)])               # (node, col, row)
        cells = []
        while q:
            node, col, row = q.popleft()
            cells.append((col, row, node.val))
            if node.left:
                q.append((node.left, col - 1, row + 1))
            if node.right:
                q.append((node.right, col + 1, row + 1))

        cells.sort()

        res = []
        prev_col = None
        for col, _, val in cells:
            if col != prev_col:
                res.append([])
                prev_col = col
            res[-1].append(val)
        return res

My original code grouped by hand with prev_x and curr_x and appended the last group after the loop. The version above starts a new group whenever the column changes, so there is no last group to add separately.

Complexity
#

Time O(n log n), dominated by sorting. Space O(n).

Mistakes to Avoid
#

  • Grouping by column without sorting by row: BFS goes roughly top to bottom, but within one row, nodes from different subtrees are not ordered by value.
  • Not sorting by value within the same column and row, which the problem requires explicitly.
  • Forgetting to add the last group when grouping by hand.

Interview Explanation
#

I give each node a coordinate: the root is (0, 0), left decreases the column, right increases it, and each level increases the row. The required order is lexicographic on (column, row, value), so I collect all triples, sort once, and group by column. Time O(n log n).

Related

LeetCode 2509: Cycle Length Queries in a Tree
·2 mins
LeetCode Hard Tree Binary-Tree Lca
LeetCode 2509 note: in heap numbering the parent is v // 2, so climb the larger node until both meet at the LCA
LeetCode 2421: Number of Good Paths
·3 mins
LeetCode Hard Tree Union-Find Graph Sorting
LeetCode 2421 note: add nodes in increasing value order and count same-value nodes per Union-Find group
LeetCode 1028: Recover a Tree From Preorder Traversal
·3 mins
LeetCode Hard Tree Binary-Tree Dfs Stack String
LeetCode 1028 note: a stack holds the path from the root to the current node, so its length is the depth
LeetCode 2973: Find Number of Coins to Place in Tree Nodes
·3 mins
LeetCode Hard Dynamic-Programming Tree-Dp Depth-First-Search Sorting Heap Tree
LeetCode 2973 note: the max product of three is either the three largest or the two smallest times the largest, so each subtree returns only its 2 smallest and 3 largest values, merged in post-order
LeetCode 1377: Frog Position After T Seconds
·3 mins
LeetCode Hard Tree Dfs Bfs Graph Probability
LeetCode 1377 note: undirected edges, seen must hold nodes, and an early arrival depends on whether the frog can still move
LeetCode 865: Smallest Subtree with all the Deepest Nodes
·2 mins
LeetCode Medium Tree Binary-Tree Bfs Dfs Lca
LeetCode 865 note: BFS to the last level and climb together, or one DFS returning (depth, node)