二叉树的层平均值[中等]

优质博文:IT-BLOG-CN

一、题目

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第0层的平均值为3,第1层的平均值为14.5,第2层的平均值为11
因此返回[3, 14.5, 11]

示例 2:

输入:root = [3,9,20,15,7]
输出:[3.00000,14.50000,11.00000]

树中节点数量在[1, 104]范围内
-231 <= Node.val <= 231 - 1

二、代码

【1】深度优先搜索: 使用深度优先搜索计算二叉树的层平均值,需要维护两个数组,counts用于存储二叉树的每一层的节点数,sums用于存储二叉树的每一层的节点值之和。搜索过程中需要记录当前节点所在层,如果访问到的节点在第i层,则将counts[i]的值加1,并将该节点的值加到sums[i]。遍历结束之后,第i层的平均值即为sums[i]/counts[i]

class Solution {public List<Double> averageOfLevels(TreeNode root) {List<Integer> counts = new ArrayList<Integer>();List<Double> sums = new ArrayList<Double>();dfs(root, 0, counts, sums);List<Double> averages = new ArrayList<Double>();int size = sums.size();for (int i = 0; i < size; i++) {averages.add(sums.get(i) / counts.get(i));}return averages;}public void dfs(TreeNode root, int level, List<Integer> counts, List<Double> sums) {if (root == null) {return;}if (level < sums.size()) {sums.set(level, sums.get(level) + root.val);counts.set(level, counts.get(level) + 1);} else {sums.add(1.0 * root.val);counts.add(1);}dfs(root.left, level + 1, counts, sums);dfs(root.right, level + 1, counts, sums);}
}

时间复杂度: O(n),其中n是二叉树中的节点个数。深度优先搜索需要对每个节点访问一次,对于每个节点,维护两个数组的时间复杂度都是O(1),因此深度优先搜索的时间复杂度是O(n)。遍历结束之后计算每层的平均值的时间复杂度是O(h),其中h是二叉树的高度,任何情况下都满足h≤n。因此总时间复杂度是O(n)
空间复杂度: O(n),其中n是二叉树中的节点个数。空间复杂度取决于两个数组的大小和递归调用的层数,两个数组的大小都等于二叉树的高度,递归调用的层数不会超过二叉树的高度,最坏情况下,二叉树的高度等于节点个数。

【2】广度优先搜索: 也可以使用广度优先搜索计算二叉树的层平均值。从根节点开始搜索,每一轮遍历同一层的全部节点,计算该层的节点数以及该层的节点值之和,然后计算该层的平均值。如何确保每一轮遍历的是同一层的全部节点呢?我们可以借鉴层次遍历的做法,广度优先搜索使用队列存储待访问节点,只要确保在每一轮遍历时,队列中的节点是同一层的全部节点即可。具体做法如下:
1、初始时,将根节点加入队列;
2、每一轮遍历时,将队列中的节点全部取出,计算这些节点的数量以及它们的节点值之和,并计算这些节点的平均值,然后将这些节点的全部非空子节点加入队列,重复上述操作直到队列为空,遍历结束。

由于初始时队列中只有根节点,满足队列中的节点是同一层的全部节点,每一轮遍历时都会将队列中的当前层节点全部取出,并将下一层的全部节点加入队列,因此可以确保每一轮遍历的是同一层的全部节点。具体实现方面,可以在每一轮遍历之前获得队列中的节点数量size,遍历时只遍历size个节点,即可满足每一轮遍历的是同一层的全部节点。

class Solution {public List<Double> averageOfLevels(TreeNode root) {List<Double> averages = new ArrayList<Double>();Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.offer(root);while (!queue.isEmpty()) {double sum = 0;int size = queue.size();for (int i = 0; i < size; i++) {TreeNode node = queue.poll();sum += node.val;TreeNode left = node.left, right = node.right;if (left != null) {queue.offer(left);}if (right != null) {queue.offer(right);}}averages.add(sum / size);}return averages;}
}

时间复杂度: O(n),其中n是二叉树中的节点个数。广度优先搜索需要对每个节点访问一次,时间复杂度是O(n)。需要对二叉树的每一层计算平均值,时间复杂度是O(h),其中h是二叉树的高度,任何情况下都满足h≤n。因此总时间复杂度是O(n)
空间复杂度: O(n),其中n是二叉树中的节点个数。空间复杂度取决于队列开销,队列中的节点个数不会超过n

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/256118.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

