Given a Binary Tree consisting of N nodes, the task to find the maximum average of values of nodes of any subtree.
Examples:
Input: 5
/ \
3 8
Output: 8
Explanation:
Average of values of subtree of node 5 = (5 + 3 + 8) / 3 = 5.33
Average of values of subtree of node 3 = 3 / 1 = 3
Average of values of subtree of node 8 = 8 / 1 = 8.Input: 20
/ \
12 18
/ \ / \
11 3 15 8
Output: 15
Explanation: Average of values of subtree of node 15 is the maximum.
Approach: The given problem is similar to that of finding the largest subtree sum in a tree. The idea is to use DFS traversal technique. Follow the steps below to solve the problem:
- Initialize a variable, ans with 0 for storing the result.
- Define a function maxAverage() for DFS traversal.
- Initialize two variables, sum to store the sum of its subtree and count to store the number of nodes in its subtree, with 0.
- Traverse over the child nodes of the current node and call the maxAverage() for its children node, and increment sum by sum of child’s node subtree and count by total nodes in the child’s node
- Increment sum by current node’s value and count by 1.
- Take the maximum of the ans and sum/count and store it in ans.
- Finally, return pair of the {sum, count}.
- Print the maximum average obtained as ans.
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; struct TreeNode { int val; vector<TreeNode*> children; TreeNode( int v) { val = v; } }; // Stores the result double ans = 0.0; // Function for finding maximum // subtree average vector< int > MaxAverage(TreeNode* root) { // Checks if current node is not // NULL and doesn't have any children if (root != NULL && root->children.size() == 0) { ans = max(ans, (root->val) * (1.0)); return {root->val, 1}; } // Stores sum of its subtree in index 0 // and count number of nodes in index 1 vector< int > childResult (2); // Traverse all children of the current node for (TreeNode *child : root->children) { // Recursively calculate max average // of subtrees among its children vector< int > childTotal = MaxAverage(child); // Increment sum by sum // of its child's subtree childResult[0] = childResult[0] + childTotal[0]; // Increment number of nodes // by its child's node childResult[1] = childResult[1] + childTotal[1]; } // Increment sum by current node's value int sum = childResult[0] + root->val; // Increment number of // nodes by one int count = childResult[1] + 1; // Take maximum of ans and // current node's average ans = max(ans, sum / count * 1.0); // Finally return pair of {sum, count} return {sum, count}; } // Driver Code int main() { // Given tree TreeNode *root = new TreeNode(20); TreeNode *left = new TreeNode(12); TreeNode *right = new TreeNode(18); root->children.push_back(left); root->children.push_back(right); left->children.push_back( new TreeNode(11)); left->children.push_back( new TreeNode(3)); right->children.push_back( new TreeNode(15)); right->children.push_back( new TreeNode(8)); // Function call MaxAverage(root); // Print answer printf ( "%0.1f\n" , ans); } // This code is contributed by mohit kumar 29 |
Java
// Java program for the above approach import java.util.*; // Structure of the Tree node class TreeNode { public int val; public List<TreeNode> children; public TreeNode( int v) { val = v; children = new ArrayList<TreeNode>(); } } class GFG { // Stores the result static double ans = 0.0 ; // Function for finding maximum // subtree average public static double [] MaxAverage( TreeNode root) { // Checks if current node is not // null and doesn't have any children if (root.children != null && root.children.size() == 0 ) { ans = Math.max(ans, root.val); return new double [] { root.val, 1 }; } // Stores sum of its subtree in index 0 // and count number of nodes in index 1 double [] childResult = new double [ 2 ]; // Traverse all children of the current node for (TreeNode child : root.children) { // Recursively calculate max average // of subtrees among its children double [] childTotal = MaxAverage(child); // Increment sum by sum // of its child's subtree childResult[ 0 ] = childResult[ 0 ] + childTotal[ 0 ]; // Increment number of nodes // by its child's node childResult[ 1 ] = childResult[ 1 ] + childTotal[ 1 ]; } // Increment sum by current node's value double sum = childResult[ 0 ] + root.val; // Increment number of // nodes by one double count = childResult[ 1 ] + 1 ; // Take maximum of ans and // current node's average ans = Math.max(ans, sum / count); // Finally return pair of {sum, count} return new double [] { sum, count }; } // Driver Code public static void main(String[] args) { // Given tree TreeNode root = new TreeNode( 20 ); TreeNode left = new TreeNode( 12 ); TreeNode right = new TreeNode( 18 ); root.children.add(left); root.children.add(right); left.children.add( new TreeNode( 11 )); left.children.add( new TreeNode( 3 )); right.children.add( new TreeNode( 15 )); right.children.add( new TreeNode( 8 )); // Function call MaxAverage(root); // Print answer System.out.println(ans); } } |
C#
// C# program for the above approach using System; using System.Collections.Generic; using System.Globalization; public class TreeNode { public int val; public List<TreeNode> children; public TreeNode( int v) { val = v; children = new List<TreeNode>(); } } public class GFG { // Stores the result static double ans = 0.0; // Function for finding maximum // subtree average public static double [] MaxAverage( TreeNode root) { // Checks if current node is not // null and doesn't have any children if (root.children != null && root.children.Count == 0) { ans = Math.Max(ans, root.val); return new double [] { root.val, 1 }; } // Stores sum of its subtree in index 0 // and count number of nodes in index 1 double [] childResult = new double [2]; // Traverse all children of the current node foreach (TreeNode child in root.children) { // Recursively calculate max average // of subtrees among its children double [] childTotal = MaxAverage(child); // Increment sum by sum // of its child's subtree childResult[0] = childResult[0] + childTotal[0]; // Increment number of nodes // by its child's node childResult[1] = childResult[1] + childTotal[1]; } // Increment sum by current node's value double sum = childResult[0] + root.val; // Increment number of // nodes by one double count = childResult[1] + 1; // Take maximum of ans and // current node's average ans = Math.Max(ans, sum / count); // Finally return pair of {sum, count} return new double [] { sum, count }; } // Driver code static public void Main () { // Given tree TreeNode root = new TreeNode(20); TreeNode left = new TreeNode(12); TreeNode right = new TreeNode(18); root.children.Add(left); root.children.Add(right); left.children.Add( new TreeNode(11)); left.children.Add( new TreeNode(3)); right.children.Add( new TreeNode(15)); right.children.Add( new TreeNode(8)); // Function call MaxAverage(root); // Print answer NumberFormatInfo setPrecision = new NumberFormatInfo(); setPrecision.NumberDecimalDigits = 1; Console.WriteLine(ans.ToString( "N" , setPrecision)); } } // This code is contributed by rag2127 |
15.0
Time Complexity: O(N)
Auxiliary Space: O(N)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.