解法一:
/**
* 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) {
//这里的队列不能用PriorityQueue,因为它会进行排序,影响遍历,所以用Queue的实现类LinkedList
Queue<TreeNode> tree = new LinkedList<>();
Queue<Integer> level = new LinkedList<>();
List<Double> list = new ArrayList<>();
if(root == null) return list;
tree.add(root);
level.add(1);//根节点在第一层
Double sum = 0.0;
int count = 0;
int curLevel = 0;//记录当前求和的是第几层
while(!tree.isEmpty()){
TreeNode popNode = tree.poll();//遍历取出一个结点
int popLevel = level.poll();
if(curLevel != popLevel){//是新的一层,就开启
//保留上一层的结果
if(count != 0){//排除一开始进入循环时的情况
list.add(sum / count);
}
curLevel = popLevel;
count = 1;
sum = (double) popNode.val;
} else{//不是新的一层,就继续叠加
count++;
sum += popNode.val;
}
//压入左右子节点
if(popNode.left != null){
tree.add(popNode.left);
level.add(popLevel + 1);//同步跟踪层数
}
if(popNode.right != null){
tree.add(popNode.right);
level.add(popLevel + 1);//同步跟踪层数
}
}
//因为上面的循环中是在下一层才统计上一层的结果,所以最后一层需要单独处理
if(count != 0){
list.add(sum / count);
}
return list;
}
}