295. 数据流的中位数

目录

题目

基础知识补充

优先队列

map、set


题目

题目出处:https://leetcode-cn.com/problems/find-median-from-data-stream/

思路:在数据插入的过程中维护一个大根堆和一个小根堆,并始终保持大根堆的元素个数==小根堆的个数或者大根堆的元素个数==小根堆的个数-1。大根堆中存放的是数据流的较小半段元素;小根堆中存放的是数据流中的较大一半的元素。每次数据插入都针对小根堆。

流程

  1. 若小根堆为空则将该元素直接插入小根堆。
  2. 若小根堆堆顶的元素大于当前要插入的元素,则将该元素插入到大根堆中,并判断此时大根堆和小根堆的元素个数的大小,若大根堆的元素个数多于小根堆的元素个数,则将此时大根堆的堆顶元素弹出并插入到小根堆中。
  3. 若小根堆堆顶的元素小于等于当前要插入的元素,则将该元素插入到小根堆中,并判断此时大根堆和小根堆的元素个数的大小,若小根堆中的元素个数比大根堆中元素个数多2个及以上,则将小根堆堆顶元素弹出并插入到大根堆中去。
class MedianFinder {
private:
    int n = 0;
    priority_queue<int, vector<int>, greater<int>> small_q;  //小根堆,升序
    priority_queue<int, vector<int>, less<int>> big_q;   //大根堆,降序
public:
    /** initialize your data structure here. */
    MedianFinder() {

    }
    
    void addNum(int num) {
        if(small_q.empty()){  //小根堆为空,直接插入 
            small_q.push(num);
        }
        else if(num > small_q.top()){  //插入元素比小根堆堆顶元素大,直接插入
            small_q.push(num);
            if(small_q.size() > big_q.size()+1){
                big_q.push(small_q.top());
                small_q.pop();              
            }
        }    
        else{    //插入的元素比比小根堆堆顶元素小, 往大根堆中插入
            big_q.push(num);
            if(small_q.size() < big_q.size()){
                small_q.push(big_q.top());
                big_q.pop();  
            }
        }
        ++n;
    }
    
    double findMedian() {
        if(n & 1){
            return small_q.top();
        }

        return (small_q.top()+big_q.top()) / 2.0;
    }
};

基础知识补充

优先队列

  priority_queue<int, vector<int>, greater<int>> q;  //升序排序,小根堆

  priority_queue<int, vector<int>, less<int>> q;  //降序排序,大根堆 (默认) 

map、set

map<int ,int> //默认按键值升序排序  ,默认是map<int, int,less<int>> 

map<int, int, greater<int>> //按键值降序排列

set<int>  //默认按键值升序排序  ,默认是set<int, less<int>> 

set<int, greater<int>> mp({6,4,1,2,7,0});     //按键值降序排列

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值