小学生都能看懂的题解 | #数据流中的中位数#

数据流中的中位数

https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1

问题是什么?

我们需要一个程序,这个程序可以从一个数据流里不断地读取数字,并且能随时告诉我们这些数字的“中间数”(也就是中位数)。如果数字的总数是奇数,中位数就是正中间的那个数;如果是偶数,中位数就是中间两个数的平均值。

我们怎么解决?

我们可以想象有两个队伍,一个是“小队”,一个是“大队”。每次新来一个数字,我们就把它放到合适的队伍里。“小队”总是放更小的数,“大队”放更大的数。但是,这两个队伍的人数不能差太多,最多只能差一个人。

具体怎么做?

  1. 创建两个队伍:
  2. “小队”用一个叫做 maxHeap 的特殊队伍,它总是让最大的数站在最前面。
  3. “大队”用一个叫做 minHeap 的特殊队伍,它总是让最小的数站在最前面。
  4. 每次有新数字来的时候:
  5. 如果这个数字比“小队”的队长还小,或者“小队”是空的,就把它加到“小队”里。
  6. 否则,把它加到“大队”里。
  7. 保持队伍人数接近:
  8. 如果“小队”的人数比“大队”多两个人以上,就把“小队”的队长送到“大队”去。
  9. 如果“大队”的人数比“小队”多,就把“大队”的队长送到“小队”去。
  10. 找出中位数:
  11. 如果两个队伍人数一样,中位数就是两个队长的平均值。
  12. 如果“小队”的人数比“大队”多一个,中位数就是“小队”的队长。

实现代码:

下面的代码实现了上面说的功能,使用了 Java 的 PriorityQueue(优先队列),来帮助我们管理这两个特殊的队伍。

import java.util.PriorityQueue;

public class MedianFinder {
    private PriorityQueue<Integer> smallTeam; // 小队,保存较小的数
    private PriorityQueue<Integer> bigTeam; // 大队,保存较大的数

    public MedianFinder() {
        smallTeam = new PriorityQueue<>((a, b) -> b - a); // 小队,让大的数排前面
        bigTeam = new PriorityQueue<>(); // 大队,让小的数排前面
    }

    // 插入新数字的方法
    public void Insert(Integer val) {
        if (smallTeam.isEmpty() || val <= smallTeam.peek()) {
            smallTeam.add(val);
        } else {
            bigTeam.add(val);
        }

        // 保持队伍人数接近
        if (smallTeam.size() > bigTeam.size() + 1) {
            bigTeam.add(smallTeam.poll());
        } else if (bigTeam.size() > smallTeam.size()) {
            smallTeam.add(bigTeam.poll());
        }
    }

    // 获取中位数的方法
    public Double GetMedian() {
        if (smallTeam.size() == bigTeam.size()) {
            return (smallTeam.peek() + bigTeam.peek()) / 2.0;
        } else {
            return (double)smallTeam.peek();
        }
    }
}

这个代码会把新来的数字放进合适的队伍,并且随时调整队伍,确保我们总能找到正确的中位数。

如果这篇文章对你有帮助,请点个免费的赞👍,让它能够帮助更多的人。

#牛客创作赏金赛#
小学生都能看懂的算法 文章被收录于专栏

主要面向小白的算法文章。以小学生都能看懂为目标而编写,顺便巩固下自己。

全部评论

相关推荐

和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务