📜  父数组中通用树的高度

📅  最后修改于: 2022-05-13 01:57:20.132000             🧑  作者: Mango

父数组中通用树的高度

我们得到一棵大小为 n 的树作为数组 parent[0..n-1],其中 parent[] 中的每个索引 i 代表一个节点,而 i 处的值代表该节点的直接父节点。对于根节点值将是 -1。在给定父链接的情况下找到通用树的高度。
例子:

Input : parent[] = {-1, 0, 0, 0, 3, 1, 1, 2}
Output : 2

父数组 1 中通用树的高度

Input  : parent[] = {-1, 0, 1, 2, 3}
Output : 4

父数组 2 中通用树的高度

在这里,通用树有时也称为 N 叉树或 N 路树,其中 N 表示节点可以拥有的最大子节点数。在这个问题中,数组表示树中的 n 个节点。

方法一:
一种解决方案是从节点向上遍历树,直到到达根节点,节点值为 -1。虽然遍历每个节点存储最大路径长度。
此解决方案的时间复杂度为O(n^2)
方法二:
在 O(n) 时间内为 N-ary Tree 构建图,并在 O(n) 时间内在存储的图上应用 BFS,同时执行 BFS 存储最大达到的级别。该解决方案进行两次迭代以找到 N 叉树的高度。

C++
// C++ code to find height of N-ary
// tree in O(n)
#include 
#define MAX 1001
using namespace std;
  
// Adjacency list to
// store N-ary tree
vector adj[MAX];
  
// Build tree in tree in O(n)
int build_tree(int arr[], int n)
{
    int root_index = 0;
  
    // Iterate for all nodes
    for (int i = 0; i < n; i++) {
  
        // if root node, store index
        if (arr[i] == -1)
            root_index = i;
  
        else {
            adj[i].push_back(arr[i]);
            adj[arr[i]].push_back(i);
        }
    }
    return root_index;
}
  
// Applying BFS
int BFS(int start)
{
    // map is used as visited array
    map vis;
  
    queue > q;
    int max_level_reached = 0;
  
    // height of root node is zero
    q.push({ start, 0 });
  
    // p.first denotes node in adjacency list
    // p.second denotes level of p.first
    pair p;
  
    while (!q.empty()) {
  
        p = q.front();
        vis[p.first] = 1;
  
        // store the maximum level reached
        max_level_reached = max(max_level_reached,
                                p.second);
  
        q.pop();
  
        for (int i = 0; i < adj[p.first].size(); i++)
  
            // adding 1 to previous level
            // stored on node p.first
            // which is parent of node adj[p.first][i]
            // if adj[p.first][i] is not visited
            if (!vis[adj[p.first][i]])
                q.push({ adj[p.first][i], p.second + 1 });
    }
  
    return max_level_reached;
}
  
// Driver Function
int main()
{
    // node 0 to node n-1
    int parent[] = { -1, 0, 1, 2, 3 };
  
    // Number of nodes in tree
    int n = sizeof(parent) / sizeof(parent[0]);
  
    int root_index = build_tree(parent, n);
  
    int ma = BFS(root_index);
    cout << "Height of N-ary Tree=" << ma;
    return 0;
}


Java
// Java code to find height of N-ary
// tree in O(n)
import java.io.*;
import java.util.*;
  
class GFG 
{
    static int MAX = 1001;
    
    // Adjacency list to
    // store N-ary tree
    static ArrayList> adj = 
      new ArrayList>();
      
    // Build tree in tree in O(n)
    static int build_tree(int arr[], int n)
    {
        int root_index = 0;
   
        // Iterate for all nodes
        for (int i = 0; i < n; i++) 
        {
   
            // if root node, store index
            if (arr[i] == -1)
                root_index = i;
   
            else 
            {
                adj.get(i).add(arr[i]);
                adj.get(arr[i]).add(i);
            }
        }
        return root_index;
    }
      
