声明:问题描述来源leetcode
一、问题描述:
637. 二叉树的层平均值
难度简单373
给定一个非空二叉树的根节点 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
- 树中节点数量在
二、题解:
下面这个直接是int超过最大数值导致出错,思路还是层序遍历
public class Solution {
List<Double> averageList = new LinkedList<>();
List<List<Integer>> lists = new LinkedList<>();
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) return averageList;
lists.add(new LinkedList<>());
searchGoalByOrder(0,root);
addAverageToResult();
return averageList;
}
private void searchGoalByOrder(int order, TreeNode root) {
lists.get(order).add(root.val);
if (root.left != null){
if (order + 1 > lists.size() - 1) lists.add(new LinkedList<>());
searchGoalByOrder(order + 1,root.left);
}
if (root.right != null){
if (order + 1 > lists.size() - 1) lists.add(new LinkedList<>());
searchGoalByOrder(order + 1,root.right);
}
}
private void addAverageToResult() {
for (List<Integer> list :lists) {
int sum = 0;
for (int i :list) {
sum += i;
}
averageList.add((sum + 0.0) / list.size());
}
}
于是修改下:
题解1:
class Solution {
List<Double> averageList = new LinkedList<>();
List<List<Double>> lists = new LinkedList<>();
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) return averageList;
lists.add(new LinkedList<>());
searchGoalByOrder(0,root);
addAverageToResult();
return averageList;
}
private void searchGoalByOrder(int order, TreeNode root) {
lists.get(order).add(root.val + 0.0);
if (root.left != null){
if (order + 1 > lists.size() - 1) lists.add(new LinkedList<>());
searchGoalByOrder(order + 1,root.left);
}
if (root.right != null){
if (order + 1 > lists.size() - 1) lists.add(new LinkedList<>());
searchGoalByOrder(order + 1,root.right);
}
}
private void addAverageToResult() {
for (List<Double> list :lists) {
double sum = 0;
for (double i :list) {
sum += i;
}
averageList.add((sum) / list.size());
}
}
}
上面的运行才3ms,还是有待优化的。
end
题解2(优化):
class Solution {
List<Double> averageList = new LinkedList<>();
List<Double[]> lists = new LinkedList<>();
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) return averageList;
lists.add(new Double[]{0.0,0.0});
searchGoalByOrder(0,root);
addAverageToResult();
return averageList;
}
private void searchGoalByOrder(int order, TreeNode root) {
lists.get(order)[0] += root.val;
lists.get(order)[1] ++;
if (root.left != null){
if (order + 1 > lists.size() - 1) lists.add(new Double[]{0.0,0.0});
searchGoalByOrder(order + 1,root.left);
}
if (root.right != null){
if (order + 1 > lists.size() - 1) lists.add(new Double[]{0.0,0.0});
searchGoalByOrder(order + 1,root.right);
}
}
private void addAverageToResult() {
for (Double[] arr :lists) {
averageList.add(arr[0] / arr[1]);
}
}
}
还是层序遍历,只是处理平均值时转换下处理的方法,用double数值来处理数据,节点的val叠加到数组的首元素上,数组的第二元素表示其数量,每次都要更新数组的这两个值。还是数组比链表操作快些。