• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar
  • Skip to footer
  • Home
  • Contact Us

All about code

  • Java
    • Spring
      • Spring Boot
      • Spring Cloud
    • Java Miscellaneous Tips
    • Java Design Patterns
  • Data Structures and Algorithms
    • Algorithms
    • Data Structures
  • Thoughts and Stories
  • AI

How to Implement the Lowest Common Ancestor in a Binary Tree Algorithm

laptop infographic online business 6087062

Introduction

Finding where two nodes in a binary tree converge in their ancestry is a problem that often arises when analyzing hierarchical data. This node, the one farthest from the root that is still a shared ancestor of both nodes, is what we call the Lowest Common Ancestor (LCA). It serves as a bridge point in the tree where two paths meet, and identifying it is useful in a wide range of tree-based applications.

Concept Overview of Lowest Common Ancestor

Let’s define the challenge: You’re given a binary tree and two nodes within it. These nodes can appear anywhere in the structure, and there’s no ordering rule like in a binary search tree. Your task is to find the node that is the deepest shared parent of both.

Visually, picture this scenario:

mathematicaCopiaModifica        A
       / \
      B   C
     / \   \
    D   E   F
       /
      G

If we’re looking for the LCA of G and D we trace their ancestry back and find that B is the first common node on both paths.

Solution of the Lowest Common Ancestor Algorithm

The method we’ll use is recursive. We look through the tree, starting from the root, and we apply the following logic:

  • If the current branch ends (i.e., the node is null), we return nothing.
  • If the node matches either of the target nodes, we send it up the call stack.
  • Otherwise, we check both the left and right subtrees.
  • If both subtrees return results, it means each target was found on a different side — making the current node their LCA.
  • If only one side returns a non-null result, that means both targets are deeper down that branch.

Java Implementation of the Lowest Common Ancestor Algorithm

Below is a Java implementation that applies this logic:

public class LowestCommonAncBinTree {

    public TreeNode lCA(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            return root;
        }

        TreeNode leftLCA = lCA(root.leftNode, p, q);
        TreeNode rightLCA = lCA(root.rightNode, p, q);

        if (leftLCA != null && rightLCA != null) {
            return root;
        }

        return (leftLCA != null) ? leftLCA : rightLCA;
    }

    public static void main(String[] args) {
        LowestCommonAncBinTree tree = new LowestCommonAncBinTree();

        LowestCommonAncBinTree.TreeNode root = tree.new TreeNode(3);
        root.leftNode = tree.new TreeNode(5);
        root.rightNode = tree.new TreeNode(1);
        root.leftNode.leftNode = tree.new TreeNode(6);
        root.leftNode.rightNode = tree.new TreeNode(2);
        root.rightNode.leftNode = tree.new TreeNode(0);
        root.rightNode.rightNode = tree.new TreeNode(8);
        root.leftNode.rightNode.leftNode = tree.new TreeNode(7);
        root.leftNode.rightNode.rightNode = tree.new TreeNode(4);

        TreeNode p = root.leftNode; // Node 5
        TreeNode q = root.rightNode; // Node 1

        TreeNode lca = tree.lCA(root, p, q);
        System.out.println("Lowest Common Ancestor of " + p.nodeVal + " and " + q.nodeVal + " is: " + lca.nodeVal);
    }
    
    class TreeNode {
        int nodeVal;
        TreeNode leftNode;
        TreeNode rightNode;

        TreeNode(int nodeVal) {
            this.nodeVal = nodeVal;
        }
    }
    
}

Conclusion

This approach works efficiently by exploring each node once, giving it a linear runtime with respect to the number of nodes in the tree. It’s versatile enough to handle any binary tree structure and doesn’t depend on the values of the nodes. Whether you’re working on tree structures in software architecture, genealogy, or file systems, understanding and implementing LCA logic is a valuable skill.

You can find the example code on Github.

Primary Sidebar

Social

  • Facebook
  • LinkedIn
  • Twitter

Archives

  • May 2026
  • April 2026
  • March 2026
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • December 2024
  • October 2024
  • August 2024
  • July 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • September 2023
  • May 2023
  • March 2023
  • January 2023
  • November 2022
  • September 2022
  • August 2022

Recent Posts

  • Better Avoid Spring Boot Lazy-initialization @PostConstruct Trap
  • How To Handle Large Datasets in Spring Boot
  • How to Log HTTP Incoming Requests in Spring Boot
  • How to Reliably Implement Post-Commit Actions in Spring
  • Brief and Easy Explanation of HATEOAS

TAGS

Algorithms Apache POI Backtracking Date Structures Dynamic Programming engineering Graphs Greedy Horror Stories HSSF Java Java New Features Java Principles Java tips real life Sorting Spring Boot Spring Cloud Strings Trees

Footer

Privacy Policy Cookie Policy Terms and Conditions