    // Applying BFS
    static int BFS(int start)
    {
        
        // map is used as visited array
        Map vis = new HashMap(); 
        ArrayList> q = new ArrayList>();
        int max_level_reached = 0;
   
        // height of root node is zero
        q.add(new ArrayList(Arrays.asList(start, 0 )));
        
        // p.first denotes node in adjacency list
        // p.second denotes level of p.first
        ArrayList p = new ArrayList();
        while(q.size() != 0)
        {
            p = q.get(0);
            vis.put(p.get(0),1);
            
            // store the maximum level reached
            max_level_reached = Math.max(max_level_reached,p.get(1));
            q.remove(0);
            for(int i = 0; i < adj.get(p.get(0)).size(); i++)
            {
                
                // adding 1 to previous level
                // stored on node p.first
                // which is parent of node adj[p.first][i]
                // if adj[p.first][i] is not visited
                if(!vis.containsKey(adj.get(p.get(0)).get(i)))
                {
                    q.add(new ArrayList(Arrays.asList(adj.get(p.get(0)).get(i), p.get(1)+1)));
                }
            }
        }
        return max_level_reached;
    }
    
    // Driver Function
    public static void main (String[] args)
    {
        for(int i = 0; i < MAX; i++)
        {
            adj.add(new ArrayList());
        }
          
        // node 0 to node n-1
        int parent[] = { -1, 0, 1, 2, 3 };
          
        // Number of nodes in tree
        int n = parent.length;
        int root_index = build_tree(parent, n);
        int ma = BFS(root_index);
        System.out.println( "Height of N-ary Tree=" + ma);
    }
}
  
// This code is contributed by rag2127


Python3
# Python3 code to find height 
# of N-ary tree in O(n)
from collections import deque
  
MAX = 1001
  
# Adjacency list to
# store N-ary tree
adj = [[] for i in range(MAX)]
  
# Build tree in tree in O(n)
def build_tree(arr, n):
    
    root_index = 0
  
    # Iterate for all nodes
    for i in range(n):
  
        # if root node, store 
        # index
        if (arr[i] == -1):
            root_index = i
        else:
            adj[i].append(arr[i])
            adj[arr[i]].append(i)
  
    return root_index
  
# Applying BFS
def BFS(start):
    
    # map is used as visited 
    # array
    vis = {}
  
    q = deque()
    max_level_reached = 0
  
    # height of root node is 
    # zero
    q.append([start, 0])
  
    # p.first denotes node in 
    # adjacency list
    # p.second denotes level of 
    # p.first
    p = []
  
    while (len(q) > 0):
        p = q.popleft()
        vis[p[0]] = 1
  
        # store the maximum level 
        # reached
        max_level_reached = max(max_level_reached,
                                p[1])
  
        for i in range(len(adj[p[0]])):
  
            # adding 1 to previous level
            # stored on node p.first
            # which is parent of node 
            # adj[p.first][i]
            # if adj[p.first][i] is not visited
            if (adj[p[0]][i] not in vis ):
                q.append([adj[p[0]][i],
                          p[1] + 1])
  
    return max_level_reached
  
# Driver code
if __name__ == '__main__':
    
    # node 0 to node n-1
    parent = [-1, 0, 1, 2, 3]
  
    # Number of nodes in tree
    n = len(parent)
  
    root_index = build_tree(parent, n)
    ma = BFS(root_index)
    print("Height of N-ary Tree=",
          ma)
  
# This code is contributed by Mohit Kumar 29


C#
// C# code to find height of N-ary
// tree in O(n)
using System;
using System.Collections.Generic;
  
public class GFG
{
  static int MAX = 1001;
  
  // Adjacency list to
  // store N-ary tree
  static List> adj = new List>();
  
  // Build tree in tree in O(n)
  static int build_tree(int[] arr, int n)
  {
    int root_index = 0;
  
    // Iterate for all nodes
    for (int i = 0; i < n; i++) 
    {
  
      // if root node, store index
      if (arr[i] == -1)
        root_index = i;
      else
      {
        adj[i].Add(arr[i]);
        adj[arr[i]].Add(i);
      }
    }
    return root_index;    
  }
  
  // Applying BFS
  static int BFS(int start)
  {
    // map is used as visited array
    Dictionary vis = new Dictionary();  
    List> q= new List>();
    int max_level_reached = 0;
  
    // height of root node is zero
    q.Add(new List(){start, 0});
  
    // p.first denotes node in adjacency list
    // p.second denotes level of p.first
    List p = new List();
  
    while(q.Count != 0)
    {
      p = q[0];
      vis.Add(p[0], 1);
  
      // store the maximum level reached
      max_level_reached = Math.Max(max_level_reached, p[1]);
      q.RemoveAt(0);
      for(int i = 0; i < adj[p[0]].Count; i++)
      {
        // adding 1 to previous level
        // stored on node p.first
        // which is parent of node adj[p.first][i]
        // if adj[p.first][i] is not visited
        if(!vis.ContainsKey(adj[p[0]][i]))
        {
          q.Add(new List(){adj[p[0]][i], p[1] + 1 });
        }
      }
    }
    return max_level_reached;
  }
  
