Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources
Lowest Common Ancestor of a Binary Tree

Lowest Common Ancestor of a Binary Tree

Problem Statement

You’re a family tree historian finding the lowest common ancestor (LCA) of two nodes in a binary tree. Given the root and nodes p and q, return their LCA. This medium-level recursive quest is a lineage hunt—trace paths to unite the branches!

Example

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

Tree:

   3
  / \
 5   1
/ \ / \
6 2 0  8
 / \
7   4

Output: 3 (LCA of 5 and 1)

Input: p = 5, q = 4

Output: 5 (5 is ancestor of 4)

Input: root = [1,2], p = 1, q = 2

Output: 1

Code

Java
Python
JavaScript
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) return root;
        return left != null ? left : right;
    }
}
            
class Solution:
    def lowestCommonAncestor(self, root, p, q):
        if not root or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left and right:
            return root
        return left if left else right
            
function lowestCommonAncestor(root, p, q) {
    if (!root || root === p || root === q) return root;
    let left = lowestCommonAncestor(root.left, p, q);
    let right = lowestCommonAncestor(root.right, p, q);
    if (left && right) return root;
    return left || right;
}
            

Explanation

  • DFS Insight: LCA is where paths to p and q split—found when both subtrees return nodes.
  • Flow: Recurse left and right; if both return non-null, root is LCA; else, propagate non-null result.
  • Example Walkthrough: [3,5,1], p=5, q=1 → left=5, right=1, root=3 is LCA.
  • Edge Case: p or q is root, or one is ancestor of the other—handled naturally.
  • Alternative: Store paths to p and q, find last common node—more space, same result.

Note

Time complexity: O(n), Space complexity: O(h). A recursive reunion—elegant and ancestral!