# Question

Formatted question description: https://leetcode.ca/all/1120.html


Given the root of a binary tree, find the maximum average value of any subtree of that tree.

(A subtree of a tree is any node of that tree plus all its descendants.
The average value of a tree is the sum of its values, divided by the number of nodes.)

Example 1:

Input: [5,6,1]
Output: 6.00000
Explanation:
For the node with value = 5 we have an average of (5 + 6 + 1) / 3 = 4.
For the node with value = 6 we have an average of 6 / 1 = 6.
For the node with value = 1 we have an average of 1 / 1 = 1.
So the answer is 6 which is the maximum.

Note:
The number of nodes in the tree is between 1 and 5000.
Each node will have a value between 0 and 100000.
Answers will be accepted as correct if they are within 10^-5 of the correct answer.



# Algorithm

DFS Define a pair<int, int> for each node, the first position represents the sum of the subtree values rooted at that node, and the second position represents the number of nodes of the subtree; Accumulate these two values of each node from the top; The average number of subtrees is the sum/node, which is stored using a global variable; Use dictionaries for memoized searches to speed up

# Code

• 
public class Maximum_Average_Subtree {

/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode() {}
*     TreeNode(int val) { this.val = val; }
*     TreeNode(int val, TreeNode left, TreeNode right) {
*         this.val = val;
*         this.left = left;
*         this.right = right;
*     }
* }
*/

class Solution {

double max = Integer.MIN_VALUE;

public double maximumAverageSubtree(TreeNode root) {
dfs(root);
return max;
}

// double[]: sum, count
private double[] dfs(TreeNode root) {
if (root == null) {
return new double[]{0, 0};
}

double[] l = dfs(root.left);
double[] r = dfs(root.right);
double sum = root.val + l + r;
double count = l + r + 1;

double avg = sum / count;
if (avg > max) {
max = avg;
}

return new double[]{sum, count};
}
}
}


• // OJ: https://leetcode.com/problems/maximum-average-subtree/
// Time: O(N)
// Space: O(H)
class Solution {
double ans = 0;
pair<int, int> dfs(TreeNode *root) {
if (!root) return {0,0};
auto left = dfs(root->left), right = dfs(root->right);
int sum = left.first + right.first + root->val, cnt = left.second + right.second + 1;
ans = max(ans, (double)sum / cnt);
return {sum, cnt};
}
public:
double maximumAverageSubtree(TreeNode* root) {
dfs(root);
return ans;
}
};

• # Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
def maximumAverageSubtree(self, root: TreeNode) -> float:
def dfs(root):
if root is None:
return 0, 0
ls, ln = dfs(root.left)
rs, rn = dfs(root.right)
s = ls + root.val + rs
n = ln + 1 + rn
nonlocal ans
ans = max(ans, s / n)
return s, n

ans = 0
dfs(root)
return ans


• /**
* Definition for a binary tree node.
* type TreeNode struct {
*     Val int
*     Left *TreeNode
*     Right *TreeNode
* }
*/
func maximumAverageSubtree(root *TreeNode) (ans float64) {
var dfs func(*TreeNode) int
dfs = func(root *TreeNode) int {
if root == nil {
return int{}
}
l, r := dfs(root.Left), dfs(root.Right)
s := root.Val + l + r
n := 1 + l + r
ans = math.Max(ans, float64(s)/float64(n))
return int{s, n}
}
dfs(root)
return
}