  // Driver Function
  static public void Main ()
  {
    for(int i = 0; i < MAX; i++)
    {
      adj.Add(new List());
    }
  
    // node 0 to node n-1
    int[] parent = { -1, 0, 1, 2, 3 };
      
    // Number of nodes in tree
    int n = parent.Length;
    int root_index = build_tree(parent, n);
    int ma = BFS(root_index);
    Console.Write("Height of N-ary Tree=" + ma);
  }
}
  
// This code is contributed by avanitrachhadiya2155


Javascript


C++
// C++ code to find height of N-ary
// tree in O(n) (Efficient Approach)
#include 
using namespace std;
  
// Recur For Ancestors of node and
// store height of node at last
int fillHeight(int p[], int node, int visited[],
                                   int height[])
{
    // If root node
    if (p[node] == -1) {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node])
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
  
int findHeight(int parent[], int n)
{
    // To store max height
    int ma = 0;
  
    // To check whether or not node is visited before
    int visited[n];
  
    // For Storing Height of node
    int height[n];
  
    memset(visited, 0, sizeof(visited));
    memset(height, 0, sizeof(height));
  
    for (int i = 0; i < n; i++) {
  
        // If not visited before
        if (!visited[i])
            height[i] = fillHeight(parent, i,
                             visited, height);
  
        // store maximum height so far
        ma = max(ma, height[i]);
    }
  
    return ma;
}
  
// Driver Function
int main()
{
    int parent[] = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = sizeof(parent) / sizeof(parent[0]);
  
    cout << "Height of N-ary Tree = "
         << findHeight(parent, n);
    return 0;
}


