Skip to content
Related Articles

Related Articles

Improve Article

Maximum average of subtree values in a given Binary Tree

  • Difficulty Level : Hard
  • Last Updated : 02 Jun, 2021
Geek Week

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);
    }
}

Python3




# Python3 program for the above approach
 
# Stores the result
ans = 0.0
 
class TreeNode:
     
    def __init__ (self, val):
       
        self.val = val
        self.children = []
 
# Function for finding maximum
# subtree average
def MaxAverage(root):
     
    global ans
     
    # Checks if current node is not
    # None and doesn't have any children
    if (root != None and len(root.children) == 0):
        ans = max(ans, (root.val))
        return [root.val, 1]
 
    # Stores sum of its subtree in index 0
    # and count number of nodes in index 1
    childResult = [0 for i in range(2)]
 
    # Traverse all children of the current node
    for child in root.children:
         
        # Recursively calculate max average
        # of subtrees among its children
        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
    sum = childResult[0] + root.val
 
    # Increment number of
    # nodes by one
    count = childResult[1] + 1
 
    # Take maximum of ans and
    # current node's average
    ans = max(ans, sum / count)
 
    # Finally return pair of {sum, count}
    return [sum, count]
 
# Driver Code
if __name__ == '__main__':
     
    # Given tree
    root =  TreeNode(20)
    left =  TreeNode(12)
    right =  TreeNode(18)
     
    root.children.append(left)
    root.children.append(right)
     
    left.children.append(TreeNode(11))
    left.children.append(TreeNode(3))
    right.children.append(TreeNode(15))
    right.children.append(TreeNode(8))
 
    # Function call
    MaxAverage(root)
 
    # Print answer
    print(ans * 1.0)
 
# This code is contributed by ipg2016107

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

Javascript




<script>
// Javascript program for the above approach
 
// Structure of the Tree node
class TreeNode
{
    constructor(v)
    {
        this.val = v;
        this.children = [];
    }
}
 
    // Stores the result
    let ans = 0.0;
     
    // Function for finding maximum
    // subtree average
    function MaxAverage(root)
    {
        // Checks if current node is not
        // null and doesn't have any children
        if (root.children != null
            && root.children.length == 0)
        {
            ans = Math.max(ans, root.val);
            return  [ root.val, 1 ];
        }
  
        // Stores sum of its subtree in index 0
        // and count number of nodes in index 1
        let childResult = new Array(2);
        for(let i=0;i<childResult.length;i++)
        {
            childResult[i] = 0;
        }
  
        // Traverse all children of the current node
        for (let child = 0; child < root.children.length; child++)
        {
  
            // Recursively calculate max average
            // of subtrees among its children
            let childTotal
                = MaxAverage(root.children[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
        let sum = childResult[0] + root.val;
  
        // Increment number of
        // nodes by one
        let 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 [ sum, count ];
    }
     
    // Driver Code
     
    // Given tree
        let root = new TreeNode(20);
        let left = new TreeNode(12);
        let right = new TreeNode(18);
        root.children.push(left);
        root.children.push(right);
        left.children.push(new TreeNode(11));
        left.children.push(new TreeNode(3));
        right.children.push(new TreeNode(15));
        right.children.push(new TreeNode(8));
  
        // Function call
        MaxAverage(root);
  
        // Print answer
        document.write(ans.toFixed(1));
     
// This code is contributed by unknown2108
</script>
Output: 
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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :