Given an integer n. There is a complete binary tree with 2n – 1 nodes. The root of that tree is the node with the value 1, and every node with a value x has two children where the left node has the value
2*x and the right node has the value 2*x + 1, you are given K queries of type (ai, bi), and the task is to return the LCA for the node pair ai and bi for all K queries.
Examples:
Input: n = 5, queries = [ { 17, 21 }, { 23, 5 }, { 15, 7 }, { 3, 21 }, { 31, 9 }, { 5, 15 }, { 11, 2 }, { 19, 7 } ]
Output: [ 2, 5, 7, 1, 1, 1, 2, 1 ]
Input: n = 3, queries = [ {2, 5}, {3, 6}, {4, 1}, {7, 3} ]
Output: [2, 3, 1, 3]
Approach: The problem can be solved based on the following idea:
As all values on a level are smaller than values on the next level. Check which node is having greater value in a query, and divide it by 2 to reach its parent node. Repeat this step until we get common element.
Follow the steps to solve the problem:
- In a query, we are having 2 nodes a and b, whose lowest common ancestor we have to find.
- By dividing the value of the node by 2, we will always get the parent node value.
- From a and b whichever node is having greater value divide by 2. So, as to move towards the root of the root.
- When a and b becomes equal, the common ancestor between them is got and returned.
Below is the implementation for the approach discussed:
// C++ code for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find lca for // given two nodes in tree int helper( int a, int b)
{ while (a != b) {
if (a > b)
a = a / 2;
else
b = b / 2;
}
return a;
} // Driver code int main()
{ // 2^n - 1 nodes in complete
// binary tree
int n = 5;
// Queries input vector
vector<vector< int > > queries
= { { 17, 21 }, { 23, 5 }, { 15, 7 }, { 3, 21 }, { 31, 9 }, { 5, 15 }, { 11, 2 }, { 19, 7 } };
// Processing each query in
// queries vector
for ( auto e : queries) {
// Function call
int lca = helper(e[0], e[1]);
cout << lca << ' ' ;
}
return 0;
} |
// Java code for the above approach import java.io.*;
class GFG {
// Function to find lca for
// given two nodes in tree
public static int helper( int a, int b)
{
while (a != b) {
if (a > b)
a = a / 2 ;
else
b = b / 2 ;
}
return a;
}
// Driver Code
public static void main(String[] args)
{
// 2^n - 1 nodes in complete
// binary tree
int n = 5 ;
// Queries input vector
int queries[][] = { { 17 , 21 }, { 23 , 5 },
{ 15 , 7 }, { 3 , 21 },
{ 31 , 9 }, { 5 , 15 },
{ 11 , 2 }, { 19 , 7 } };
// Processing each query in
// queries vector
for ( int e[] : queries) {
// Function call
int lca = helper(e[ 0 ], e[ 1 ]);
System.out.print(lca + " " );
}
}
} // This code is contributed by Rohit Pradhan |
using System;
using System.Collections.Generic;
class Program
{ // Function to find lca for
// given two nodes in tree
static int helper( int a, int b)
{
while (a != b)
{
if (a > b)
a = a / 2;
else
b = b / 2;
}
return a;
}
// Driver code
static void Main( string [] args)
{
// 2^n - 1 nodes in complete
// binary tree
int n = 5;
// Queries input vector
List<List< int >> queries = new List<List< int >> {
new List< int > { 17, 21 },
new List< int > { 23, 5 },
new List< int > { 15, 7 },
new List< int > { 3, 21 },
new List< int > { 31, 9 },
new List< int > { 5, 15 },
new List< int > { 11, 2 },
new List< int > { 19, 7 }
};
// Processing each query in
// queries vector
foreach ( var e in queries)
{
// Function call
int lca = helper(e[0], e[1]);
Console.Write(lca + " " );
}
}
} // code by ksam24000 |
// Function to find lca for // given two nodes in tree function helper(a, b) {
while (a != b) {
if (a > b)
a = Math.floor(a / 2);
else
b = Math.floor(b / 2);
}
return a;
} // Driver code console.log( "LCA(s):" );
// 2^n - 1 nodes in complete // binary tree let n = 5; // Queries input array let queries = [ [ 17, 21 ], [ 23, 5 ], [ 15, 7 ], [ 3, 21 ], [ 31, 9 ], [ 5, 15 ], [ 11, 2 ], [ 19, 7 ] ]; // Processing each query in // queries array for (let i = 0; i < queries.length; i++) {
let e = queries[i];
// Function call
let lca = helper(e[0], e[1]);
console.log(lca + ' ' );
} |
# Function to find lca for # given two nodes in tree def helper(a, b):
while (a ! = b):
if (a > b):
a = a / / 2
else :
b = b / / 2
return a
# Driver code print ( "LCA(s):" )
# 2^n - 1 nodes in complete # binary tree n = 5
# Queries input list queries = [ [ 17 , 21 ], [ 23 , 5 ], [ 15 , 7 ], [ 3 , 21 ], [ 31 , 9 ], [ 5 , 15 ], [ 11 , 2 ], [ 19 , 7 ] ]
# Processing each query in # queries list for e in queries:
# Function call
lca = helper(e[ 0 ], e[ 1 ])
print (lca, end = ' ' )
|
2 5 7 1 1 1 2 1
Time Complexity: O(log2(max(a,b)), here we divide number a or b every time with 2 so it will cost log2() complexity and here we are doing it for a and b so a max of(a,b) will be the number which takes worst time so overall time complexity will be O(log2(max(a,b))) to find LCA of two node a&b.
Auxiliary Space: O(1)
Related Articles: