数据流中的中位数

  1. 题目描述
    1. 思路

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

思路

  • 两个优先队列,分别存一半,一个存大值,一个存小值
class Solution {
private:
        vector<int> min; // 小顶锥,存放一半的大元素
        vector<int> max; // 大顶锥,存放一半的小元素
public:
         // 存数据
        void Insert(int num)
        {
           if(((min.size()+max.size())&1)==0)   //偶数时 ,放入最小堆
           {
              // 由于num小于大顶锥的最大值,需先放入大顶锥
              if(max.size()>0 && num<max[0])
              {
                // push_heap (_First, _Last),要先在容器中加入数据,再调用push_heap ()
                 max.push_back(num);            //先将元素压入容器
                 push_heap(max.begin(),max.end(),less<int>()); //调整最大堆

                 num=max[0];                    //取出最大堆的最大值

                 //pop_heap(_First, _Last),要先调用pop_heap(),再在容器中删除数据
                 pop_heap(max.begin(),max.end(),less<int>());  //删除最大堆的最大值
                 max.pop_back();                //在容器中删除
              }
              min.push_back(num);//压入最小堆
              push_heap(min.begin(),min.end(),greater<int>());//调整最小堆
           }
           else//奇数时候,放入最大堆
           {
              // 由于num大于小顶锥的最小值,需先放入小顶锥
              if(min.size()>0 && num>min[0])
              {
                // push_heap (_First, _Last),要先在容器中加入数据,再调用push_heap ()
                 min.push_back(num);            // 先压入最小堆
                 push_heap(min.begin(),min.end(),greater<int>()); // 调整最小堆

                 num=min[0];                    // 得到最小堆的最小值(堆顶)

                 //pop_heap(_First, _Last),要先调用pop_heap(),再在容器中删除数据
                 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();
            if(size<=0)          // 没有元素,抛出异常
                return 0;        // throw exception("No numbers are available");
            if((size&1)==0)      // 偶数时,去平均
                return ((double)(max[0]+min[0])/2);
            else                 //奇数,去最小堆,因为最小堆数据保持和最大堆一样多,或者比最大堆多1个
                return min[0];
        }
};

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:数据流中的中位数

Count:612

Author:攀登

Created At:2019-12-26, 23:12:31

Updated At:2024-06-15, 15:53:35

Url:http://jiafeimao-gjf.github.io/2019/12/26/sword-%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%AD%E7%9A%84%E4%B8%AD%E4%BD%8D%E6%95%B0/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation