java数据结构与算法刷题-----LeetCode637. 二叉树的层平均值

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

在这里插入图片描述

解题思路:时间复杂度O(n),空间复杂度O(n)
  1. 使用广度优先遍历,按层遍历即可,遍历过程中,记录每层的结点和,最后将其平均数求出
  2. 使用深度优先遍历,需要记录当前结点的层次,然后必须使用一个可以通过下标获取值的容器来记录每个结点值

深度遍历时,将当前结点值累加到当前结点所在层次对应的地方,也就是容器对应下标(下标代表层次)位置。

1. 广度优先

代码:给出两种代码思路,一种是普通做法,第二种是直接在生成容器时,静态构建,因此第二种非常快,作为扩展了解即可
  1. 普通方法
    在这里插入图片描述
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> list = new ArrayList<>();//答案
        Queue<TreeNode> bfs_queue = new LinkedList<>();//广度优先队列
        bfs_queue.offer(root);//根结点入队列
        while(!bfs_queue.isEmpty()){
            int size = bfs_queue.size();//获取当前层中结点个数
            long sum = 0;//记录当前层结点的和
            for(int i = 0;i<size;i++){//遍历当前层
                TreeNode poll = bfs_queue.poll();//出队列
                sum+=poll.val;//累加
                if(poll.left!=null) bfs_queue.offer(poll.left);
                if(poll.right!=null)bfs_queue.offer(poll.right);
            }
            list.add((double)sum/size);//计算平均值
        }
        return list;
    }
    
}
  1. 进阶方法
    在这里插入图片描述
import java.util.AbstractList;
class Solution {
    public static List<Double> averageOfLevels(TreeNode root) {
        return new AbstractList<Double>() {//直接构建抽象链表
            private final List<Double> list = new ArrayList<>();//此链表保存答案
            private final List<TreeNode> level = new ArrayList<>();//此链表用于深度优先遍历
            @Override
            public Double get(int index) {//此方法为重写链表构建方法,获取指定下标值
                init();//初始化链表
                return list.get(index);//获取值
            }
            @Override
            public int size() {//获取链表值
                init();
                return list.size();
            }
            void init() {//初始化链表
                if (list.isEmpty()) {//如果链表为空,就初始化
                    level.add(root);//广度优先初始化
                    while (!level.isEmpty()) {
                        levelTraverse(level);
                    }
                }
            }
            //广度优先逻辑,统计每层的平均值
            void levelTraverse(List<TreeNode> level) {
                int count = level.size();
                long sum = 0;
                for (int i = 0; i < count; i++) {
                    TreeNode tree = level.get(0);
                    sum += tree.val;
                    if (tree.left != null) {
                        level.add(tree.left);
                    }
                    if (tree.right != null) {
                        level.add(tree.right);
                    }
                    level.remove(0);
                }
                list.add((double) sum / count);
            }
        };
    }
}

2. 深度优先

代码

在这里插入图片描述

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);//对应层结点个数+1
        } else {//如果第一次到达当前层,创建层次,当前结点值为当前层第一个结点,当前层结点个数为1
            sums.add(1.0 * root.val);//
            counts.add(1);
        }
        //继续遍历
        dfs(root.left, level + 1, counts, sums);
        dfs(root.right, level + 1, counts, sums);
    }
}
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值