「这是我参与2022首次更文挑战的第 19 天,活动详情查看:2022首次更文挑战」
题目链接
637. 二叉树的层平均值 - 力扣(LeetCode) (leetcode-cn.com)
题目描述
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 以内的答案可以被接受。
测试用例
示例 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] 。
条件限制
树中节点数量在 范围内
题目分析
题目需要我们求二叉树的每一层的平均值,这种就是标准的广度搜索遍历。
这里用到了几个变量,currLayer 表示当前层需要遍历的点,nextLayer 表示下一层准备遍历的点,avgs 表示每层的节点求和的平均值
在遍历当前层的节点的时候,将这个节点存在的左右子节点存入到 nextLayer,并且需要一个临时数组 tempArr 来记录当前层遍历时每个节点的值,在当前层遍历完成后,通过 tempArr 求出平均值,并依次添加到 avgs 即可
最后我们再返回 avgs 即为题目所需
注意点:因为求平均值大概率会有除不尽的情况,题目暗示了需要我们保留4位小数。
代码实现
var averageOfLevels = function(root) {
let currLayer = [root],
nextLayer = [];
let avgs = [];
while (currLayer.length > 0 || nextLayer.length > 0) {
let vals = [];
while (currLayer.length > 0) {
let curr = currLayer.shift();
vals.push(curr.val);
if (curr.left != null) nextLayer.push(curr.left);
if (curr.right != null) nextLayer.push(curr.right);
}
currLayer=nextLayer;
nextLayer=[];
let avg = vals.reduce((a,b)=>a+b,0)/vals.length;
avgs.push(avg.toFixed(5));
}
return avgs;
};
优化
之所以需要 nextLayer, currLayer 来标记每一层的节点,是因为当这些节点都存一个数组时,无法区分当前遍历的节点是哪一层的
但我们使用一个计数标记 len 来辅助确认需要从数组中取出多少个元素元素时,一个数组变量足以。
每次取出 len 个节点,这些取出的节点,都位于同一层。等遍历完成后,我们重置 len 的值,为当前节点数组的长度,重复上一步
代码优化如下:
var averageOfLevels = function(root) {
let layer = [root];
let avgs = [];
for (let len = layer.length; len > 0; len = layer.length) {
let sum = 0;
let count = len;
for (; len > 0; len--) {
let curr = layer.shift();
sum += curr.val;
if (curr.left != null) layer.push(curr.left);
if (curr.right != null) layer.push(curr.right);
}
avgs.push(sum / count);
}
return avgs;
};