📖 4 min read
Last updated on

Lowest Common Ancestor of a Binary Search Tree — Coding Interview Walkthrough


You’re given a BST and two nodes. Find their lowest common ancestor. Most candidates reach for the generic binary tree LCA algorithm, which works but completely ignores the BST property. Interviewers notice. The real test here is whether you can exploit the ordering constraint to turn an O(n) traversal into an O(h) walk down the tree, and whether you can articulate why the split point is the answer.


The Problem

Given a binary search tree and two nodes p and q, find their lowest common ancestor (LCA). The LCA is defined as the deepest node that has both p and q as descendants (a node can 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

Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 Output: 2

Node 2 is the ancestor of both itself and node 4.

BST [6,2,8,0,4,7,9] with node 6 highlighted as the split point LCA of p=2 and q=8. Edges from root to both children highlighted in teal.

Already comfortable with the solution? Practice it in a mock interview →


What Interviewers Are Actually Testing

SkillWhat Interviewers Observe
BST property exploitationDo you use val comparisons instead of generic tree traversal?
LCA intuitionDo you understand what “split point” means?
Iterative vs. recursiveCan you write both and explain the space difference?
LCA generalizationDo you know this differs from LCA of a general binary tree?

Step 1: Clarifying Questions

  1. Is this a BST or a general binary tree? Critical. BST ordering enables a simple comparison-based approach that doesn’t work on general trees.
  2. Are p and q guaranteed to exist in the tree? Assume yes per problem constraints.
  3. Can a node be its own ancestor? Yes. The LCA of 2 and 4 in the example is 2 itself.

Step 2: The Naive Idea

Treat it like a general binary tree and do a standard LCA via DFS — checking if each subtree contains p or q. Works, but ignores the BST property. O(n) time. We can do better.


Step 3: The Key Insight

In a BST, the LCA is the first node where p and q “split.” If both p.val and q.val are less than node.val, the LCA is in the left subtree. If both are greater, it’s in the right subtree. The moment they’re on opposite sides (or one equals node.val), you’ve found the LCA.

This reduces the search to O(h) — tree height — by exploiting BST structure.


Step 4: Optimal Strategy

  1. Start at the root.
  2. If both p.val and q.val < node.val: go left.
  3. If both p.val and q.val > node.val: go right.
  4. Otherwise: current node is the LCA. Return it.

Python Implementation

Recursive:

def lowestCommonAncestor(root, p, q):
    if p.val < root.val and q.val < root.val:
        return lowestCommonAncestor(root.left, p, q)
    if p.val > root.val and q.val > root.val:
        return lowestCommonAncestor(root.right, p, q)
    return root  # Split point found

Iterative (O(1) space):

def lowestCommonAncestor(root, p, q):
    node = root
    while node:
        if p.val < node.val and q.val < node.val:
            node = node.left
        elif p.val > node.val and q.val > node.val:
            node = node.right
        else:
            return node

Time & Space Complexity

ApproachTimeSpace
RecursiveO(h)O(h) call stack
IterativeO(h)O(1)

For a balanced BST, h = O(log n). For a skewed BST, h = O(n).


Common Interview Mistakes

  1. Using the general binary tree LCA approach. It works but ignores the BST structure. Interviewers view this as a missed optimization.

  2. Not handling the case where p or q equals the current node. The else branch handles this correctly since if p.val == root.val, neither condition is true.

  3. Not knowing the difference between LCA of BST (#235) and LCA of binary tree (#236). The BST version is O(h); the general version is O(n). Being able to state this distinction shows depth.

  4. Forgetting that the iterative version is O(1) space. Always mention this as an advantage over the recursive version.


What a Strong Candidate Sounds Like

“Since this is a BST, I can exploit the ordering property. At each node, if both target values are less than the current value, the LCA must be in the left subtree. If both are greater, go right. The first node where they split — or one equals the node — is the LCA. This is O(h) time and O(1) space with the iterative version.”


Example Interview Dialogue

Interviewer: How would your approach change for a general binary tree?

Candidate: For a general tree I can’t use value comparisons to decide direction. I’d do a full DFS: at each node, recursively check if the left subtree contains p, the right contains q, or vice versa. The node where both subtrees return a match (or the node itself is one of the targets) is the LCA. That’s O(n) time instead of O(h).

Interviewer: What if the BST is highly skewed?

Candidate: Then h = O(n) and we lose the logarithmic advantage. The algorithm still works correctly, but performance degrades to linear. If we needed guaranteed O(log n), we’d need a self-balancing BST like a red-black tree or AVL tree.



Practice This in a Mock Interview

The split-point insight is easy to understand when reading about it. Articulating it fluently while an interviewer watches — that’s the hard part. Practice explaining why the split point is the answer, not just what code to write.

Start a mock interview for Lowest Common Ancestor of a BST on Intervu.


Further reading:

Practice Like It's the Real Interview

Get instant feedback on your approach, communication, and code — powered by AI.

Start a Mock Interview →