题目12:1120. 子树的最大平均值
同类题目
前置知识
- 无
题目描述
给你一棵二叉树的根节点 root,找出这棵树的 每一棵 子树的 平均值 中的 最大 值。
子树是树中的任意节点和它的所有后代构成的集合。
树的平均值是树中节点值的总和除以节点数。
示例:
输入:[5,6,1]
输出:6.00000
解释:
以 value = 5 的节点作为子树的根节点,得到的平均值为 (5 + 6 + 1) / 3 = 4。
以 value = 6 的节点作为子树的根节点,得到的平均值为 6 / 1 = 6。
以 value = 1 的节点作为子树的根节点,得到的平均值为 1 / 1 = 1。
所以答案取最大值 6。
提示:
- 树中的节点数介于
1到5000之间。 - 每个节点的值介于
0到100000之间。 - 如果结果与标准答案的误差不超过
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…