剑指offer面试题[64]-数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

分析:

       由于数据是从数据流中读出来的,数据的数目随着时间的变换而变化的。需要请用一个数据容器来保存从数据流中读出来的数据,当有新的数据从流中读出来时,这些数据就插入到数据容器中。

       如果数组没有排序,可以用partition函数找出数组中的中位数。在没有排序的数组中插入一个数字和找出中位数的时间复杂度分别是0(1)和0(n).

       可以用最大堆和最小堆的思想,详情见剑指offer面试题64。

       参考代码如下:

class Solution {
public:
    void Insert(int num)
    {
       if((min.size()+max.size()&1)==0)  //偶数位置,放入到最小堆
          {
           if(max.size()>0&&num<max[0])
            {  
              max.push_back(num);
              push_heap(max.begin(),max.end(),less<int>());
              
              num=max[0];
               
              pop_heap(max.begin(),max.end(),less<int>());
              max.pop_back(); 
            }  
              min.push_back(num);
              push_heap(min.begin(),min.end(),greater<int>());
          }
        else  //奇数位置,放入到最大堆中
          {
            if(min.size()>0&&num>min[0])  
            {
              min.push_back(num);
              push_heap(min.begin(),min.end(),greater<int>());
              
              num=min[0];
                
              pop_heap(min.begin(),min.end(),greater<int>());
              min.pop_back(); 
            }  
              max.push_back(num);
              push_heap(max.begin(),max.end(),less<int>());              
          }
    }

    double GetMedian()
    { 
        int size=min.size()+max.size();
        double medium=0;
        if(size==0)
            return 0;
        if((size&1)==1)
            medium=min[0];
        else
            medium=(double)(max[0]+min[0])/2;  //注意这里需要强制类型转换为double,不然输出结果精度不够,略了小数部分
        return medium;
            
    }
private:
    vector<int> min;
    vector<int> max;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

rs勿忘初心

您的鼓励将是我的最大创动原动力

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

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

打赏作者

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

抵扣说明:

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

余额充值