LeetCode ยท #235

Lowest Common Ancestor of a BST Solution

Given a BST, find the lowest common ancestor (LCA) of two given nodes.

01
Section One ยท Problem

Problem Statement

๐Ÿท๏ธ

Difficulty

Medium

๐Ÿ”—

LeetCode

Problem #235

๐Ÿ—๏ธ

Pattern

BST โ€” split point detection

Given a BST and two nodes p and q, find their lowest common ancestor โ€” the deepest node that has both p and q as descendants (a node is allowed to be a descendant of itself).

Example
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 Output: 6 // 2 is in left subtree, 8 is in right โ†’ root 6 is the split point
Constraints
โ€ข 2 โ‰ค number of nodes โ‰ค 10โต โ€ข All values are unique โ€ข p โ‰  q, both exist in the BST
02
Section Two ยท Approach 1

Generic LCA (no BST property) โ€” O(n)

Ignore the BST ordering and use the general binary tree LCA approach: recursively search both subtrees. Works but doesn't exploit the sorted property โ€” always visits O(n) nodes.

03
Section Three ยท Approach 2

BST Split Point โ€” O(H)

In a BST, the LCA is the first node where p and q split โ€” one goes left, the other goes right (or one equals the current node). If both are smaller, go left. If both are larger, go right. Otherwise, the current node is the LCA.

๐Ÿ’ก Mental model: Walk down from the root. At each fork, both friends need to go the same direction (both smaller โ†’ go left; both bigger โ†’ go right). The first time they need to split up โ€” one goes left, the other right โ€” you're standing at their meeting point.
Algorithm
  • If both p and q < node โ†’ go left.
  • If both p and q > node โ†’ go right.
  • Else โ†’ current node is the LCA (split point or one matches).
๐ŸŽฏ Why O(H), not O(n)? We only walk one root-to-node path. In a balanced BST, H = O(log n). In a skewed BST, H = O(n) worst case.
04
Section Four ยท Trace

Visual Walkthrough

BST [6,2,8,0,4,7,9], p=2, q=8
6 โ† LCA 2 p โ†’ 8 โ† q 0 4 7 9 SPLIT-POINT DETECTION Node 6: p=2 < 6 (go left?) AND q=8 > 6 (go right?) โ†’ SPLIT! p and q diverge here. Node 6 is the LCA. One step โ€” immediate answer at the root. O(1) for this example. Answer: 6 โœ“
05
Section Five ยท Implementation

Code โ€” Java & Python

Java โ€” Iterative
class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { while (root != null) { if (p.val < root.val && q.val < root.val) { root = root.left; } else if (p.val > root.val && q.val > root.val) { root = root.right; } else { return root; // split point = LCA } } return null; } }
Python โ€” Iterative
class Solution: def lowestCommonAncestor(self, root, p, q): while root: if p.val < root.val and q.val < root.val: root = root.left elif p.val > root.val and q.val > root.val: root = root.right else: return root
06
Section Six ยท Analysis

Complexity Analysis

ApproachTimeSpace
Generic LCAO(n)O(n)
BST split โ† optimalO(H)O(1)
07
Section Seven ยท Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
One is ancestorp=2, q=4 (4 under 2)At node 2: q=4 > 2 โ†’ split. LCA = 2 (p itself).
Adjacent nodesp=3, q=4Split happens at their parent.
Root is LCAp = leftmost, q = rightmostRoot is always a common ancestor โ€” but might be the lowest too.
โš  Common Mistake: Forgetting that a node can be its own ancestor. If p = 2 and q = 4, and 4 is in 2's subtree, the LCA is 2 โ€” not 2's parent. The "else" case correctly returns the current node when one value matches.

โ† Back to BST problems