Given a tree of size n as array parent[0..n-1] where every index i in the parent[] represents a node and the value at i represents the immediate parent of that node. For root, the node value will be -1. Find the height of the generic tree given the parent links.
Here, a generic tree is sometimes also called an N-ary tree or N-way tree where N denotes the maximum number of child a node can have. In this problem, the array represents n number of nodes in the tree.
The naive approach is to traverse up the tree from the node till the root node is reached with node value -1. While Traversing for each node stores maximum path length. The Time Complexity of this solution is O(n^2).
[Expected Approach - 1] Using BFS - O(n) Time and O(n) Space
Build graph for N-ary Tree in O(n) time and apply BFS on the stored graph in O(n) time and while doing BFS store maximum reached level. This solution does two iterations to find the height of N-ary tree.
Below is the implementation of the above approach:
C++
// C++ code of finding height of N-array// tree using BFS#include<bits/stdc++.h>usingnamespacestd;intbuildTree(vector<int>&parent,intn,vector<vector<int>>&adj){introot=-1;// Iterate through all nodes to //establish connectionsfor(inti=0;i<n;i++){if(parent[i]==-1)root=i;else{adj[i].push_back(parent[i]);adj[parent[i]].push_back(i);}}returnroot;}// Function to compute height of the tree // using BFSintgetTreeHeight(introot,vector<vector<int>>&adj){// Visited map to track nodesmap<int,bool>visited;// Pair stores (node, level)queue<pair<int,int>>q;intmaxHeight=0;// Start BFS from the // root nodeq.push({root,0});while(!q.empty()){autonode=q.front().first;autolevel=q.front().second;q.pop();visited[node]=true;maxHeight=max(maxHeight,level);// Traverse all children of the// current nodefor(intchild:adj[node]){if(!visited[child]){// Increment levelq.push({child,level+1});}}}returnmaxHeight;}intmain(){// Example: N-ary tree represented // by parent arrayvector<int>parent={-1,0,0,0,3,1,1,2};intn=parent.size();vector<vector<int>>adj(n);introot=buildTree(parent,n,adj);intheight=getTreeHeight(root,adj);cout<<height<<endl;return0;}
Java
// Java code to find the height of an// N-ary tree using BFSimportjava.util.*;classGfG{staticintbuildTree(int[]parent,intn,List<List<Integer>>adj){introot=-1;// Iterate through all nodes to establish// connectionsfor(inti=0;i<n;i++){if(parent[i]==-1)root=i;else{adj.get(i).add(parent[i]);adj.get(parent[i]).add(i);}}returnroot;}// Function to compute height of the// tree using BFSstaticintgetTreeHeight(introot,List<List<Integer>>adj){Map<Integer,Boolean>visited=newHashMap<>();Queue<int[]>q=newLinkedList<>();intmaxHeight=0;// Start BFS from the root nodeq.add(newint[]{root,0});while(!q.isEmpty()){intnode=q.peek()[0];intlevel=q.peek()[1];q.poll();visited.put(node,true);maxHeight=Math.max(maxHeight,level);// Traverse all children of the// current nodefor(intchild:adj.get(node)){if(!visited.getOrDefault(child,false)){q.add(newint[]{child,level+1});}}}returnmaxHeight;}publicstaticvoidmain(String[]args){int[]parent={-1,0,0,0,3,1,1,2};intn=parent.length;List<List<Integer>>adj=newArrayList<>(n);for(inti=0;i<n;i++){adj.add(newArrayList<>());}introot=buildTree(parent,n,adj);intheight=getTreeHeight(root,adj);System.out.println(height);}}
Python
# Python code to find the height of an# N-ary tree using BFSfromcollectionsimportdeque,defaultdictdefbuild_tree(parent):adj=defaultdict(list)root=-1# Iterate through all nodes to# establish connectionsfori,pinenumerate(parent):ifp==-1:root=ielse:adj[i].append(p)adj[p].append(i)returnroot,adj# Function to compute height of the# tree using BFSdefget_tree_height(root,adj):visited=set()q=deque([(root,0)])max_height=0# Start BFS from the root nodewhileq:node,level=q.popleft()visited.add(node)max_height=max(max_height,level)# Traverse all children of the # current nodeforchildinadj[node]:ifchildnotinvisited:# Increment levelq.append((child,level+1))returnmax_heightparent=[-1,0,0,0,3,1,1,2]root,adj=build_tree(parent)height=get_tree_height(root,adj)print(height)
C#
// C# code to find the height of an// N-ary tree using BFSusingSystem;usingSystem.Collections.Generic;classGfG{staticintBuildTree(int[]parent,intn,List<List<int>>adj){introot=-1;// Iterate through all nodes to establish// connectionsfor(inti=0;i<n;i++){if(parent[i]==-1)root=i;else{adj[i].Add(parent[i]);adj[parent[i]].Add(i);}}returnroot;}// Function to compute height of the// tree using BFSstaticintGetTreeHeight(introot,List<List<int>>adj){varvisited=newDictionary<int,bool>();varq=newQueue<(int,int)>();intmaxHeight=0;// Start BFS from the root nodeq.Enqueue((root,0));while(q.Count>0){var(node,level)=q.Dequeue();visited[node]=true;maxHeight=Math.Max(maxHeight,level);// Traverse all children of the // current nodeforeach(intchildinadj[node]){if(!visited.ContainsKey(child)||!visited[child]){q.Enqueue((child,level+1));}}}returnmaxHeight;}staticvoidMain(string[]args){int[]parent={-1,0,0,0,3,1,1,2};intn=parent.Length;List<List<int>>adj=newList<List<int>>(n);for(inti=0;i<n;i++){adj.Add(newList<int>());}introot=BuildTree(parent,n,adj);intheight=GetTreeHeight(root,adj);Console.WriteLine(height);}}
JavaScript
// JavaScript code to find the height of an N-ary tree using// BFSfunctionbuildTree(parent){letadj=Array.from({length:parent.length},()=>[]);letroot=-1;// Iterate through all nodes to establish// connectionsfor(leti=0;i<parent.length;i++){if(parent[i]===-1)root=i;else{adj[i].push(parent[i]);adj[parent[i]].push(i);}}return{root,adj};}// Function to compute height of the // tree using BFSfunctiongetTreeHeight(root,adj){letvisited=newSet();letq=[[root,0]];letmaxHeight=0;// Start BFS from the root nodewhile(q.length){let[node,level]=q.shift();visited.add(node);maxHeight=Math.max(maxHeight,level);// Traverse all children of the// current nodefor(letchildofadj[node]){if(!visited.has(child)){// Increment levelq.push([child,level+1]);}}}returnmaxHeight;}constparent=[-1,0,0,0,3,1,1,2];const{root,adj}=buildTree(parent);constheight=getTreeHeight(root,adj);console.log(height);
Output
2
[Expected Approach - 2] Without using map - O(n) Time and O(n) Space
We can find the height of the N-ary Tree in only one iteration. We visit nodes from 0 to n-1 iteratively and mark the unvisited ancestors recursively if they are not visited before till we reach a node which is visited, or we reach the root node. If we reach the visited node while traversing up the tree using parent links, then we use its height and will not go further in recursion.
Explanation For Example 1:
For node 0: Check for Root node is true, Return 0 as height, Mark node 0 as visited
For node 1: Recur for an immediate ancestor, i.e 0, which is already visited So, Use its height and return height(node 0) +1 Mark node 1 as visited
For node 2: Recur for an immediate ancestor, i.e 0, which is already visited So, Use its height and return height(node 0) +1 Mark node 2 as visited
For node 3: Recur for an immediate ancestor, i.e 0, which is already visited So, Use its height and return height(node 0) +1 Mark node 3 as visited
For node 4: Recur for an immediate ancestor, i.e 3, which is already visited So, Use its height and return height(node 3) +1 Mark node 3 as visited
For node 5: Recur for an immediate ancestor, i.e 1, which is already visited So, Use its height and return height(node 1) +1 Mark node 5 as visited
For node 6: Recur for an immediate ancestor, i.e 1, which is already visited So, Use its height and return height(node 1) +1 Mark node 6 as visited
For node 7: Recur for an immediate ancestor, i.e 2, which is already visited So, Use its height and return height(node 2) +1
Mark node 7 as visited Hence, we processed each node in the N-ary tree only once.
Below is the implementation of the above approach:
C++
// C++ code of finding height of N-array// tree#include<bits/stdc++.h>usingnamespacestd;// Recur For Ancestors of node and// store height of node at lastintfillHeight(vector<int>&parent,intnode,vector<int>&visited,vector<int>&height){// If root nodeif(parent[node]==-1){// mark root node as visitedvisited[node]=1;return0;}// If node is already visitedif(visited[node])returnheight[node];// Visit node and calculate its// heightvisited[node]=1;// Recur for the parent nodeheight[node]=1+fillHeight(parent,parent[node],visited,height);// Return calculated height for nodereturnheight[node];}intfindHeight(vector<int>&parent){intn=parent.size();// To store max heightintmaxHeight=0;// To check whether or not node is // visited beforevector<int>visited(n,0);// For storing the height of each nodevector<int>height(n,0);// Calculate the height of all nodesfor(inti=0;i<n;i++){// If not visited beforeif(!visited[i])height[i]=fillHeight(parent,i,visited,height);// Store maximum height so farmaxHeight=max(maxHeight,height[i]);}returnmaxHeight;}intmain(){vector<int>parent={-1,0,0,0,3,1,1,2};cout<<findHeight(parent)<<endl;return0;}
Java
// Java code of finding height of N-array// treeimportjava.util.*;classGfG{// Recur For Ancestors of node and store height of node// at laststaticintfillHeight(List<Integer>parent,intnode,List<Integer>visited,List<Integer>height){// If root nodeif(parent.get(node)==-1){// mark root node as visitedvisited.set(node,1);return0;}// If node is already visitedif(visited.get(node)==1)returnheight.get(node);// Visit node and calculate its heightvisited.set(node,1);// Recur for the parent nodeheight.set(node,1+fillHeight(parent,parent.get(node),visited,height));// Return calculated height// for nodereturnheight.get(node);}staticintfindHeight(List<Integer>parent){intn=parent.size();// To store max heightintmaxHeight=0;// To check whether or not node is // visited beforeList<Integer>visited=newArrayList<>(Collections.nCopies(n,0));// For storing the height of each nodeList<Integer>height=newArrayList<>(Collections.nCopies(n,0));// Calculate the height of all nodesfor(inti=0;i<n;i++){// If not visited beforeif(visited.get(i)==0)height.set(i,fillHeight(parent,i,visited,height));// Store maximum height so farmaxHeight=Math.max(maxHeight,height.get(i));}returnmaxHeight;}publicstaticvoidmain(String[]args){List<Integer>parent=Arrays.asList(-1,0,0,0,3,1,1,2);System.out.println(findHeight(parent));}}
Python
# Python code of finding height of N-array# treedeffillHeight(parent,node,visited,height):# If root nodeifparent[node]==-1:# mark root node as visitedvisited[node]=1return0# If node is already visitedifvisited[node]:returnheight[node]# Visit node and calculate its heightvisited[node]=1# Recur for the parent nodeheight[node]=1+fillHeight(parent, \
parent[node],visited,height)# Return calculated height for nodereturnheight[node]deffindHeight(parent):n=len(parent)# To store max heightmaxHeight=0# To check whether or not node is # visited beforevisited=[0]*n# For storing the height of each nodeheight=[0]*n# Calculate the height of all nodesforiinrange(n):# If not visited beforeifnotvisited[i]:height[i]=fillHeight(parent,i, \
visited,height)# Store maximum height so farmaxHeight=max(maxHeight,height[i])returnmaxHeightif__name__=="__main__":parent=[-1,0,0,0,3,1,1,2]print(findHeight(parent))
C#
// C# code of finding height of N-array// treeusingSystem;usingSystem.Collections.Generic;classGfG{// Recur For Ancestors of node and store height of node// at laststaticintFillHeight(List<int>parent,intnode,List<int>visited,List<int>height){// If root nodeif(parent[node]==-1){// mark root node as visitedvisited[node]=1;return0;}// If node is already visitedif(visited[node]==1)returnheight[node];// Visit node and calculate // its heightvisited[node]=1;// Recur for the parent nodeheight[node]=1+FillHeight(parent,parent[node],visited,height);// Return calculated height for nodereturnheight[node];}staticintFindHeight(List<int>parent){intn=parent.Count;// To store max heightintmaxHeight=0;// To check whether or not node is visited beforeList<int>visited=newList<int>(newint[n]);// For storing the height of each nodeList<int>height=newList<int>(newint[n]);// Calculate the height of all nodesfor(inti=0;i<n;i++){// If not visited beforeif(visited[i]==0)height[i]=FillHeight(parent,i,visited,height);// Store maximum height so farmaxHeight=Math.Max(maxHeight,height[i]);}returnmaxHeight;}staticvoidMain(string[]args){List<int>parent=newList<int>{-1,0,0,0,3,1,1,2};Console.WriteLine(FindHeight(parent));}}
JavaScript
// Javascript code of finding height of N-array// treefunctionfillHeight(parent,node,visited,height){// If root nodeif(parent[node]===-1){// mark root node as visitedvisited[node]=1;return0;}// If node is already visitedif(visited[node])returnheight[node];// Visit node and calculate its heightvisited[node]=1;// Recur for the parent nodeheight[node]=1+fillHeight(parent,parent[node],visited,height);// Return calculated height for nodereturnheight[node];}functionfindHeight(parent){letn=parent.length;// To store max heightletmaxHeight=0;// To check whether or not node// is visited beforeletvisited=Array(n).fill(0);// For storing the height of each nodeletheight=Array(n).fill(0);// Calculate the height of all nodesfor(leti=0;i<n;i++){// If not visited beforeif(!visited[i])height[i]=fillHeight(parent,i,visited,height);// Store maximum height so farmaxHeight=Math.max(maxHeight,height[i]);}returnmaxHeight;}letparent=[-1,0,0,0,3,1,1,2];console.log(findHeight(parent));