Lowest Common Ancestor in a Binary Tree | Set 3 ( Using RMQ ) | JAVA code to find LCA of given two nodes in a tree ; the graph ; level of each node ; the segment tree ; adding edges to the graph ( tree ) ; assigning level to nodes ; storing the dfs traversal in the array e ; making the array l ; making the array h ; if is already stored ; Range minimum query to return the index of minimum in the subarray L [ qs : qe ] ; out of range ; in the range ; constructs the segment tree ; leaf ; Function to get LCA ; Driver code ; n = number of nodes in the tree q = number of queries to answer ; 1 / | \ 2 3 4 | \ 5 6 / | \ 8 7 9 ( right of 5 ) / | \ | \ 10 11 12 13 14 | 15
import java . util . * ; public class GFG { static int maxn = 100005 ; static int left ( int i ) { return ( 2 * i + 1 ) ; } static int right ( int i ) { return 2 * i + 2 ; } static Vector < Integer > [ ] g = new Vector [ maxn ] ; static int [ ] level = new int [ maxn ] ; static Vector < Integer > e = new Vector < > ( ) ; static Vector < Integer > l = new Vector < > ( ) ; static int [ ] h = new int [ maxn ] ; static int [ ] st = new int [ 5 * maxn ] ; static void add_edge ( int u , int v ) { g [ u ] . add ( v ) ; g [ v ] . add ( u ) ; } static void levelling ( int src ) { for ( int i = 0 ; i < ( g [ src ] . size ( ) ) ; i ++ ) { int des = g [ src ] . get ( i ) ; if ( level [ des ] != 0 ) { level [ des ] = level [ src ] + 1 ; leveling ( des ) ; } } } static boolean [ ] visited = new boolean [ maxn ] ; static void dfs ( int src ) { e . add ( src ) ; visited [ src ] = true ; for ( int i = 0 ; i < ( g [ src ] ) . size ( ) ; i ++ ) { int des = g [ src ] . get ( i ) ; if ( ! visited [ des ] ) { dfs ( des ) ; e . add ( src ) ; } } } static void setting_l ( int n ) { for ( int i = 0 ; i < e . size ( ) ; i ++ ) l . add ( level [ e . get ( i ) ] ) ; } static void setting_h ( int n ) { for ( int i = 0 ; i <= n ; i ++ ) h [ i ] = - 1 ; for ( int i = 0 ; i < e . size ( ) ; i ++ ) { if ( h [ e . get ( i ) ] == - 1 ) h [ e . get ( i ) ] = i ; } } static int RMQ ( int ss , int se , int qs , int qe , int i ) { if ( ss > se ) return - 1 ; if ( se < qs qe < ss ) return - 1 ; if ( qs <= ss && se <= qe ) return st [ i ] ; int mid = ( ss + se ) / 2 ; int st = RMQ ( ss , mid , qs , qe , left ( i ) ) ; int en = RMQ ( mid + 1 , se , qs , qe , right ( i ) ) ; if ( st != - 1 && en != - 1 ) { if ( l . get ( st ) < l . get ( en ) ) return st ; return en ; } else if ( st != - 1 ) return st - 2 ; else if ( en != - 1 ) return en - 1 ; return 0 ; } static void SegmentTreeConstruction ( int ss , int se , int i ) { if ( ss > se ) return ; if ( ss == se ) { st [ i ] = ss ; return ; } int mid = ( ss + se ) / 2 ; SegmentTreeConstruction ( ss , mid , left ( i ) ) ; SegmentTreeConstruction ( mid + 1 , se , right ( i ) ) ; if ( l . get ( st [ left ( i ) ] ) < l . get ( st [ right ( i ) ] ) ) st [ i ] = st [ left ( i ) ] ; else st [ i ] = st [ right ( i ) ] ; } static int LCA ( int x , int y ) { if ( h [ x ] > h [ y ] ) { int t = x ; x = y ; y = t ; } return e . get ( RMQ ( 0 , l . size ( ) - 1 , h [ x ] , h [ y ] , 0 ) ) ; } public static void main ( String [ ] args ) { int n = 15 , q = 5 ; for ( int i = 0 ; i < g . length ; i ++ ) g [ i ] = new Vector < Integer > ( ) ; add_edge ( 1 , 2 ) ; add_edge ( 1 , 3 ) ; add_edge ( 1 , 4 ) ; add_edge ( 3 , 5 ) ; add_edge ( 4 , 6 ) ; add_edge ( 5 , 7 ) ; add_edge ( 5 , 8 ) ; add_edge ( 5 , 9 ) ; add_edge ( 7 , 10 ) ; add_edge ( 7 , 11 ) ; add_edge ( 7 , 12 ) ; add_edge ( 9 , 13 ) ; add_edge ( 9 , 14 ) ; add_edge ( 12 , 15 ) ; level [ 1 ] = 1 ; leveling ( 1 ) ; dfs ( 1 ) ; setting_l ( n ) ; setting_h ( n ) ; SegmentTreeConstruction ( 0 , l . size ( ) - 1 , 0 ) ; System . out . print ( LCA ( 10 , 15 ) + "NEW_LINE"); System . out . print ( LCA ( 11 , 14 ) + "NEW_LINE"); } }