问题描述
给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.
示例 1:
输入:
3
/
9 20
/
15 7
输出: [3, 14.5, 11]
解释:
第0层的平均值是 3, 第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].
注意:
节点值的范围在32位有符号整数范围内。
解题思路
树结构的 层序,第一反应的思路就是层序遍历的思想:通过Queue来存每一行,通过三个遍历来控制每一层,但这里有要注意的是:层序遍历的时候,最后一层的元素也单独poll,这样会多计算出一行空值,所以要去掉最后一项。
实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) {
return new ArrayList<Double>();
}
int curCount = 0;
int curNum = 1;
int nextCount = 1;
double linesum = 0;//坑点处
List<Double> reslist = new ArrayList<>();
reslist.add((double) root.val);
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode t = queue.poll();
if (t.left != null) {
queue.offer(t.left);
linesum = linesum + t.left.val;
nextCount++;
}
if (t.right != null) {
queue.offer(t.right);
linesum = linesum + t.right.val;
nextCount++;
}
if (++curCount == curNum) {
reslist.add((double) linesum / (nextCount - curCount));
linesum = 0;
curNum = nextCount;
}
}
reslist.remove(reslist.size()-1);
return reslist;
}
}
陷阱
节点值的范围在32位有符号整数范围内:int虽然是4个字节,32位,但 linesum = linesum + t.right.val;加和的结果就不是这个范围了,要用double类型来接,否则会错误
double linesum = 0;//坑点处
别人的实现
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res = new ArrayList<>();
Queue<TreeNode> que = new LinkedList<>();
que.add( root );
double curSum = 0;
while( !que.isEmpty() ){
int si = que.size();
for( int i = 0 ; i < si ; i ++ ){
TreeNode cur = que.poll(); //每次弹出上一层节点
if( cur.left != null )que.add( cur.left );//queue放入当前层的节点
if( cur.right != null )que.add( cur.right );
curSum += cur.val;//计算上一层和
}
res.add( curSum / si );
curSum = 0;
}
return res;
}
}
看起来更容易懂,更清晰一些
- 首先把根节点放入队列
- 循环中取队列的长度,根据长度,弹出并取出队列元素,判断弹出的元素是否有孩子节点,有的话就放入队列,加和求平均值。