63剑指offer--数据流中的中位数
Posted qqky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了63剑指offer--数据流中的中位数相关的知识,希望对你有一定的参考价值。
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值
解题思路:分为两种情况,奇数取中间的数字,偶数取中间两个数的平均值。
使用两个堆来实现,左侧使用最大堆存储小的数字,右侧使用最小堆存储大的数字。
在插入时,
1)如果为偶数,则插入最小堆,且如果插入的数比最大堆中最大的数还小,则该数应插入最大堆,然后调整最大堆,找出此时最大堆中最大的插入最小堆,然后调整最小堆。
2)如果为奇数,则插入最大堆,如果此数比最小堆中最小的还大,则应插入最小堆,然后调整最小堆,将最小堆中最小的插入最大堆。
在取结果时,分为奇数和偶数,奇数取min[0](因为偶数时,插入到最小堆,插入完为奇数,此时最小堆比最大堆多一个),偶数取平均值
1 class Solution { 2 private: 3 vector<int>min;//最小堆存的是大数(右边) 4 vector<int>max;//最大堆存的是小数(左边) 5 public: 6 void Insert(int num) 7 { 8 if(((min.size()+max.size())&1)==0)//偶数个数,插入右侧(最小堆) 9 { 10 if(max.size()>0 && num < max[0])//比最大堆中的数小,应放入最大堆,因此将最大堆中最大值放入最小堆 11 { 12 max.push_back(num); 13 push_heap(max.begin(),max.end(),less<int>());//容器插入后插入堆 14 num = max[0]; 15 pop_heap(max.begin(),max.end(),less<int>());//调整后才能从容器中删除 16 max.pop_back(); 17 } 18 //插入最小堆 19 min.push_back(num); 20 push_heap(min.begin(),min.end(),greater<int>()); 21 } 22 else//插入左侧(最大堆) 23 { 24 if(min.size() >0 && min[0] < num)//应插入最小堆 25 { 26 min.push_back(num); 27 push_heap(min.begin(),min.end(),greater<int>()); 28 num = min[0]; 29 pop_heap(min.begin(),min.end(),greater<int>()); 30 min.pop_back(); 31 } 32 //插入最大堆 33 max.push_back(num); 34 push_heap(max.begin(),max.end(),less<int>()); 35 } 36 } 37 38 double GetMedian() 39 { 40 int size = max.size()+min.size(); 41 if(size <= 0) 42 return 0; 43 if((size & 1) == 0)//偶数 44 { 45 return (double)((max[0] + min[0])/2.0);//注意2.0 46 } 47 else 48 { 49 return min[0]; 50 } 51 } 52 };
以上是关于63剑指offer--数据流中的中位数的主要内容,如果未能解决你的问题,请参考以下文章