Java
// Java code to find height of N-ary
// tree in O(n) (Efficient Approach)
import java.util.*;
class GFG
{
  
// Recur For Ancestors of node and
// store height of node at last
static int fillHeight(int p[], int node, 
                      int visited[], int height[])
{
    // If root node
    if (p[node] == -1)
    {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
  
static int findHeight(int parent[], int n)
{
    // To store max height
    int ma = 0;
  
    // To check whether or not node is visited before
    int []visited = new int[n];
  
    // For Storing Height of node
    int []height = new int[n];
  
    for(int i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
  
    for (int i = 0; i < n; i++) 
    {
  
        // If not visited before
        if (visited[i] != 1)
          
            height[i] = fillHeight(parent, i,
                            visited, height);
  
        // store maximum height so far
        ma = Math.max(ma, height[i]);
    }
    return ma;
}
  
// Driver Code
public static void main(String[] args) 
{
    int parent[] = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = parent.length;
  
    System.out.println("Height of N-ary Tree = " +
                           findHeight(parent, n));
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 code to find height of N-ary 
# tree in O(n) (Efficient Approach) 
  
# Recur For Ancestors of node and 
# store height of node at last 
def fillHeight(p, node, visited, height):
      
    # If root node 
    if (p[node] == -1): 
  
        # mark root node as visited 
        visited[node] = 1
        return 0
  
    # If node is already visited 
    if (visited[node]): 
        return height[node] 
  
    # Visit node and calculate its height 
    visited[node] = 1
  
    # recur for the parent node 
    height[node] = 1 + fillHeight(p, p[node], 
                                  visited, height) 
  
    # return calculated height for node 
    return height[node]
  
def findHeight(parent, n):
      
    # To store max height 
    ma = 0
  
    # To check whether or not node is 
    # visited before 
    visited = [0] * n
  
    # For Storing Height of node 
    height = [0] * n 
  
    for i in range(n):
  
        # If not visited before 
        if (not visited[i]):
            height[i] = fillHeight(parent, i,
                                   visited, height) 
  
        # store maximum height so far 
        ma = max(ma, height[i])
  
    return ma
  
# Driver Code
if __name__ == '__main__':
  
    parent = [-1, 0, 0, 0, 3, 1, 1, 2] 
    n = len(parent)
  
    print("Height of N-ary Tree =",
             findHeight(parent, n))
  
# This code is contributed by PranchalK


C#
// C# code to find height of N-ary
// tree in O(n) (Efficient Approach)
using System;
      
class GFG
{
  
// Recur For Ancestors of node and
// store height of node at last
static int fillHeight(int []p, int node, 
                      int []visited, 
                      int []height)
{
    // If root node
    if (p[node] == -1)
    {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
  
static int findHeight(int []parent, int n)
{
    // To store max height
    int ma = 0;
  
    // To check whether or not 
    // node is visited before
    int []visited = new int[n];
  
    // For Storing Height of node
    int []height = new int[n];
  
    for(int i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
  
    for (int i = 0; i < n; i++) 
    {
  
        // If not visited before
        if (visited[i] != 1)
          
            height[i] = fillHeight(parent, i,
                            visited, height);
  
        // store maximum height so far
        ma = Math.Max(ma, height[i]);
    }
    return ma;
}
  
// Driver Code
public static void Main(String[] args) 
{
    int []parent = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = parent.Length;
  
    Console.WriteLine("Height of N-ary Tree = " +
                          findHeight(parent, n));
}
}
  
// This code contributed by Rajput-Ji


Javascript


输出:
Height of N-ary Tree=4

该解决方案的时间复杂度为O(2n) ,对于非常大的 n,它收敛到 O(n)。
方法3:
我们可以在一次迭代中找到 N-ary Tree 的高度。我们迭代地访问从 0 到 n-1 的节点,如果在到达被访问的节点或到达根节点之前未访问过它们,则递归地标记未访问的祖先。如果我们在使用父链接向上遍历树时到达访问节点,那么我们使用它的高度并且不会在递归中走得更远。
示例 1 的说明::

父数组 3 中通用树的高度

对于节点 0 :检查 Root 节点是否为真,
返回 0 作为高度,将节点 0 标记为已访问
对于节点 1 :对于已经访问过的直接祖先,即 0,重复出现
因此,使用它的高度并返回高度(节点 0)+1
将节点 1 标记为已访问
对于节点 2 :对于已经访问过的直接祖先,即 0,重复出现
因此,使用它的高度并返回高度(节点 0)+1
将节点 2 标记为已访问
对于节点 3 :针对已经访问过的直接祖先,即 0 重复出现
因此,使用它的高度并返回高度(节点 0)+1
将节点 3 标记为已访问
对于节点 4 :针对已经访问过的直系祖先,即 3 重复出现
所以,使用它的高度并返回高度(节点 3)+1
将节点 3 标记为已访问
对于节点 5 :针对已经访问过的直接祖先(即 1)重复出现
所以,使用它的高度并返回高度(节点 1)+1
将节点 5 标记为已访问
对于节点 6 :针对已经访问过的直接祖先(即 1)重复出现
所以,使用它的高度并返回高度(节点 1)+1
将节点 6 标记为已访问
对于节点 7 :针对已经访问过的直接祖先,即 2 重复出现
所以,使用它的高度并返回高度(节点 2)+1
将节点 7 标记为已访问
因此,我们只处理 N 叉树中的每个节点一次。

C++

// C++ code to find height of N-ary
// tree in O(n) (Efficient Approach)
#include 
using namespace std;
  
// Recur For Ancestors of node and
// store height of node at last
int fillHeight(int p[], int node, int visited[],
                                   int height[])
{
    // If root node
    if (p[node] == -1) {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node])
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
  
int findHeight(int parent[], int n)
{
    // To store max height
    int ma = 0;
  
    // To check whether or not node is visited before
    int visited[n];
  
    // For Storing Height of node
    int height[n];
  
    memset(visited, 0, sizeof(visited));
    memset(height, 0, sizeof(height));
  
    for (int i = 0; i < n; i++) {
  
        // If not visited before
        if (!visited[i])
            height[i] = fillHeight(parent, i,
                             visited, height);
  
        // store maximum height so far
        ma = max(ma, height[i]);
    }
  
    return ma;
}
  
// Driver Function
int main()
{
    int parent[] = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = sizeof(parent) / sizeof(parent[0]);
  
    cout << "Height of N-ary Tree = "
         << findHeight(parent, n);
    return 0;
}

Java

// Java code to find height of N-ary
// tree in O(n) (Efficient Approach)
import java.util.*;
class GFG
{
  
// Recur For Ancestors of node and
// store height of node at last
static int fillHeight(int p[], int node, 
                      int visited[], int height[])
{
    // If root node
    if (p[node] == -1)
    {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
  
static int findHeight(int parent[], int n)
{
    // To store max height
    int ma = 0;
  
    // To check whether or not node is visited before
    int []visited = new int[n];
  
    // For Storing Height of node
    int []height = new int[n];
  
    for(int i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
  
    for (int i = 0; i < n; i++) 
    {
  
        // If not visited before
        if (visited[i] != 1)
          
            height[i] = fillHeight(parent, i,
                            visited, height);
  
        // store maximum height so far
        ma = Math.max(ma, height[i]);
    }
    return ma;
}
  
// Driver Code
public static void main(String[] args) 
{
    int parent[] = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = parent.length;
  
    System.out.println("Height of N-ary Tree = " +
                           findHeight(parent, n));
}
}
  
// This code is contributed by 29AjayKumar

Python3

# Python3 code to find height of N-ary 
# tree in O(n) (Efficient Approach) 
  
# Recur For Ancestors of node and 
# store height of node at last 
def fillHeight(p, node, visited, height):
      
    # If root node 
    if (p[node] == -1): 
  
        # mark root node as visited 
        visited[node] = 1
        return 0
  
    # If node is already visited 
    if (visited[node]): 
        return height[node] 
  
    # Visit node and calculate its height 
    visited[node] = 1
  
    # recur for the parent node 
    height[node] = 1 + fillHeight(p, p[node], 
                                  visited, height) 
  
    # return calculated height for node 
    return height[node]
  
def findHeight(parent, n):
      
    # To store max height 
    ma = 0
  
    # To check whether or not node is 
    # visited before 
    visited = [0] * n
  
    # For Storing Height of node 
    height = [0] * n 
  
    for i in range(n):
  
        # If not visited before 
        if (not visited[i]):
            height[i] = fillHeight(parent, i,
                                   visited, height) 
  
        # store maximum height so far 
        ma = max(ma, height[i])
  
    return ma
  
# Driver Code
if __name__ == '__main__':
  
    parent = [-1, 0, 0, 0, 3, 1, 1, 2] 
    n = len(parent)
  
    print("Height of N-ary Tree =",
             findHeight(parent, n))
  
# This code is contributed by PranchalK

C#

// C# code to find height of N-ary
// tree in O(n) (Efficient Approach)
using System;
      
class GFG
{
  
// Recur For Ancestors of node and
// store height of node at last
static int fillHeight(int []p, int node, 
                      int []visited, 
                      int []height)
{
    // If root node
    if (p[node] == -1)
    {
  
        // mark root node as visited
        visited[node] = 1;
        return 0;
    }
  
    // If node is already visited
    if (visited[node] == 1)
        return height[node];
  
    // Visit node and calculate its height
    visited[node] = 1;
  
    // recur for the parent node
    height[node] = 1 + fillHeight(p, p[node],
                            visited, height);
  
    // return calculated height for node
    return height[node];
}
  
static int findHeight(int []parent, int n)
{
    // To store max height
    int ma = 0;
  
    // To check whether or not 
    // node is visited before
    int []visited = new int[n];
  
    // For Storing Height of node
    int []height = new int[n];
  
    for(int i = 0; i < n; i++)
    {
        visited[i] = 0;
        height[i] = 0;
    }
  
    for (int i = 0; i < n; i++) 
    {
  
        // If not visited before
        if (visited[i] != 1)
          
            height[i] = fillHeight(parent, i,
                            visited, height);
  
        // store maximum height so far
        ma = Math.Max(ma, height[i]);
    }
    return ma;
}
  
// Driver Code
public static void Main(String[] args) 
{
    int []parent = { -1, 0, 0, 0, 3, 1, 1, 2 };
    int n = parent.Length;
  
    Console.WriteLine("Height of N-ary Tree = " +
                          findHeight(parent, n));
}
}
  
// This code contributed by Rajput-Ji

Javascript


输出:
Height of N-ary Tree = 2

时间复杂度: O(n)