Lowest Common Ancestor in a Binary Tree using Parent Pointer
Last Updated : 08 May, 2025
Given values of two nodes in a Binary Tree, find the Lowest Common Ancestor (LCA). It may be assumed that both nodes exist in the tree.
For example, consider the Binary Tree in diagram, LCA of 10 and 14 is 12 and LCA of 8 and 14 is 8.
Let T be a rooted tree. The lowest common ancestor between two nodes n1 and n2 is defined as the lowest node in T that has both n1 and n2 as descendants (where we allow a node to be a descendant of itself). Source : Wikipedia.
We have discussed different approaches to find LCA in set 1. Finding LCA becomes easy when parent pointer is given as we can easily find all ancestors of a node using parent pointer. Below are steps to find LCA.
- Create an empty hash table.
- Insert n1 and all of its ancestors in hash table.
- Check if n2 or any of its ancestors exist in hash table, if yes return the first existing ancestor.
Below is the implementation of above steps.
C++14 // C++ program to find lowest common ancestor using parent pointer #include <bits/stdc++.h> using namespace std; // A Tree Node struct Node { Node *left, *right, *parent; int key; }; // A utility function to create a new BST node Node *newNode(int item) { Node *temp = new Node; temp->key = item; temp->parent = temp->left = temp->right = NULL; return temp; } /* A utility function to insert a new node with given key in Binary Search Tree */ Node *insert(Node *node, int key) { /* If the tree is empty, return a new node */ if (node == NULL) return newNode(key); /* Otherwise, recur down the tree */ if (key < node->key) { node->left = insert(node->left, key); node->left->parent = node; } else if (key > node->key) { node->right = insert(node->right, key); node->right->parent = node; } /* return the (unchanged) node pointer */ return node; } // To find LCA of nodes n1 and n2 in Binary Tree Node *LCA(Node *n1, Node *n2) { // Create a map to store ancestors of n1 map <Node *, bool> ancestors; // Insert n1 and all its ancestors in map while (n1 != NULL) { ancestors[n1] = true; n1 = n1->parent; } // Check if n2 or any of its ancestors is in // map. while (n2 != NULL) { if (ancestors.find(n2) != ancestors.end()) return n2; n2 = n2->parent; } return NULL; } // Driver method to test above functions int main(void) { Node * root = NULL; root = insert(root, 20); root = insert(root, 8); root = insert(root, 22); root = insert(root, 4); root = insert(root, 12); root = insert(root, 10); root = insert(root, 14); Node *n1 = root->left->right->left; Node *n2 = root->left; Node *lca = LCA(n1, n2); printf("LCA of %d and %d is %d \n", n1->key, n2->key, lca->key); return 0; }
Java import java.util.HashMap; import java.util.Map; // Java program to find lowest common ancestor using parent pointer // A tree node class Node { int key; Node left, right, parent; Node(int key) { this.key = key; left = right = parent = null; } } class BinaryTree { Node root, n1, n2, lca; /* A utility function to insert a new node with given key in Binary Search Tree */ Node insert(Node node, int key) { /* If the tree is empty, return a new node */ if (node == null) return new Node(key); /* Otherwise, recur down the tree */ if (key < node.key) { node.left = insert(node.left, key); node.left.parent = node; } else if (key > node.key) { node.right = insert(node.right, key); node.right.parent = node; } /* return the (unchanged) node pointer */ return node; } // To find LCA of nodes n1 and n2 in Binary Tree Node LCA(Node n1, Node n2) { // Create a map to store ancestors of n1 Map<Node, Boolean> ancestors = new HashMap<Node, Boolean>(); // Insert n1 and all its ancestors in map while (n1 != null) { ancestors.put(n1, Boolean.TRUE); n1 = n1.parent; } // Check if n2 or any of its ancestors is in // map. while (n2 != null) { if (ancestors.containsKey(n2) != ancestors.isEmpty()) return n2; n2 = n2.parent; } return null; } // Driver method to test above functions public static void main(String[] args) { BinaryTree tree = new BinaryTree(); tree.root = tree.insert(tree.root, 20); tree.root = tree.insert(tree.root, 8); tree.root = tree.insert(tree.root, 22); tree.root = tree.insert(tree.root, 4); tree.root = tree.insert(tree.root, 12); tree.root = tree.insert(tree.root, 10); tree.root = tree.insert(tree.root, 14); tree.n1 = tree.root.left.right.left; tree.n2 = tree.root.left; tree.lca = tree.LCA(tree.n1, tree.n2); System.out.println("LCA of " + tree.n1.key + " and " + tree.n2.key + " is " + tree.lca.key); } } // This code has been contributed by Mayank Jaiswal(mayank_24)
Python # Python program to find lowest common ancestor using parent pointer global root root = None # A Tree Node class Node: def __init__(self, key): self.key = key self.left = None self.right = None self.parent = None # A utility function to insert a new node with given key in Binary Search Tree def insert(root, key): # If the tree is empty, return a new node if root == None: return Node(key) # Otherwise, recur down the tree if key < root.key: root.left = insert(root.left, key) root.left.parent = root elif key > root.key: root.right = insert(root.right, key) root.right.parent = root # return the (unchanged) node pointer return root # To find LCA of nodes n1 and n2 in Binary Tree def LCA(n1, n2): # Create a map to store ancestors of n1 ancestors = {} # Insert n1 and all its ancestors in map while n1 != None: ancestors[n1] = True n1 = n1.parent # Check if n2 or any of its ancestors is in map. while n2 != None: if n2 in ancestors: return n2 n2 = n2.parent return None # Driver method to test above functions if __name__ == '__main__': root = insert(root, 20) root = insert(root, 8) root = insert(root, 22) root = insert(root, 4) root = insert(root, 12) root = insert(root, 10) root = insert(root, 14) n1 = root.left.right.left n2 = root.left lca = LCA(n1, n2) print("LCA of", n1.key, "and", n2.key, "is", lca.key) # This code is contributed by Tapesh(tapeshdua420)
C# // C# program to find lowest common ancestor using parent pointer // A tree node using System; using System.Collections; using System.Collections.Generic; public class Node { public int key; public Node left, right, parent; public Node(int key) { this.key = key; left = right = parent = null; } } class BinaryTree { Node root, n1, n2, lca; /* A utility function to insert a new node with given key in Binary Search Tree */ Node insert(Node node, int key) { /* If the tree is empty, return a new node */ if (node == null) return new Node(key); /* Otherwise, recur down the tree */ if (key < node.key) { node.left = insert(node.left, key); node.left.parent = node; } else if (key > node.key) { node.right = insert(node.right, key); node.right.parent = node; } /* return the (unchanged) node pointer */ return node; } // To find LCA of nodes n1 and n2 in Binary Tree Node LCA(Node n1, Node n2) { // Create a map to store ancestors of n1 Dictionary<Node, Boolean> ancestors = new Dictionary<Node, Boolean>(); // Insert n1 and all its ancestors in map while (n1 != null) { ancestors.Add(n1,true); n1 = n1.parent; } // Check if n2 or any of its ancestors is in // map. while (n2 != null) { if (ancestors.ContainsKey(n2)) return n2; n2 = n2.parent; } return null; } // Driver code public static void Main(String []args) { BinaryTree tree = new BinaryTree(); tree.root = tree.insert(tree.root, 20); tree.root = tree.insert(tree.root, 8); tree.root = tree.insert(tree.root, 22); tree.root = tree.insert(tree.root, 4); tree.root = tree.insert(tree.root, 12); tree.root = tree.insert(tree.root, 10); tree.root = tree.insert(tree.root, 14); tree.n1 = tree.root.left.right.left; tree.n2 = tree.root.left; tree.lca = tree.LCA(tree.n1, tree.n2); Console.WriteLine("LCA of " + tree.n1.key + " and " + tree.n2.key + " is " + tree.lca.key); } } // This code is contributed by Arnab Kundu
JavaScript // Javascript code for above approach // A Tree Node class Node { constructor(left, right, parent, key) { this.left = left; this.right = right; this.parent = parent; this.key = key; } } // A utility function to create a new BST node function newNode(item) { let temp = new Node(); temp.key = item; temp.parent = temp.left = temp.right = null; return temp; } /* A utility function to insert a new node with given key in Binary Search Tree */ function insert(node, key) { /* If the tree is empty, return a new node */ if (node == null) return newNode(key); /* Otherwise, recur down the tree */ if (key < node.key) { node.left = insert(node.left, key); node.left.parent = node; } else if (key > node.key) { node.right = insert(node.right, key); node.right.parent = node; } /* return the (unchanged) node pointer */ return node; } // To find LCA of nodes n1 and n2 in Binary Tree function LCA(n1, n2) { // Create a map to store ancestors of n1 let ancestors = new Map(); // Insert n1 and all its ancestors in map while (n1 != null) { ancestors.set(n1, true); n1 = n1.parent; } // Check if n2 or any of its ancestors is in // map. while (n2 != null) { if (ancestors.has(n2)) return n2; n2 = n2.parent; } return null; } // Driver method to test above functions let root = null; root = insert(root, 20); root = insert(root, 8); root = insert(root, 22); root = insert(root, 4); root = insert(root, 12); root = insert(root, 10); root = insert(root, 14); let n1 = root.left.right.left; let n2 = root.left; let lca = LCA(n1, n2); console.log(`LCA of ${n1.key} and ${n2.key} is ${lca.key}`); // This code is contributed by adityamaharshi21
Output:
LCA of 10 and 8 is 8
Note : The above implementation uses insert of Binary Search Tree to create a Binary Tree, but the function LCA is for any Binary Tree (not necessarily a Binary Search Tree). Time Complexity : O(h) where h is height of Binary Tree if we use hash table to implement the solution (Note that the above solution uses map which takes O(Log h) time to insert and find). So the time complexity of above implementation is O(h Log h). Auxiliary Space : O(h) A O(h) time and O(1) Extra Space Solution: The above solution requires extra space because we need to use a hash table to store visited ancestors. We can solve the problem in O(1) extra space using following fact : If both nodes are at same level and if we traverse up using parent pointers of both nodes, the first common node in the path to root is lca. The idea is to find depths of given nodes and move up the deeper node pointer by the difference between depths. Once both nodes reach same level, traverse them up and return the first common node. Thanks to Mysterious Mind for suggesting this approach.
C++ // C++ program to find lowest common ancestor using parent pointer #include <bits/stdc++.h> using namespace std; // A Tree Node struct Node { Node *left, *right, *parent; int key; }; // A utility function to create a new BST node Node *newNode(int item) { Node *temp = new Node; temp->key = item; temp->parent = temp->left = temp->right = NULL; return temp; } /* A utility function to insert a new node with given key in Binary Search Tree */ Node *insert(Node *node, int key) { /* If the tree is empty, return a new node */ if (node == NULL) return newNode(key); /* Otherwise, recur down the tree */ if (key < node->key) { node->left = insert(node->left, key); node->left->parent = node; } else if (key > node->key) { node->right = insert(node->right, key); node->right->parent = node; } /* return the (unchanged) node pointer */ return node; } // A utility function to find depth of a node // (distance of it from root) int depth(Node *node) { int d = -1; while (node) { ++d; node = node->parent; } return d; } // To find LCA of nodes n1 and n2 in Binary Tree Node *LCA(Node *n1, Node *n2) { // Find depths of two nodes and differences int d1 = depth(n1), d2 = depth(n2); int diff = d1 - d2; // If n2 is deeper, swap n1 and n2 if (diff < 0) { Node * temp = n1; n1 = n2; n2 = temp; diff = -diff; } // Move n1 up until it reaches the same level as n2 while (diff--) n1 = n1->parent; // Now n1 and n2 are at same levels while (n1 && n2) { if (n1 == n2) return n1; n1 = n1->parent; n2 = n2->parent; } return NULL; } // Driver method to test above functions int main(void) { Node * root = NULL; root = insert(root, 20); root = insert(root, 8); root = insert(root, 22); root = insert(root, 4); root = insert(root, 12); root = insert(root, 10); root = insert(root, 14); Node *n1 = root->left->right->left; Node *n2 = root->right; Node *lca = LCA(n1, n2); printf("LCA of %d and %d is %d \n", n1->key, n2->key, lca->key); return 0; }
Java import java.util.HashMap; import java.util.Map; // Java program to find lowest common ancestor using parent pointer // A tree node class Node { int key; Node left, right, parent; Node(int key) { this.key = key; left = right = parent = null; } } class BinaryTree { Node root, n1, n2, lca; /* A utility function to insert a new node with given key in Binary Search Tree */ Node insert(Node node, int key) { /* If the tree is empty, return a new node */ if (node == null) return new Node(key); /* Otherwise, recur down the tree */ if (key < node.key) { node.left = insert(node.left, key); node.left.parent = node; } else if (key > node.key) { node.right = insert(node.right, key); node.right.parent = node; } /* return the (unchanged) node pointer */ return node; } // A utility function to find depth of a node // (distance of it from root) int depth(Node node) { int d = -1; while (node != null) { ++d; node = node.parent; } return d; } // To find LCA of nodes n1 and n2 in Binary Tree Node LCA(Node n1, Node n2) { // Find depths of two nodes and differences int d1 = depth(n1), d2 = depth(n2); int diff = d1 - d2; // If n2 is deeper, swap n1 and n2 if (diff < 0) { Node temp = n1; n1 = n2; n2 = temp; diff = -diff; } // Move n1 up until it reaches the same level as n2 while (diff-- != 0) n1 = n1.parent; // Now n1 and n2 are at same levels while (n1 != null && n2 != null) { if (n1 == n2) return n1; n1 = n1.parent; n2 = n2.parent; } return null; } // Driver method to test above functions public static void main(String[] args) { BinaryTree tree = new BinaryTree(); tree.root = tree.insert(tree.root, 20); tree.root = tree.insert(tree.root, 8); tree.root = tree.insert(tree.root, 22); tree.root = tree.insert(tree.root, 4); tree.root = tree.insert(tree.root, 12); tree.root = tree.insert(tree.root, 10); tree.root = tree.insert(tree.root, 14); tree.n1 = tree.root.left.right.left; tree.n2 = tree.root.right; tree.lca = tree.LCA(tree.n1, tree.n2); System.out.println("LCA of " + tree.n1.key + " and " + tree.n2.key + " is " + tree.lca.key); } } // This code has been contributed by Mayank Jaiswal(mayank_24)
Python # Python program to find lowest common ancestor using parent pointer # A tree node class Node: def __init__(self, key): self.key = key self.left = None self.right = None self.parent = None class BinaryTree: def __init__(self): self.root = None self.n1 = None self.n2 = None self.lca = None # A utility function to insert a new node with # given key in Binary Search Tree def insert(self, node, key): # If the tree is empty, return a new node if node == None: return Node(key) # Otherwise, recur down the tree if key < node.key: node.left = self.insert(node.left, key) node.left.parent = node elif key > node.key: node.right = self.insert(node.right, key) node.right.parent = node # return the (unchanged) node pointer return node # A utility function to find depth of a node (distance of it from root) def depth(self, node): d = -1 while(node != None): d += 1 node = node.parent return d # To find LCA of nodes n1 and n2 in Binary Tree def LCA(self, n1, n2): # Find depths of two nodes and differences d1 = self.depth(n1) d2 = self.depth(n2) diff = d1-d2 # If n2 is deeper, swap n1 and n2 if diff < 0: temp = n1 n1 = n2 n2 = temp diff = -diff # Move n1 up until it reaches the same level as n2 while diff != 0: n1 = n1.parent diff -= 1 # Now n1 and n2 are at same levels while n1 != None and n2 != None: if (n1 == n2): return n1 n1 = n1.parent n2 = n2.parent return None # Driver method to test above functions if __name__ == '__main__': tree = BinaryTree() tree.root = tree.insert(tree.root, 20) tree.root = tree.insert(tree.root, 8) tree.root = tree.insert(tree.root, 22) tree.root = tree.insert(tree.root, 4) tree.root = tree.insert(tree.root, 12) tree.root = tree.insert(tree.root, 10) tree.root = tree.insert(tree .root, 14) tree.n1 = tree.root.left.right.left tree.n2 = tree.root.right tree.lca = tree.LCA(tree.n1, tree.n2) print("LCA of " + str(tree.n1.key) + " and " + str(tree.n2.key) + " is " + str(tree .lca .key)) # This code is contributed by Tapesh(tapesh1308)
C# // C# program to find lowest common // ancestor using parent pointer using System; // A tree node public class Node { public int key; public Node left, right, parent; public Node(int key) { this.key = key; left = right = parent = null; } } class GFG { public Node root, n1, n2, lca; /* A utility function to insert a new node with given key in Binary Search Tree */ public virtual Node insert(Node node, int key) { /* If the tree is empty, return a new node */ if (node == null) { return new Node(key); } /* Otherwise, recur down the tree */ if (key < node.key) { node.left = insert(node.left, key); node.left.parent = node; } else if (key > node.key) { node.right = insert(node.right, key); node.right.parent = node; } /* return the (unchanged) node pointer */ return node; } // A utility function to find depth of a // node (distance of it from root) public virtual int depth(Node node) { int d = -1; while (node != null) { ++d; node = node.parent; } return d; } // To find LCA of nodes n1 and n2 // in Binary Tree public virtual Node LCA(Node n1, Node n2) { // Find depths of two nodes // and differences int d1 = depth(n1), d2 = depth(n2); int diff = d1 - d2; // If n2 is deeper, swap n1 and n2 if (diff < 0) { Node temp = n1; n1 = n2; n2 = temp; diff = -diff; } // Move n1 up until it reaches // the same level as n2 while (diff-- != 0) { n1 = n1.parent; } // Now n1 and n2 are at same levels while (n1 != null && n2 != null) { if (n1 == n2) { return n1; } n1 = n1.parent; n2 = n2.parent; } return null; } // Driver Code public static void Main(string[] args) { GFG tree = new GFG(); tree.root = tree.insert(tree.root, 20); tree.root = tree.insert(tree.root, 8); tree.root = tree.insert(tree.root, 22); tree.root = tree.insert(tree.root, 4); tree.root = tree.insert(tree.root, 12); tree.root = tree.insert(tree.root, 10); tree.root = tree.insert(tree.root, 14); tree.n1 = tree.root.left.right.left; tree.n2 = tree.root.right; tree.lca = tree.LCA(tree.n1, tree.n2); Console.WriteLine("LCA of " + tree.n1.key + " and " + tree.n2.key + " is " + tree.lca.key); } } // This code is contributed by Shrikant13
JavaScript // Javascript code for above approach // A Tree Node class Node { constructor(left, right, parent, key) { this.left = left; this.right = right; this.parent = parent; this.key = key; } } // A utility function to create a new BST node function newNode(item) { let temp = new Node(); temp.key = item; temp.parent = temp.left = temp.right = null; return temp; } // A utility function to insert a new node with // given key in Binary Search Tree function insert(node, key){ // If the tree is empty, return a new node if (node == null) return newNode(key); // Otherwise, recur down the tree if (key < node.key){ node.left = insert(node.left, key); node.left.parent = node; } else if (key > node.key){ node.right = insert(node.right, key); node.right.parent = node; } // return the (unchanged) node pointer return node; } // A utility function to find depth of a node // (distance of it from root) function depth(node){ let d = -1; while(node){ ++d; node = node.parent; } return d; } // To find LCA of nodes n1 and n2 in Binary Tree function LCA(n1, n2){ // Find depths of two nodes and differences let d1 = depth(n1), d2 = depth(n2); let diff = d1 - d2; // If n2 is deeper, swap n1 and n2 if (diff < 0){ let temp = n1; n1 = n2; n2 = temp; diff = -diff; } // Move n1 up until it reaches the same level as n2 while (diff--) n1 = n1.parent; // Now n1 and n2 are at same levels while (n1 && n2){ if (n1 == n2) return n1; n1 = n1.parent; n2 = n2.parent; } return null; } // Driver method to test above functions let root = null; root = insert(root, 20); root = insert(root, 8); root = insert(root, 22); root = insert(root, 4); root = insert(root, 12); root = insert(root, 10); root = insert(root, 14); let n1 = root.left.right.left; let n2 = root.right; let lca = LCA(n1, n2); console.log(`LCA of ${n1.key} and ${n2.key} is ${lca.key}`); // this code is contributed by Yash Agarwal(yashagarwal2852002)
Output :
LCA of 10 and 22 is 20
Time Complexity : O(h)
Space Complexity : O(1)
You may like to see below articles as well : Lowest Common Ancestor in a Binary Tree | Set 1 Lowest Common Ancestor in a Binary Search Tree. Find LCA in Binary Tree using RMQ
Similar Reads
Lowest Common Ancestor in a Binary Tree | Set 3 (Using RMQ)
Given a rooted tree, and two nodes are in the tree, find the Lowest common ancestor of both the nodes. The LCA for two nodes u and v is defined as the farthest node from the root that is the ancestor to both u and v. Prerequisites: LCA | SET 1 Example for the above figure : Input : 4 5 Output : 2 In
15+ min read
Lowest Common Ancestor in a Binary Tree
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
15+ min read
Lowest Common Ancestor in Parent Array Representation
Given a binary tree represented as parent array, find Lowest Common Ancestor between two nodes 'm' and 'n'. In the above diagram, LCA of 10 and 14 is 12 and LCA of 10 and 12 is 12. Make a parent array and store the parent of ith node in it. Parent of root node should be -1. Now, access all the nodes
6 min read
LCA in BST - Lowest Common Ancestor in Binary Search Tree
Given two nodes n1 and n2 of a Binary Search Tree, find the Lowest Common Ancestor (LCA). You may assume that both values exist in the tree. The Lowest Common Ancestor between two nodes n1 and n2 is defined as the lowest node that has both n1 and n2 as descendants (where we allow a node to be a desc
15+ min read
Least Common Ancestor of any number of nodes in Binary Tree
Given a binary tree (not a binary search tree) and any number of Key Nodes, the task is to find the least common ancestor of all the key Nodes. Following is the definition of LCA from Wikipedia: Let T be a rooted tree. The lowest common ancestor between two nodes n1 and n2 is defined as the lowest n
9 min read
Lowest Common Ancestor of the deepest leaves of a Binary Tree
Given a Binary Tree consisting of N nodes having distinct values from the range [1, N], the task is to find the lowest common ancestor of the deepest leaves of the binary tree. Examples: Input: Output: 1Explanation: The deepest leaf nodes of the tree are {8, 9, 10}. Lowest common ancestor of these n
10 min read
Print Ancestors of a given node in Binary Tree
Given a Binary Tree and a key, write a function that prints all the ancestors of the key in the given binary tree. For example, if the given tree is following Binary Tree and the key is 7, then your function should print 4, 2, and 1. 1 / \ 2 3 / \ 4 5 / 7Recommended PracticeAncestors in Binary TreeT
13 min read
Construct Ancestor Matrix from a Given Binary Tree
Given a Binary Tree where all values are from 0 to n-1. Construct an ancestor matrix mat[n][n] where the ancestor matrix is defined as below. mat[i][j] = 1 if i is ancestor of jmat[i][j] = 0, otherwiseExamples: Input: Output: {{0 1 1} {0 0 0} {0 0 0}}Input: Output: {{0 0 0 0 0 0} {1 0 0 0 1 0} {0 0
15+ min read
Print path between any two nodes in a Binary Tree
Given a Binary Tree of distinct nodes and a pair of nodes. The task is to find and print the path between the two given nodes in the binary tree. For Example, in the above binary tree the path between the nodes 7 and 4 is 7 -> 3 -> 1 -> 4. The idea is to find paths from root nodes to the tw
12 min read
Lowest Common Ancestor for a Set of Nodes in a Rooted Tree
Given a rooted tree with N nodes, the task is to find the Lowest Common Ancestor for a given set of nodes V of that tree. Examples: Input: 1 / | \ 2 3 4 / \ | | 5 6 7 10 / \ 8 9 V[] = {7, 3, 8, 9} Output: 3 Input: 1 / | \ 2 3 4 / \ | | 5 6 7 10 / \ 8 9 V[] = {4, 6, 7} Output: 1 Approach: We can obse
12 min read