Shubham Sourabhthe room · director's cutplain résumé
Room 04 · The Grind — Trees

Lowest Common Ancestor of a Binary Search Tree

MEDIUM✓ CHIP-TIMEDLC #235 — FULL STATEMENT

The briefingthe full drill, in my own words

The drill: Given two nodes somewhere in a binary search tree, find the deepest node that has both of them as descendants — a node counts as its own descendant.

A binary search tree arrives along with two of its nodes, and the task is to find the deepest node in the tree that counts both of them among its descendants.

A node is considered its own descendant, so if one of the two target nodes happens to be an ancestor of the other, that target node itself is the answer.

Both target nodes are guaranteed to exist somewhere in the tree, and the tree's search-tree ordering — everything smaller to the left, everything larger to the right — holds throughout.

  • both target nodes exist in the tree and are distinct
  • the tree can hold anywhere from a couple of nodes to a few thousand
  • all values in the tree are unique and follow standard BST ordering
  • a node counts as its own descendant when checking ancestry
EX 01
root = [6, 2, 8, 0, 4, 7, 9, null, null, 3, 5] · p = [2] · q = [8]
→ [6, 2, 8, 0, 4, 7, 9, null, null, 3, 5]
targets split at the root
EX 02
root = [6, 2, 8, 0, 4, 7, 9, null, null, 3, 5] · p = [2] · q = [4]
→ [2, 0, 4, null, null, 3, 5]
one target is an ancestor of the other
EX 03
root = [6, 2, 8, 0, 4, 7, 9, null, null, 3, 5] · p = [0] · q = [3]
→ [2, 0, 4, null, null, 3, 5]
both targets sit deep in the same left branch

The hintstake only what you need

HINT 1 THE NUDGE

Ignoring the search-tree ordering entirely still gives a correct answer: search both subtrees for each target and combine what comes back. It just never uses the one fact this tree offers for free.

HINT 2 THE STRUCTURE

In a BST, a node's value alone tells you which side any other value lives on. If both targets are smaller than the current node, the answer can't be here — it's entirely in the left subtree, and symmetrically for the right.

HINT 3 ONE STEP FROM THE ANSWER

Walk down from the root comparing both target values against the current node's value: same-side, step that way; split (or a match), stop — that node is the answer.

Coach's boardthe pattern, step by step

FOLLOW THE ORDERINGPATTERN · FOLLOW THE ORDERINGroot = [6,2,8,0,4,7,9,null,null,3,5] · p = 3 · q = 5
STEP 1

Find the deepest node that's an ancestor of both 3 and 5. The BST ordering tells us which side to walk without ever searching — start at the root, 6.

STEP 1 / 5 · ← → WORK TOO

The splitstwo paces, two languages

grind/lowest-common-ancestor-of-a-binary-search-tree.py — RACE PACE
LANG ▸
PACE ▸
class Solution:
    def lowestCommonAncestor(self, root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode":
        curr = root
        while curr:
            if p.val < curr.val and q.val < curr.val:
                curr = curr.left
            elif p.val > curr.val and q.val > curr.val:
                curr = curr.right
            else:
                return curr
        return None
TIME O(H)SPACE O(1)PYTHON · RACE PACE · 11 LN

✓ CHIP-TIMEDALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED