二叉树_题目12:1120. 子树的最大平均值

220 阅读2分钟

题目12:1120. 子树的最大平均值

1120. 子树的最大平均值

同类题目

前置知识

题目描述

给你一棵二叉树的根节点 root,找出这棵树的 每一棵 子树的 平均值 中的 最大 值。

子树是树中的任意节点和它的所有后代构成的集合。

树的平均值是树中节点值的总和除以节点数。

示例:

img

 输入:[5,6,1]
 输出:6.00000
 解释: 
 以 value = 5 的节点作为子树的根节点,得到的平均值为 (5 + 6 + 1) / 3 = 4。
 以 value = 6 的节点作为子树的根节点,得到的平均值为 6 / 1 = 6。
 以 value = 1 的节点作为子树的根节点,得到的平均值为 1 / 1 = 1。
 所以答案取最大值 6。

提示:

  1. 树中的节点数介于 15000之间。
  2. 每个节点的值介于 0100000 之间。
  3. 如果结果与标准答案的误差不超过 10^-5,那么该结果将被视为正确答案。

思路分析

子问题分解(分治)

每一个子树都求解一下,找出来最大的即可。

如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点交给框架,递归函数会帮你在所有节点上执行相同的操作。

本题明显是需要左右子树返回节点个数和节点和之后,再计算当前树的平均值,那位置就是在后续。

如果单独抽出一个二叉树节点,它需要做什么事情?

  • 左右子树的节点值的和 + 当前节点的值 ,计算出来当前树的总和
  • 左右子树的节点个数 + 1 计算出来当前树一共的节点个数
  • 求最大平均值,并返回当前树的节点个数和总和

程序代码

方法一:使用一个全局变量记录最大平均值

 //[1120. 子树的最大平均值](https://leetcode.cn/problems/maximum-average-subtree)
 ​
 #include<iostream>
 #include<pair>
 #include<vector>
 ​
 using namespace std;
 struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 };
 ​
 class Solution {
 private:
     double ans = 0.0;
 public:
     pair<int,int> travel(TreeNode* root)
     {
         if(root == nullptr)
         {
             return make_pair(0,0);
         }
 ​
         pair<int,int> leftv = travel(root->left);
         pair<int,int> rightv = travel(root->right);
 ​
         int nodeNum = leftv.first + rightv.first + 1;
         int nodeSum = leftv.second + rightv.second + root->val;
 ​
         ans = max(ans,nodeSum*1.0/nodeNum);
         
         return make_pair(nodeNum,nodeSum);
 ​
     }
 ​
     double maximumAverageSubtree(TreeNode* root) {
         travel(root);
         return ans;
     }
 }

复杂度分析

时间复杂度:O(n),其中 n 是二叉树中的节点个数。每个节点都会遍历一次。

空间复杂度:O(n),其中 n 是二叉树中的节点个数。递归栈的开销,极限情况树是链状的高度为O(N)。

更多相关知识:github.com/pingguo1987…