力扣295. 数据流的中位数(java,堆解法)

Problem: 295. 数据流的中位数

文章目录

题目描述


思路

由于该题目的数据是动态的 我们可以维护两个来解决该问题

1.维护一个大顶堆,一个小顶堆

2.每个堆中元素个数接近n/2;如果n是偶数,两个堆中的数据个数都是n/2;如果n是奇数,则大顶堆中有n/2 + 1个数据,小顶堆中有n/2个数据

3.大顶堆中的数据值都要小于小顶堆中的数据值

即大顶堆中的堆顶元素就是中位数

解题方法

1.(创建堆)按思路创建一个大顶堆和小顶堆

2.(维护堆):

2.1.如果新插入数据小于等于大顶堆,则将其插入到大顶堆中,否则插入到小顶堆;

2.2.插入数据后,两个堆中的数据量个数不满足思路中的要求2,则我们需要从一个堆中不停的将堆顶元素移动到另一个堆

复杂度

时间复杂度:

a d d N u m : O ( l o g n ) addNum:O(logn) addNum:O(logn)
f i n d M e d i a n : O ( 1 ) findMedian:O(1) findMedian:O(1)

空间复杂度:

O ( n ) O(n) O(n)

Code

java 复制代码
class MedianFinder {
    /*维护一个大顶堆和小顶堆*/
    private PriorityQueue<Integer> minQueue = new PriorityQueue<>(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 - o2;
        }
    });
    private PriorityQueue<Integer> maxQueue = new PriorityQueue<>(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    });

    public MedianFinder() {

    }

    /**
     * 数据流插入数据
     *
     * @param num 待插入的数据
     */
    public void addNum(int num) {
        //如果插入数据小于等于大顶堆堆顶元素,大顶堆直接插入
        if (maxQueue.isEmpty() || num <= maxQueue.peek()) {
            maxQueue.add(num);
        } else {
            minQueue.add(num);
        }
        //大顶堆数据量不能小于小顶堆
        while (maxQueue.size() < minQueue.size()) {
            Integer minQueueElement = minQueue.poll();
            maxQueue.add(minQueueElement);
        }
        //小顶堆数据量可以比大顶堆小一个
        while (minQueue.size() < maxQueue.size() - 1) {
            Integer maxQueueElement = maxQueue.poll();
            minQueue.add(maxQueueElement);
        }
    }

    /**
     * 找出中位数
     *
     * @return double
     */
    public double findMedian() {
        //如果大顶堆数据量大于小顶堆
        if (maxQueue.size() > minQueue.size()) {
            return maxQueue.peek();
        } else {
            return (maxQueue.peek() + minQueue.peek()) / 2f;
        }
    }
}


/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */
相关推荐
不爱学习的YY酱5 分钟前
【计网不挂科】计算机网络第二章< 物理层 >习题库(含答案)
java·数据库·计算机网络
qq_2739002316 分钟前
pytorch detach方法介绍
人工智能·pytorch·python
南城花随雪。24 分钟前
Spring框架之装饰者模式 (Decorator Pattern)
java·开发语言·装饰器模式
编程、小哥哥28 分钟前
设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
java·设计模式·装饰器模式
虞书欣的635 分钟前
Python小游戏24——小恐龙躲避游戏
开发语言·python·游戏·小程序·pygame
FHYAAAX43 分钟前
【机器学习】任务十:从函数分析到机器学习应用与BP神经网络
开发语言·python
PyAIGCMaster1 小时前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python
何曾参静谧1 小时前
「Py」模块篇 之 PyAutoGUI库自动化图形用户界面库
运维·python·自动化
pumpkin845141 小时前
客户端发送http请求进行流量控制
python·网络协议·http
smj2302_796826522 小时前
用枚举算法解决LeetCode第3348题最小可整除数位乘积II
python·算法·leetcode