N叉树的平均宽度
给定一个由N个节点组成的通用树,任务是找到给定树中每个节点的平均宽度。
The average width for each node can be calculated by the ratio of the total number of nodes in that subtree(including the node itself) to the total number of levels under that node.
例子:
Input:
1
/ \
2 3
/ \ / \ \
4 5 6 7 8
Output: 1:2, 2:1, 3:2, 4:1, 5:1, 6:1, 7:1, 8:1
Explanation: The average width for each node can be calculated as
For node 1: 8/3 = 2
For node 2: 3/2 = 1
For node 3: 4/2 = 2
For node 4: 1/1 = 1
For node 5: 1/1 = 1
For node 6: 1/1 = 1
For node 7: 1/1 = 1
For node 8: 1/1 = 1
方法:可以通过求N叉树中每个节点的子树大小和N叉树中每个节点的层级或高度来计算平均宽度。两者都可以使用单个 DFS 遍历来计算。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
vector > ans;
// Node structure
struct Node {
int val;
vector child;
};
// Utility function to create a new
// tree node
Node* newNode(int key)
{
Node* temp = new Node;
temp->val = key;
return temp;
}
// Function to find levels and
// subtree sizes
vector UtilityFun(Node* root, vector >& ans)
{
if (root == nullptr)
return { 0, 0 };
// Num nodes and level with just
// a single node
int totalNodes = 1, totalLevels = 1;
// Recur for all children
for (int i = 0; i < root->child.size(); i++) {
vector info = UtilityFun(root->child[i], ans);
totalNodes += info[0];
totalLevels = max(totalLevels, 1 + info[1]);
}
// Finding the current Width
int currentAverageWidth = totalNodes / totalLevels;
// Storing in ans
ans.push_back({ root->val, currentAverageWidth });
return { totalNodes, totalLevels };
}
// Function to find the average width
// of all nodes
vector > findAvgWidth(Node* root)
{
if (root == nullptr)
return {};
// Function Call
UtilityFun(root, ans);
return ans;
}
// Function to display the values
void display(vector > ans)
{
for (int i = 0; i < ans.size(); i++) {
cout << ans[i][0] << ":" << ans[i][1] << ", ";
}
}
// Driver Code
int main()
{
// Given Input
Node* root = newNode(1);
(root->child).push_back(newNode(2));
(root->child).push_back(newNode(3));
(root->child[0]->child).push_back(newNode(4));
(root->child[1]->child).push_back(newNode(5));
(root->child[0]->child).push_back(newNode(6));
(root->child[1])->child.push_back(newNode(7));
(root->child[1]->child).push_back(newNode(8));
// Function Call
findAvgWidth(root);
// Function Call
display(ans);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
public class Main
{
static Vector> ans = new Vector>();
// Node structure
static class Node {
public int val;
public Vector child;
public Node(int key)
{
val = key;
child = new Vector();
}
}
// Utility function to create a new
// tree node
static Node newNode(int key)
{
Node temp = new Node(key);
return temp;
}
// Function to find levels and
// subtree sizes
static Vector UtilityFun(Node root, Vector> ans)
{
if (root == null)
{
Vector temp = new Vector();
temp.add(0);
temp.add(0);
return temp;
}
// Num nodes and level with just
// a single node
int totalNodes = 1, totalLevels = 1;
// Recur for all children
for (int i = 0; i < root.child.size(); i++) {
Vector info = UtilityFun(root.child.get(i), ans);
totalNodes += info.get(0);
totalLevels = Math.max(totalLevels, 1 + info.get(1));
}
// Finding the current Width
int currentAverageWidth = totalNodes / totalLevels;
// Storing in ans
Vector temp = new Vector();
temp.add(root.val);
temp.add(currentAverageWidth);
ans.add(temp);
temp = new Vector();
temp.add(totalNodes);
temp.add(totalLevels);
return temp;
}
// Function to find the average width
// of all nodes
static Vector> findAvgWidth(Node root)
{
if (root == null)
return new Vector>();
// Function Call
UtilityFun(root, ans);
return ans;
}
// Function to display the values
static void display(Vector> ans)
{
for (int i = 0; i < ans.size(); i++) {
System.out.print(ans.get(i).get(0) + ":" + ans.get(i).get(1) + ", ");
}
}
public static void main(String[] args)
{
// Given Input
Node root = newNode(1);
(root.child).add(newNode(2));
(root.child).add(newNode(3));
(root.child.get(0).child).add(newNode(4));
(root.child.get(1).child).add(newNode(5));
(root.child.get(0).child).add(newNode(6));
(root.child.get(1)).child.add(newNode(7));
(root.child.get(1).child).add(newNode(8));
// Function Call
findAvgWidth(root);
// Function Call
display(ans);
}
}
// This code is contributed by suresh07.
Python3
# Python3 program for the above approach
ans = []
# Node structure
class Node:
def __init__(self, key):
self.val = key
self.child = []
# Utility function to create a new
# tree node
def newNode(key):
temp = Node(key)
return temp
# Function to find levels and
# subtree sizes
def UtilityFun(root, ans):
if (root == None):
return [ 0, 0 ]
# Num nodes and level with just
# a single node
totalNodes, totalLevels = 1, 1
# Recur for all children
for i in range(len(root.child)):
info = UtilityFun(root.child[i], ans)
totalNodes += info[0]
totalLevels = max(totalLevels, 1 + info[1])
# Finding the current Width
currentAverageWidth = int(totalNodes / totalLevels)
# Storing in ans
ans.append([ root.val, currentAverageWidth ])
return [ totalNodes, totalLevels ]
# Function to find the average width
# of all nodes
def findAvgWidth(root):
if (root == None):
return []
# Function Call
UtilityFun(root, ans)
return ans
# Function to display the values
def display(ans):
for i in range(len(ans)):
print(ans[i][0], ":", ans[i][1], ", ", sep="",end="")
# Given Input
root = newNode(1)
(root.child).append(newNode(2))
(root.child).append(newNode(3))
(root.child[0].child).append(newNode(4))
(root.child[1].child).append(newNode(5))
(root.child[0].child).append(newNode(6))
(root.child[1]).child.append(newNode(7))
(root.child[1].child).append(newNode(8))
# Function Call
findAvgWidth(root)
# Function Call
display(ans)
# This code is contributed by divyesh072019.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
static List> ans = new List>();
// Node structure
class Node {
public int val;
public List child;
public Node(int key)
{
val = key;
child = new List();
}
}
// Utility function to create a new
// tree node
static Node newNode(int key)
{
Node temp = new Node(key);
return temp;
}
// Function to find levels and
// subtree sizes
static List UtilityFun(Node root, List> ans)
{
if (root == null)
{
List temp = new List();
temp.Add(0);
temp.Add(0);
return temp;
}
// Num nodes and level with just
// a single node
int totalNodes = 1, totalLevels = 1;
// Recur for all children
for (int i = 0; i < root.child.Count; i++) {
List info = UtilityFun(root.child[i], ans);
totalNodes += info[0];
totalLevels = Math.Max(totalLevels, 1 + info[1]);
}
// Finding the current Width
int currentAverageWidth = totalNodes / totalLevels;
// Storing in ans
ans.Add(new List{root.val, currentAverageWidth});
return new List{totalNodes, totalLevels};
}
// Function to find the average width
// of all nodes
static List> findAvgWidth(Node root)
{
if (root == null)
return new List>();
// Function Call
UtilityFun(root, ans);
return ans;
}
// Function to display the values
static void display(List> ans)
{
for (int i = 0; i < ans.Count; i++) {
Console.Write(ans[i][0] + ":" + ans[i][1] + ", ");
}
}
static void Main()
{
// Given Input
Node root = newNode(1);
(root.child).Add(newNode(2));
(root.child).Add(newNode(3));
(root.child[0].child).Add(newNode(4));
(root.child[1].child).Add(newNode(5));
(root.child[0].child).Add(newNode(6));
(root.child[1]).child.Add(newNode(7));
(root.child[1].child).Add(newNode(8));
// Function Call
findAvgWidth(root);
// Function Call
display(ans);
}
}
// This code is contributed by mukesh07.
Javascript
4:1, 6:1, 2:1, 5:1, 7:1, 8:1, 3:2, 1:2,
时间复杂度: O(N)
辅助空间: O(N)