Lowest Common Ancestor in a Binary Tree
Last Updated :
23 Jul, 2025
Given the root of a Binary Tree with all unique values and two node values n1 and n2, the task is to find the lowest common ancestor of the given two nodes. The Lowest Common Ancestor (or LCA) is the lowest node in the tree that has both n1 and n2 as descendants. In other words, the LCA of n1 and n2 is the shared ancestor of n1 and n2 that is located farthest from the root.
We may assume that either both n1 and n2 are present in the tree or none of them are present.
Examples:
Input:
Output: 2
Explanation: As shown below, LCA of 4 and 5 is 2
Input:
Output: 1
Explanation: As shown below, LCA of 5 and 6 is 1.
Using Arrays to Store Paths of Nodes from Root - O(n) Time and O(n) Space
The idea is to store the paths of nodes from the root in two separate arrays. Then start traversing from the 0th index and look simultaneously into the values stored in the arrays, the LCA is the last matching element in both the arrays.
Path from root to 5 = 1 -> 2 -> 5
Path from root to 6 = 1 -> 3 -> 6
- We start checking from 0th index. As both of the value matches, we move to the next index.
- Now check for values at 1st index, there's a mismatch so we consider the previous value.
- Therefore the LCA of (5, 6) is 1
C++
// C++ program to find LCA using Arrays to Store
// Paths of Nodes from Root
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Function to find path from root to given node.
bool findPath(Node* root, vector<Node*>& path, int k) {
// base case
if (root == nullptr)
return false;
// Store current node value in the path.
path.push_back(root);
// If node value is equal to k, or
// if node exist in left subtree or
// if node exist in right subtree return true
if (root->data == k ||
findPath(root->left, path, k) ||
findPath(root->right, path, k))
return true;
// else remove root from path and return false
path.pop_back();
return false;
}
// Returns LCA of two nodes.
Node* lca(Node* root, int n1, int n2) {
// to store paths to n1 and n2 from the root
vector<Node*> path1, path2;
// Find paths from root to n1 and
// root to n2. If either
// n1 or n2 is not present, return nullptr
if (!findPath(root, path1, n1) ||
!findPath(root, path2, n2))
return nullptr;
// Compare the paths to get the first
// different value
int i;
for (i = 0; i < path1.size()
&& i < path2.size(); i++) {
if (path1[i] != path2[i])
return path1[i-1];
}
// if both the datas are same, return last node
return path1[i-1];
}
int main() {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node* ans = lca(root, 4, 5);
if(ans == nullptr)
cout<<"No common ancestor found";
else
cout<< ans->data;
return 0;
}
Java
// Java program to find LCA using Arrays to Store
// Paths of Nodes from Root
import java.util.ArrayList;
import java.util.List;
class Node {
int data;
Node left, right;
Node(int value) {
data = value;
left = right = null;
}
}
class GfG {
// Function to find lca
static Node lca(Node root, int n1, int n2) {
// to store paths to n1 and n2 from the root
List<Node> path1 = new ArrayList<>();
List<Node> path2 = new ArrayList<>();
// Find paths from root to n1 and
// root to n2. If either
// n1 or n2 is not present, return null.
if(!findPath(root, path1, n1) ||
!findPath(root, path2, n2))
return null;
// Compare the paths to get the first
// different value
int i;
for(i = 0; i<path1.size() &&
i<path2.size(); i++) {
if(path1.get(i) != path2.get(i))
return path1.get(i-1);
}
// if both the datas are same, return last node
return path1.get(i-1);
}
// Finds the path from root to given node
static boolean findPath(Node root, List<Node> path, int n) {
// base case
if (root == null) {
return false;
}
// Store current node
path.add(root);
if (root.data == n ||
findPath(root.left, path, n) ||
findPath(root.right, path, n)) {
return true;
}
// remove root from path and return false
path.remove(path.size() - 1);
return false;
}
public static void main(String[] args) {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node ans = lca(root, 4, 5);
if(ans == null){
System.out.println("No common ancestor found");
}
else{
System.out.println(ans.data);
}
}
}
Python
# Python program to find LCA using Arrays to Store
# Paths of Nodes from Root
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# function to find path from root to node
def findPath(root, path, k):
# Baes Case
if root is None:
return False
# Store current node in path
path.append(root)
# If node value is equal to k, or
# if node exist in left subtree or
# if node exist in right subtree return true
if (root.data == k or
findPath(root.left, path, k)
or findPath(root.right, path, k)):
return True
# else remove root from path and return false
path.pop()
return False
# Function to find lca of two nodes
def lca(root, n1, n2):
# To store paths to n1 and n2 fromthe root
path1 = []
path2 = []
# Find paths from root to n1 and root to n2.
# If either n1 or n2 is not present , return -1
if (not findPath(root, path1, n1) or not findPath(root, path2, n2)):
return None
# Compare the paths to get the first different value
i = 0
while(i < len(path1) and i < len(path2)):
if path1[i] != path2[i]:
break
i += 1
return path1[i-1]
if __name__ == '__main__':
# construct the binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
ans = lca(root, 4, 5)
if(ans == None):
print("No common ancestor found")
else :
print(ans.data)
C#
// C# program to find LCA using Arrays to Store
// Paths of Nodes from Root
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Function to find path from root to given node.
static bool findPath(Node root, List<Node> path, int k) {
// base case
if (root == null)
return false;
// Store current node value in the path.
path.Add(root);
// If node value is equal to k, or
// if node exist in left subtree or
// if node exist in right subtree return true
if (root.data == k ||
findPath(root.left, path, k) ||
findPath(root.right, path, k))
return true;
// else remove root from path and return false
path.RemoveAt(path.Count - 1);
return false;
}
// Returns LCA of two nodes.
static Node lca(Node root, int n1, int n2) {
// to store paths to n1 and n2 from the root
List<Node> path1 = new List<Node>();
List<Node> path2 = new List<Node>();
// Find paths from root to n1 and
// root to n2. If either
// n1 or n2 is not present, return null
if (!findPath(root, path1, n1) ||
!findPath(root, path2, n2))
return null;
// Compare the paths to get the first
// different value
int i;
for (i = 0; i < path1.Count && i < path2.Count; i++) {
if (path1[i] != path2[i])
return path1[i - 1];
}
// if both the datas are same, return last node
return path1[i - 1];
}
static void Main(string[] args) {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node ans = lca(root, 4, 5);
if (ans == null)
Console.WriteLine("No common ancestor found");
else
Console.WriteLine(ans.data);
}
}
JavaScript
// Javascript program to find LCA using Arrays to Store
// Paths of Nodes from Root
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Function to find path from root to given node.
function findPath(root, path, k) {
// base case
if (root === null)
return false;
// Store current node value in the path.
path.push(root);
// If node value is equal to k, or
// if node exists in left subtree or
// if node exists in right subtree return true
if (root.data === k ||
findPath(root.left, path, k) ||
findPath(root.right, path, k))
return true;
// else remove root from path and return false
path.pop();
return false;
}
// Returns LCA of two nodes.
function lca(root, n1, n2) {
// to store paths to n1 and n2 from the root
let path1 = [];
let path2 = [];
// Find paths from root to n1 and
// root to n2. If either
// n1 or n2 is not present, return null
if (!findPath(root, path1, n1) ||
!findPath(root, path2, n2))
return null;
// Compare the paths to get the first
// different value
let i;
for (i = 0; i < path1.length && i < path2.length; i++) {
if (path1[i] !== path2[i])
return path1[i - 1];
}
// if both the datas are same, return last node
return path1[i - 1];
}
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
let ans = lca(root, 4, 5);
if (ans === null)
console.log("No common ancestor found");
else
console.log(ans.data);
[Expected Approach] Using Single Traversal - O(n) Time and O(h) Space
Note: This approach assumes that both the keys are present in the given tree.
The idea is to traverse the tree starting from the root. If any of the given keys (n1 and n2) matches with the root, then the root is LCA (assuming that both keys are present). If the root doesn't match with any of the keys, we recur for the left and right subtree. The node which has one key present in its left subtree and the other key present in the right subtree is the LCA, else if, both keys lie in the left subtree, then the left subtree has LCA, else the LCA lies in the right subtree.
Illustration:
Root is pointing to the node with value 1, as its value doesn't match with { 5, 6 }. We look for the key in left subtree and right subtree.
- Left Subtree :
- New Root = { 2 } ≠ 5 or 6, hence we will continue our recursion
- New Root = { 4 } , it's left and right subtree is null, we will return NULL for this call
- New Root = { 5 } , value matches with 5 so will return the node with value 5
- The function call for root with value 2 will return a value of 5
- Right Subtree :
- Root = { 3 } ≠ 5 or 6 hence we continue our recursion
- Root = { 6 } = 5 or 6 , we will return the this node with value 6
- Root = { 7 } ≠ 5 or 6, we will return NULL
- So the function call for root with value 3 will return node with value 6
- As both the left subtree and right subtree of the node with value 1 is not NULL, so 1 is the LCA.
C++
// C++ program to find LCA using Single traversal
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
Node *left, *right;
int data;
Node(int k) {
data = k;
left = nullptr;
right = nullptr;
}
};
// Function to find LCA of two keys.
Node* lca(Node* root, int n1, int n2) {
if (!root)
return nullptr;
// If either key matches with root data, return root
if (root->data == n1 || root->data == n2)
return root;
// Look for datas in left and right subtrees
Node* leftLca = lca(root->left, n1, n2);
Node* rightLca = lca(root->right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca && rightLca)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return leftLca ? leftLca : rightLca;
}
int main() {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node* ans = lca(root, 4, 5);
if(ans == nullptr){
cout<<"No common ancestor found";
}
else{
cout<<ans->data;
}
return 0;
}
C
// C program to find LCA using Single traversal
#include <stdio.h>
#include <stdlib.h>
struct Node {
struct Node *left, *right;
int key;
};
// Function to find LCA of two keys.
struct Node* lca(struct Node* root, int n1, int n2) {
// Base case
if (root == NULL)
return NULL;
// If either key matches with root data, return root
if (root->key == n1 || root->key == n2)
return root;
// Look for keys in left and right subtrees
struct Node* leftLca = lca(root->left, n1, n2);
struct Node* rightLca = lca(root->right, n1, n2);
// If both of the above calls return Non-NULL, then one
// key is present in once subtree and other is present
// in other, So this node is the LCA
if (leftLca && rightLca)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return (leftLca != NULL) ? leftLca : rightLca;
}
struct Node* createnode(int key) {
struct Node* newnode =
(struct Node*)malloc(sizeof(struct Node));
newnode->key = key;
newnode->left = newnode->right = NULL;
return newnode;
}
int main() {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
struct Node* root = createnode(1);
root->left = createnode(2);
root->right = createnode(3);
root->left->left = createnode(4);
root->left->right = createnode(5);
root->right->left = createnode(6);
root->right->right = createnode(7);
struct Node* ans = lca(root, 4, 5);
if(ans == NULL){
printf("No common ancestor found");
}
else{
printf("%d", ans->key);
}
return 0;
}
Java
// Java program to find LCA using Single traversal
class Node {
Node left, right;
int data;
Node(int k) {
data = k;
left = null;
right = null;
}
}
// Function to find LCA of two keys
class GfG {
// Function to find LCA of two keys.
static Node lca(Node root, int n1, int n2) {
if (root == null)
return null;
// If either key matches with root data, return root
if (root.data == n1 || root.data == n2)
return root;
// Look for datas in left and right subtrees
Node leftLca = lca(root.left, n1, n2);
Node rightLca = lca(root.right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca != null && rightLca != null)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return (leftLca != null) ? leftLca : rightLca;
}
public static void main(String[] args) {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node ans = lca(root, 4, 5);
if (ans == null) {
System.out.println("No common ancestor found");
}
else {
System.out.println(ans.data);
}
}
}
Python
# Python program to find LCA using Single traversal
class Node:
def __init__(self, k):
self.data = k
self.left = None
self.right = None
# Function to find LCA of two keys.
def lca(root, n1, n2):
if not root:
return None
# If either key matches with root data, return root
if root.data == n1 or root.data == n2:
return root
# Look for datas in left and right subtrees
leftLca = lca(root.left, n1, n2)
rightLca = lca(root.right, n1, n2)
# If both of the above calls return Non-NULL, then one
# data is present in one subtree and the other is present
# in the other, so this node is the LCA
if leftLca and rightLca:
return root
# Otherwise check if left subtree or right subtree is
# LCA
return leftLca if leftLca else rightLca
if __name__ == "__main__":
# construct the binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
ans = lca(root, 4, 5)
if ans is None:
print("No common ancestor found")
else:
print(ans.data)
C#
// C# program to find LCA using Single traversal
using System;
class Node {
public Node left, right;
public int data;
public Node(int k) {
data = k;
left = null;
right = null;
}
}
// Class to find LCA of two keys
class GfG {
// Function to find LCA of two keys.
static Node lca(Node root, int n1, int n2) {
if (root == null)
return null;
// If either key matches with root data, return root
if (root.data == n1 || root.data == n2)
return root;
// Look for data in left and right subtrees
Node leftLca = lca(root.left, n1, n2);
Node rightLca = lca(root.right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca != null && rightLca != null)
return root;
// Otherwise check if left subtree or right subtree is LCA
return leftLca != null ? leftLca : rightLca;
}
static void Main() {
// Construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node ans = lca(root, 4, 5);
if (ans == null) {
Console.WriteLine("No common ancestor found");
}
else {
Console.WriteLine(ans.data);
}
}
}
JavaScript
// Javascript program to find LCA using Single traversal
class Node {
constructor(k) {
this.left = null;
this.right = null;
this.data = k;
}
}
// Function to find LCA of two keys.
function lca(root, n1, n2) {
if (root === null)
return null;
// If either key matches with root data, return root
if (root.data === n1 || root.data === n2)
return root;
// Look for data in left and right subtrees
let leftLca = lca(root.left, n1, n2);
let rightLca = lca(root.right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca && rightLca)
return root;
// Otherwise check if left subtree or right subtree is LCA
return leftLca ? leftLca : rightLca;
}
// Construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
let ans = lca(root, 4, 5);
if (ans === null) {
console.log("No common ancestor found");
}
else {
console.log(ans.data);
}
Alternate Approach - O(n) Time and O(h) Space
The above method assumes that keys are present in Binary Tree. If one key is present and the other is absent, then it returns the present key as LCA, whereas it ideally should have returned NULL. We can extend the above method to handle all cases by checking if n1 and n2 are present in the tree first and then finding the LCA of n1 and n2. To check whether the node is present in the binary tree or not then traverse on the tree for both n1 and n2 nodes separately.
C++
//C++ Program to find LCA
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
Node *left, *right;
int data;
Node(int k) {
data = k;
left = nullptr;
right = nullptr;
}
};
// Function to find LCA of two datas.
Node* findLca(Node* root, int n1, int n2) {
if (!root)
return nullptr;
// If either data matches with root data, return root
if (root->data == n1 || root->data == n2)
return root;
// Look for datas in left and right subtrees
Node* leftLca = findLca(root->left, n1, n2);
Node* rightLca = findLca(root->right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca && rightLca)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return leftLca ? leftLca : rightLca;
}
// Returns true if key k is present in tree rooted with root
bool checkIfPresent(Node* root, int k) {
// Base Case
if (root == nullptr)
return false;
// If data is present at root, or in left subtree or
// right subtree, return true;
if (root->data == k || checkIfPresent(root->left, k) ||
checkIfPresent(root->right, k))
return true;
// Else return false
return false;
}
// function to check in keys are present
// in the tree and returns the lca.
Node* lca(Node* root, int n1, int n2) {
// Return LCA only if both n1 and n2 are
// present in tree
if (checkIfPresent(root, n1) && checkIfPresent(root, n2))
return findLca(root, n1, n2);
// Else return nullptr
return nullptr;
}
int main() {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node* ans = lca(root, 4, 5);
if(ans == nullptr){
cout<<"No common ancestor found";
}
else{
cout<<ans->data;
}
return 0;
}
Java
// Java Program to find LCA
class Node {
Node left, right;
int data;
Node(int k) {
data = k;
left = null;
right = null;
}
}
// Function to find LCA of two datas.
class GfG {
// Function to find LCA of two datas
static Node findLca(Node root, int n1, int n2) {
if (root == null)
return null;
// If either data matches with root data, return root
if (root.data == n1 || root.data == n2)
return root;
// Look for datas in left and right subtrees
Node leftLca = findLca(root.left, n1, n2);
Node rightLca = findLca(root.right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca != null && rightLca != null)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return leftLca != null ? leftLca : rightLca;
}
// Returns true if key k is present in tree rooted with root
static boolean checkIfPresent(Node root, int k) {
// Base Case
if (root == null)
return false;
// If data is present at root, or in left subtree or
// right subtree, return true;
if (root.data == k || checkIfPresent(root.left, k) ||
checkIfPresent(root.right, k))
return true;
// Else return false
return false;
}
// Function to check if keys are present
// in the tree and returns the lca.
static Node lca(Node root, int n1, int n2) {
// Return LCA only if both n1 and n2 are
// present in tree
if (checkIfPresent(root, n1) && checkIfPresent(root, n2))
return findLca(root, n1, n2);
// Else return null
return null;
}
public static void main(String[] args) {
// Construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node ans = lca(root, 4, 5);
if (ans == null) {
System.out.println("No common ancestor found");
} else {
System.out.println(ans.data);
}
}
}
Python
# Python Program to find LCA
class Node:
def __init__(self, k):
self.data = k
self.left = None
self.right = None
# Function to find LCA of two datas.
def findLca(root, n1, n2):
if not root:
return None
# If either data matches with root data, return root
if root.data == n1 or root.data == n2:
return root
# Look for datas in left and right subtrees
leftLca = findLca(root.left, n1, n2)
rightLca = findLca(root.right, n1, n2)
# If both of the above calls return Non-NULL, then one
# data is present in one subtree and the other is present
# in the other, so this node is the LCA
if leftLca and rightLca:
return root
# Otherwise check if left subtree or right subtree is LCA
return leftLca if leftLca else rightLca
# Returns true if key k is present in tree rooted with root
def checkIfPresent(root, k):
# Base Case
if root is None:
return False
# If data is present at root, or in left subtree or
# right subtree, return true
if (root.data == k or checkIfPresent(root.left, k) or
checkIfPresent(root.right, k)):
return True
# Else return false
return False
# Function to check if keys are present
# in the tree and returns the lca.
def lca(root, n1, n2):
# Return LCA only if both n1 and n2 are
# present in tree
if checkIfPresent(root, n1) and checkIfPresent(root, n2):
return findLca(root, n1, n2)
# Else return None
return None
if __name__ == "__main__":
# Construct the binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
ans = lca(root, 4, 5)
if ans is None:
print("No common ancestor found")
else:
print(ans.data)
C#
// C# Program to find LCA
using System;
class Node {
public Node left, right;
public int data;
public Node(int k) {
data = k;
left = null;
right = null;
}
}
class GfG {
// Function to find LCA of two datas.
static Node findLca(Node root, int n1, int n2) {
if (root == null)
return null;
// If either data matches with root data, return root
if (root.data == n1 || root.data == n2)
return root;
// Look for datas in left and right subtrees
Node leftLca = findLca(root.left, n1, n2);
Node rightLca = findLca(root.right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca != null && rightLca != null)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return leftLca != null ? leftLca : rightLca;
}
// Returns true if key k is present in tree rooted with root
static bool checkIfPresent(Node root, int k) {
// Base Case
if (root == null)
return false;
// If data is present at root, or in left subtree or
// right subtree, return true;
if (root.data == k || checkIfPresent(root.left, k) ||
checkIfPresent(root.right, k))
return true;
// Else return false
return false;
}
// Function to check if keys are present
// in the tree and returns the lca.
static Node lca(Node root, int n1, int n2) {
// Return LCA only if both n1 and n2 are
// present in tree
if (checkIfPresent(root, n1) && checkIfPresent(root, n2))
return findLca(root, n1, n2);
// Else return null
return null;
}
static void Main() {
// Construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node ans = lca(root, 4, 5);
if (ans == null) {
Console.WriteLine("No common ancestor found");
}
else {
Console.WriteLine(ans.data);
}
}
}
JavaScript
// JavaScript Program to find LCA
class Node {
constructor(k) {
this.data = k;
this.left = null;
this.right = null;
}
}
// Function to find LCA of two datas.
function findLca(root, n1, n2) {
if (!root)
return null;
// If either data matches with root data, return root
if (root.data === n1 || root.data === n2)
return root;
// Look for datas in left and right subtrees
var leftLca = findLca(root.left, n1, n2);
var rightLca = findLca(root.right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca && rightLca)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return leftLca ? leftLca : rightLca;
}
// Returns true if key k is present in tree rooted with root
function checkIfPresent(root, k) {
// Base Case
if (root == null)
return false;
// If data is present at root, or in left subtree or
// right subtree, return true;
if (root.data === k || checkIfPresent(root.left, k) ||
checkIfPresent(root.right, k))
return true;
// Else return false
return false;
}
// Function to check if keys are present
// in the tree and returns the lca.
function lca(root, n1, n2) {
// Return LCA only if both n1 and n2 are
// present in tree
if (checkIfPresent(root, n1) && checkIfPresent(root, n2))
return findLca(root, n1, n2);
// Else return null
return null;
}
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
var root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
var ans = lca(root, 4, 5);
if (ans === null) {
console.log("No common ancestor found");
}
else {
console.log(ans.data);
}
Application of Lowest Common Ancestor(LCA)
We use LCA to find the shortest distance between pairs of nodes in a tree: the shortest distance from n1 to n2 can be computed as the distance from the LCA to n1, plus the distance from the LCA to n2.
Related articles:
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem