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.
classSolution:
deflowestCommonAncestor(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
Approach
Time
Space
Generic LCA
O(n)
O(n)
BST split โ optimal
O(H)
O(1)
07
Section Seven ยท Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
One is ancestor
p=2, q=4 (4 under 2)
At node 2: q=4 > 2 โ split. LCA = 2 (p itself).
Adjacent nodes
p=3, q=4
Split happens at their parent.
Root is LCA
p = leftmost, q = rightmost
Root 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.