27.LeetCode 2265. 统计值等于子树平均值的节点数 —— 后序遍历实战

一、题目分析

题目要求统计二叉树中满足 "节点值等于其所在子树平均值" 的节点数量。子树平均值的计算规则为:子树所有节点值之和 ÷ 子树节点总数。

示例解析

以输入 root = [4,8,5,0,1,null,6] 为例:

  • 节点 4 的子树包含 6 个节点,总和为 24,平均值为 4,与节点值相等,符合条件。
  • 节点 5 的子树包含 2 个节点,总和为 11,平均值为 5,与节点值相等,符合条件。
  • 叶子节点 0、1、6 的子树仅包含自身,平均值等于节点值,均符合条件。 最终输出结果为 5。

二、解题思路

核心思路是后序遍历二叉树,因为计算子树的平均值需要先获取左、右子树的节点总和与节点数,再结合当前节点的值进行计算。具体步骤如下:

  1. 递归遍历左子树,获取左子树的节点总和与节点数。

  2. 递归遍历右子树,获取右子树的节点总和与节点数。

  3. 计算当前节点所在子树的总和(左子树总和 + 右子树总和 + 当前节点值)与节点数(左子树节点数 + 右子树节点数 + 1)。

  4. 计算子树平均值,判断是否与当前节点值相等,若相等则统计结果加 1。

  5. 将当前子树的总和与节点数返回给上层递归。

    #include
    #include
    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:
    int result = 0; // 统计符合条件的节点数

    复制代码
     // 后序遍历辅助函数,返回当前子树的总和与节点数
     pair<int, int> postOrder(TreeNode* root) {
         if (root == nullptr) {
             return {0, 0}; // 空节点返回总和0,节点数0
         }
    
         // 递归遍历左子树
         auto [leftSum, leftCount] = postOrder(root->left);
         // 递归遍历右子树
         auto [rightSum, rightCount] = postOrder(root->right);
    
         // 计算当前子树的总和与节点数
         int currentSum = leftSum + rightSum + root->val;
         int currentCount = leftCount + rightCount + 1;
    
         // 判断当前节点值是否等于子树平均值
         if (root->val == currentSum / currentCount) {
             result++;
         }
    
         // 返回当前子树的总和与节点数给上层
         return {currentSum, currentCount};
     }

    public:
    int averageOfSubtree(TreeNode* root) {
    postOrder(root);
    return result;
    }
    };

    // 测试代码
    int main() {
    // 构建示例二叉树
    TreeNode* root = new TreeNode(4);
    root->left = new TreeNode(8);
    root->right = new TreeNode(5);
    root->left->left = new TreeNode(0);
    root->left->right = new TreeNode(1);
    root->right->right = new TreeNode(6);

    复制代码
     Solution sol;
     cout << "符合条件的节点数:" << sol.averageOfSubtree(root) << endl; // 输出5
    
     // 释放内存(可选,避免内存泄漏)
     delete root->left->left;
     delete root->left->right;
     delete root->right->right;
     delete root->left;
     delete root->right;
     delete root;
    
     return 0;

    }

四、代码说明

  1. 二叉树节点结构 :使用 TreeNode 结构体定义二叉树节点,包含节点值、左子节点指针和右子节点指针。
  2. 后序遍历函数 :postOrder 函数通过递归实现后序遍历,返回值为 pair<int, int>,分别表示子树的总和与节点数。
  3. 统计逻辑 :在计算完当前子树的总和与节点数后,判断节点值是否等于子树平均值,若相等则将 result 加 1。
  4. 测试代码 :构建题目示例中的二叉树,调用 averageOfSubtree 函数并输出结果。

五、复杂度分析

  • 时间复杂度:O (n),其中 n 为二叉树的节点数,每个节点仅被遍历一次。
  • 空间复杂度:O (h),其中 h 为二叉树的高度,递归栈的深度取决于树的高度。
相关推荐
AiNightVision8 分钟前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件
硅基手札33 分钟前
【Linux 内核专栏 19】20 · 嵌入式子系统 — GPIO·pinctrl·clock·regulator
linux·运维·单片机·linux内核·嵌入式开发·调试定位
牧羊人.3331 小时前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
小郎君6582 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie7772 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai
東隅已逝,桑榆非晚2 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
专注仿真2 小时前
卷积神经网络(CNN)算法详解
人工智能·python·算法·代码·大模型训练
FII工业富联科技服务2 小时前
多智能体如何进入制造现场?从业务协同到数字孪生验证
大数据·人工智能·算法·机器人·制造·数字孪生
何粥学3 小时前
Vivado 2024.2 开发记录(AC820 Zynq-7020)——软件使用,点亮led灯
单片机·嵌入式硬件·zynq
≮傷£≯√3 小时前
httpserver_QNetWorkClient
算法