堆栈,BSS,DATA,TEXT

一、目标文件 首先目标文件的构成&#xff0c;Linux下就是.o 文件 编译器编译源码后生成的文件叫目标文件&#xff08;Object File&#xff09;。 目标文件和可执行文件一般采用同一种格式&#xff0c;这种存储格式为 ELF。 目前文件的内容至少有编译后的机器指令代码和数据&a…

汽车软件大时代,如何提升软件工程创新力?

当前&#xff0c;传统汽车产业正加速数字化转型&#xff0c;“软件定义汽车”不断深化。在电动化、智能化和网联化趋势下&#xff0c;汽车软件已经成为汽车技术革新和发展的核心驱动力之一。根据亿欧智库发布的《2023中国智能电动汽车车载软件市场分析报告》&#xff0c;2022年…

产品成本收集器流程演示

感谢大佬的文章&#xff0c;我只是一个翻译搬运工&#xff0c;原文地址&#xff1a;产品成本收集器 概述 SAP 令人兴奋的部分之一是它在不同操作模块之间的集成程度。使用产品成本收集器来跟踪生产就是一个很好的例子。在本博客中&#xff0c;我计划遵循产品成本收集器流程&a…

Matlab 点云对称性检测

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 这是一个很有趣的功能,它的思路其实与ICP算法的思路有些相似: 首先,它会初始化两个旋转角度,即绕x轴旋转与绕y轴旋转,初始的过程是将点对称(镜像)过去,计算与匹配点之间的距离误差,误差最小者为最优初始值…

C语言之Switch语句

目录 Switch语句和break语句 复杂的Switch语句 选择语句 if语句会根据某个条件的判断结果&#xff0c;将程序的流程分为两支&#xff0c;而Switch语句&#xff0c;则会将程序分为多个分支。 Switch语句和break语句 让我们来看下Switch语句的结构图&#xff1a;&#xff08…

软件开发、管理、运维、实施、验收、交付、安全检查等文档支撑

软件开发涉及到哪些文档&#xff1a; 全文档获取&#xff1a;点我获取 可行性分析报告&#xff1a;在项目开始前&#xff0c;需要编写可行性分析报告&#xff0c;评估项目的可行性、技术需求、成本预算等因素&#xff0c;为决策提供依据。项目开发计划&#xff1a;明确项目的…

基于个微机器人的开发

简要描述&#xff1a; 下载消息中的动图 请求URL&#xff1a; http://域名/getMsgEmoji 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明…

C++新经典模板与泛型编程:用成员函数重载实现std::is_convertible

用成员函数重载实现is_convertible C标准库中提供的可变参类模板std::is_convertible&#xff0c;这个类模板的主要能力是判断能否从某个类型隐式地转换到另一个类型&#xff0c;返回的是一个布尔值true或false。例如&#xff0c;一般的从int转换成float或从float转换成int&am…

Zabbix自动发现机制

Zabbix的自动发现机制 Zabbix客户端主动的和服务端联系&#xff0c;将自己的地址和端口发送服务端&#xff0c;实现自动添加监控主机&#xff0c;客户端是主动的一方缺点自定义网段中主机数量太多&#xff0c;等级耗时会很久&#xff0c;而且这个自动发现机制不是很稳定 Zabb…

分享一个微信红包封面过审方法

大家好&#xff0c;我是小悟 兄弟们&#xff0c;已经12月份了&#xff0c;今年的最后一个月&#xff0c;距离过年还有两个月左右&#xff0c;如果你需要制作微信红包封面&#xff0c;我建议你现在就可以着手了。 一方面&#xff0c;临近春节&#xff0c;会有很多人在制作红包封…

解决思维题的一些自我总结

目录 常见思维题类型 排序 区间问题 01串串 字符串串 位运算 gcd 与 lcm 质数相关 二元组 常见思维题类型 思维题很多都可以说是贪心、但贪心种类很多&#xff0c;具体怎么贪&#xff0c;重要的还是在于积累经验吧...有些东西也很难总结&#xff0c;以下算是我的碎碎念…

项目架构-六边形架构的概述和实现

使用传统的分层架构&#xff0c;我们的所有依赖项都指向一个方向&#xff0c;上面的每一层都依赖于下面的层。传输层将依赖于交互器&#xff0c;交互器将依赖于持久层。 在六边形架构中&#xff0c;所有依赖项都指向内部——我们的核心业务逻辑对传输层或数据源一无所知。尽管如…