【力扣hot100题】(075)数据流的中位数

一开始只建立了一个优先队列,每次查询中位数时都要遍历一遍于是喜提时间超限,看了答案才恍然大悟原来还有这么聪明的办法。

方法是建立两个优先队列,一个大根堆一个小根堆,大根堆记录较小的数,小根堆记录较大的数。

每次加入元素时首先和大根堆最大的数进行比较,若元素更小则加入大根堆,否则加入小根堆,接着比较大根堆小根堆的大小,若大根堆比小根堆大超过一个元素(默认元素总数为奇数时大根堆多一个元素),则将大根堆最大元素加入小根堆并从大根堆移除那个元素;若小根堆比大根堆大时同理。

找出中位数时若总数为偶数(大根堆小根堆大小相等),则取大根堆最大元素和小根堆最小元素相加除以二;若总数为奇数(大根堆多一个元素),则直接取大根堆最大的元素。

好聪明的办法!!

另外小根堆构造方法是priority_queue<int,vector<int>,greater<int>> minq;,其中greater是小元素在前的比较函数。(大根堆中这个函数是less<int>)

cpp 复制代码
class MedianFinder {
public:
    priority_queue<int> maxq; //大根堆,记录较小的数
    priority_queue<int,vector<int>,greater<int>> minq; //小根堆,记录较大的数
    MedianFinder() {
    }
    
    void addNum(int num) {
        if(maxq.empty()||num<maxq.top()){
            maxq.emplace(num);
            if(maxq.size()>minq.size()+1){
                minq.emplace(maxq.top());
                maxq.pop();
            }
        }
        else{
            minq.emplace(num);
            if(minq.size()>maxq.size()){
                maxq.emplace(minq.top());
                minq.pop();
            }
        }

    }
    
    double findMedian() {
        if(maxq.size()==minq.size()) return (maxq.top()+minq.top())/2.0;
        else return maxq.top();
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */
相关推荐
毕设源码-钟学长1 分钟前
【开题答辩全过程】以 基于Spark机器学习算法的体育新闻智能分类系统设计与实现为例,包含答辩的问题和答案
算法·机器学习·spark
天勤量化大唯粉4 分钟前
基于距离的配对交易策略:捕捉价差异常偏离的均值回归机会(天勤量化代码实现)
android·开发语言·python·算法·kotlin·开源软件·策略模式
智航GIS5 分钟前
ArcGIS大师之路500技---036通俗易懂讲解克里金法
人工智能·算法·arcgis
拼好饭和她皆失7 分钟前
逆元,除法同余原理
算法·逆元·除法同余原理
leiming68 分钟前
c++ 利用模板创建一个可以储存任意类型数据的数组类
开发语言·c++·算法
TL滕11 分钟前
从0开始学算法——第二十天(简易搜索引擎)
笔记·学习·算法
cpp_250118 分钟前
P8723 [蓝桥杯 2020 省 AB3] 乘法表
数据结构·c++·算法·蓝桥杯·题解·洛谷
牛客企业服务23 分钟前
AI面试:如何从概念真正落地?
人工智能·面试·职场和发展
再__努力1点28 分钟前
【76】Haar特征的Adaboost级联人脸检测全解析及python实现
开发语言·图像处理·人工智能·python·算法·计算机视觉·人脸检测
溟洵29 分钟前
【算法C++】链表(题目列表:两数相加、两两交换链表中的节点、重排链表、合并 K 个升序链表、K 个一组翻转链表7)
数据结构·c++·算法·链表