Lowest Common Ancestor

March 11, 2011

Today’s problem appears with some regularity at places like Proggit and Stack Overflow and in lists of programming interview questions:

Given a binary tree t and two elements of the tree, m and n, with m<n, find the lowest element of the tree (farthest from the root) that is an ancestor of both m and n.

For example, in the tree shown at right, the lowest common ancestor of 4 and 7 is 6, the lowest common ancestor of 4 and 10 is 8, and the lowest common ancestor of 1 and 4 is 3. It is possible for an element of the tree to be its own ancestor, so the lowest common ancestor of 1 and 3 is 3, and the lowest common ancestor of 3 and 6 is 3.

Your task is to write a function that finds the lowest common ancestor of two elements of a binary tree. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Serabe: I’m not sure I know the difference between a binary tree and a binary search tree. The trees we are talking about have nodes with two children, all nodes with keys less than the current node in the left child and all nodes with keys greater than the current node in the right child.

That’s a binary search tree. A tree whose nodes have two children are binary trees (without the order restriction). I guess you can see now that Remco’s algorithm cannot work on binary trees, without the “search” part.

First, a Python version. My insert() method is a bit cumbersome,
since it checks whether the current node has a left/right subtree before
heading down it. I owe the lca() implementation to Remco’s
succinct Haskell code.

My approach focuses on traversing the tree using DFS, saving each node’s path from the root, and then comparing the nodes’ path in order to find the lowest common ancestor. Here’s the Java function that traverses the tree:

Given the same list structure in my previous post, the following lca()-function finds the lowest common ancestor for any two nodes regardless of whether the items in the tree are sorted, i.e., for any binary tree. The only requirement is that for an item at list[n], the two children are at list[2n+1] and list[2n+2].