LCA (Lowest common ancestor) – binary tree (recursive / example)

  • Given a binary tree, find least or lowest common ancestor (LCA) of two given nodes.
  • Given input nodes should exists in a binary tree.
  • We will use depth first search (DFS) recursive algorithm to traverse the binary tree.
  • We have discussed the similar problem Find LCA in BST
Example binary tree
Fig 1: LCA of given binary tree

Example of least common ancestor nodes is:

We will analyse the Fig 1 binary tree and find out the LCA of nodes lying in different subtrees.

S. No.Input nodes LCA
1LCA (F , G)  C
2LCA ( C, G) C
3LCA (D ,E ) B
4LCA (D ,B ) B
5LCA (D, C ) A
6LCA (E ,G ) A

Example 1: LCA of Node B (25) & C (75) of a binary tree. (Fig 2).

  • Perform depth first search traversal.
  • Traverse left subtree of Node A & We will find node B (input node).
    • Node B will send its reference to its parent (Node A).
  • Traverse right  subtree of Node A & We will find node C (input node).
    • Node C will send its reference to its parent (Node A)
  • Node A getting non null from its left and right subtree.
    • Node A will be LCA of Node B & Node C
LCA of example tree
Fig 2: LCA (B,C) = A

Example 2: LCA of Node B (25) and D (10) of a binary tree. (Fig 3).

lowest common ancestor node
Fig 3: LCA (B , D) = B.
  • Perform DFS traversal of binary tree.
  • Traverse the left subtree of Node A.
    • We found Node B (whose LCA we would like to find).
    • No need to traverse underlying nodes).
    • return node B to its parent node A.
  • Traverse the right subtree of Node A.
    • In right subtree traversal (Node C), we will not get node B or D.
    • Right subtree will return null to its parent node A.
  • Node A will get node B from left subtree & null from right subtree.
  • Non null value i.e. Node B will be LCA of Node B & Node D.

Example 3: LCA of Node I & Node K (refer Fig 4).

lowest ancestor node left subtree
Fig 4: LCA ( I , K ) = B
  • Perform DFS traversal of binary tree to find LCA of Node I & K
  • Traverse left subtree of node A ie Node B
    • Traverse left subtree of Node B i.e. Node D
      • Right subtree traversal of Node D will find Node I.
      • Node D will return reference of Node I to Node B.
    • Traverse right subtree of Node B i.e. Node E
      • Right subtree traversal of Node E will find Node K.
      • Node D will return reference of Node K to Node B.
    • Node B got node I from left subtree and Node K from right subtree
      • return Node B to its parent i.e. Node A.
  • Traverse right subtree of Node A i.e. Node C.
    • Traverse left & right subtrees of Node C
    • No match will be found & return null to Node A.
  • Node A will get Node B from left subtree & null from right subtree.
  • Node B will LCA of Node I & Node K.

Example 4: LCA of Node I and Node M (refer Fig 5).

LCA node left & right subtree
Fig 5: LCA (I,M) = A

We can analyse the Fig 5 similar to previous examples.
Time complexity of algorithm is O(n).

Program to find lowest common ancestor of input nodes.

1.) LCA Class: LCA class is responsible for finding lowest common ancestors of two input nodes in a given binary tree.

 
package org.learn.Question;

public class LCA {
 public static Node lca(Node root, Node node1, Node node2) {
  if (null == root) {
   return root;
  }
  if (root == node1 || root == node2) {
   return root;
  }
  Node left = lca(root.left, node1, node2);
  Node right = lca(root.right, node1, node2);

  if (left != null && right != null) {
   return root;
  }
  if (left != null)
   return left;
  else
   return right;
 }
}

2.) Node Class: Node class is representing the nodes of a given binary tree.

package org.learn.Question;

public class Node {
 public int data;
 public Node left;
 public Node right;

 public Node(int num) {
  this.data = num;
  this.left = null;
  this.right = null;
 }

 public Node() {
  this.left = null;
  this.right = null;
 }
 
 public static Node createNode(int number) {
  return new Node(number);
 }
}

3.) App Class: We are creating the binary tree in a main method & calling method of LCA class to find least or lowest common ancestor of two input nodes of a given binary tree.

package org.learn.Client;

import org.learn.Question.LCA;
import org.learn.Question.Node;

public class App {
 public static void main(String[] args) {
  // root level 0
  Node A = Node.createNode(50);
  // Level 1
  Node B = Node.createNode(25);
  Node C = Node.createNode(75);
  // Level 2
  Node D = Node.createNode(15);
  Node E = Node.createNode(40);
  Node F = Node.createNode(60);
  Node G = Node.createNode(95);

  // Level 3
  Node H = Node.createNode(10);
  Node I = Node.createNode(20);
  Node J = Node.createNode(30);
  Node K = Node.createNode(45);
  Node L = Node.createNode(55);
  Node M = Node.createNode(65);

  // connect Level 0 and 1
  A.left = B;
  A.right = C;
  // connect level 1 and level 2
  B.left = D;
  B.right = E;
  C.left = F;
  C.right = G;
  // connect level 2 and level 3
  D.left = H;
  D.right = I;
  E.left = J;
  E.right = K;
  F.left = L;
  F.right = M;

  Node lca = LCA.lca(A, D, H);
  String message = String.format("1. LCA[Node D (%d) & Node H (%d)] = %d",
             D.data,H.data,lca.data);
  System.out.println(message);

  lca = LCA.lca(A, I, K);
  message = String.format("2. LCA[Node I (%d) & Node K (%d)] = %d", 
             I.data, K.data, lca.data);
  System.out.println(message);

  lca = LCA.lca(A, I, M);
  message = String.format("3. LCA[Node I (%d) & Node M (%d)] = %d", 
             I.data, M.data, lca.data);
  System.out.println(message);
 }
}

Output: Least common ancestors of input nodes :

1. LCA[Node D (15) & Node H (10)] = 15
2. LCA[Node I (20) & Node K (45)] = 25
3. LCA[Node I (20) & Node M (65)] = 50

Download Code – Find LCA of two node in a binary tree

Scroll to Top