父数组中通用树的高度
我们得到一棵大小为 n 的树作为数组 parent[0..n-1],其中 parent[] 中的每个索引 i 代表一个节点,而 i 处的值代表该节点的直接父节点。对于根节点值将是 -1。在给定父链接的情况下找到通用树的高度。
例子:
Input : parent[] = {-1, 0, 0, 0, 3, 1, 1, 2}
Output : 2
Input : parent[] = {-1, 0, 1, 2, 3}
Output : 4
方法一:
一种解决方案是从节点向上遍历树,直到到达根节点,节点值为 -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 的说明::
对于节点 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)