Queries to check if the path between two nodes in a tree is a palindrome | JavaScript implementation of the approach ; Function that returns true if a palindromic string can be formed using the given characters ; Count odd occurring characters ; Return false if odd count is more than 1 , ; Find to find the Lowest Common Ancestor in the tree ; Base case ; Base case ; Initially value - 1 denotes that we need to find the ancestor ; - 1 denotes that we need to find the lca for x and y , values other than x and y will be the LCA of x and y ; Iterating in the child substree of the currentNode ; Next node that will be checked ; Look for the next child subtree ; Both the nodes exist in the different subtrees , in this case parent node will be the lca ; Handle the cases where LCA is already calculated or both x and y are present in the same subtree ; Function to calculate the character count for each path from node i to 1 ( root node ) ; Updating the character count for each node ; Look for the child subtree ; Function that returns true if a palindromic path is possible between the nodes x and y ; If both x and y are same then lca will be the node itself ; Find the lca of x and y ; Calculating the character count for path node x to y ; Checking if we can form the palindrome string with the all character count ; Function to update character count at node v ; Updating the character count at node v ; Function to perform the queries ; If path can be a palindrome ; Fill the complete array with 0 ; Edge between 1 and 2 labelled " bbc " ; Edge between 1 and 3 labelled " ac " ; Update the character count from root to the ith node ; Perform the queries
let MAX_SIZE = 100005 , MAX_CHAR = 26 ; let nodeCharactersCount = new Array ( MAX_SIZE ) ; let tree = new Array ( MAX_SIZE ) ; function canFormPalindrome ( charArray ) { let oddCount = 0 ; for ( let i = 0 ; i < MAX_CHAR ; i ++ ) { if ( charArray [ i ] % 2 == 1 ) oddCount ++ ; } if ( oddCount >= 2 ) return false ; else return true ; } function LCA ( currentNode , x , y ) { if ( currentNode == x ) return x ; if ( currentNode == y ) return y ; let xLca , yLca ; xLca = yLca = - 1 ; let gotLca = - 1 ; for ( let l = 0 ; l < tree [ currentNode ] . length ; l ++ ) { let nextNode = tree [ currentNode ] [ l ] ; let out_ = LCA ( nextNode , x , y ) ; if ( out_ == x ) xLca = out_ ; if ( out_ == y ) yLca = out_ ; if ( xLca != - 1 && yLca != - 1 ) return currentNode ; if ( out_ != - 1 ) gotLca = out_ ; } return gotLca ; } function buildTree ( i ) { for ( let l = 0 ; l < tree [ i ] . length ; l ++ ) { let nextNode = tree [ i ] [ l ] ; for ( let j = 0 ; j < MAX_CHAR ; j ++ ) { nodeCharactersCount [ nextNode ] [ j ] += nodeCharactersCount [ i ] [ j ] ; } buildTree ( nextNode ) ; } } function canFormPalindromicPath ( x , y ) { let lcaNode ; if ( x == y ) lcaNode = x ; else lcaNode = LCA ( 1 , x , y ) ; let charactersCountFromXtoY = new Array ( MAX_CHAR ) ; charactersCountFromXtoY . fill ( 0 ) ; for ( let i = 0 ; i < MAX_CHAR ; i ++ ) { charactersCountFromXtoY [ i ] = nodeCharactersCount [ x ] [ i ] + nodeCharactersCount [ y ] [ i ] - 2 * nodeCharactersCount [ lcaNode ] [ i ] ; } if ( canFormPalindrome ( charactersCountFromXtoY ) ) return true ; return false ; } function updateNodeCharactersCount ( str , v ) { for ( let i = 0 ; i < str . length ; i ++ ) nodeCharactersCount [ v ] [ str [ i ] . charCodeAt ( ) - ' ' . charCodeAt ( ) ] ++ ; } function performQueries ( queries , q ) { let i = 0 ; while ( i < q ) { let x = queries [ i ] [ 0 ] ; let y = queries [ i ] [ 1 ] ; if ( canFormPalindromicPath ( x , y ) ) document . write ( " " + " " ) ; else document . write ( " " + " " ) ; i ++ ; } } for ( let i = 0 ; i < MAX_SIZE ; i ++ ) { nodeCharactersCount [ i ] = new Array ( MAX_CHAR ) ; for ( let j = 0 ; j < MAX_CHAR ; j ++ ) { nodeCharactersCount [ i ] [ j ] = 0 ; } } for ( let i = 0 ; i < MAX_SIZE ; i ++ ) { tree [ i ] = [ ] ; } tree [ 1 ] . push ( 2 ) ; updateNodeCharactersCount ( " " , 2 ) ; tree [ 1 ] . push ( 3 ) ; updateNodeCharactersCount ( " " , 3 ) ; buildTree ( 1 ) ; let queries = [ [ 1 , 2 ] , [ 2 , 3 ] , [ 3 , 1 ] , [ 3 , 3 ] ] ; let q = queries . length ; performQueries ( queries , q ) ;