剑指offer 面试题. 数据流中的中位数
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
解答:
这题没做过,用一个最大堆和一个最小堆来夹逼中位数,记录一下这个方法。
限制条件有两个:
1.最大堆的数都比最小堆小,这一点可以通过二者的top来限制(即限制最大堆的top小于最小堆的top)。
2.最小堆的size要么等于最大堆的size,要么比最大堆的size大1。这是什么意思呢,举个栗子:
最大堆:1,2,3,4
最小堆:6,7,8,9(当然这里不符合堆的性质,只是举例其中含有的数字)
那么此时二者size相同,中位数就是最小堆的top。
如果最小堆多一个10,即此时最小堆为:6,7,8,9,10
那么中位数就恰好是最大堆的top和最小堆的top的平均数。
另外一点就是priority_queue默认是最大堆,greater<int>是最小堆,less<Int>是最大堆,下次记住吧。。。。
代码:
1 class Solution { 2 public: 3 priority_queue<int,vector<int>,less<int>> heap_le; 4 priority_queue<int,vector<int>,greater<int>> heap_ri; 5 void Insert(int num) 6 { 7 if(heap_le.empty() or heap_le.top()>=num){ 8 heap_le.push(num); 9 } 10 else{ 11 heap_ri.push(num); 12 } 13 while(not heap_le.empty() and not heap_ri.empty() and heap_le.top()>heap_ri.top()){//保持性质1 14 heap_ri.push(heap_le.top()); 15 heap_le.pop(); 16 } 17 while(heap_le.size()>heap_ri.size()){//保持性质2 18 heap_ri.push(heap_le.top()); 19 heap_le.pop(); 20 } 21 while(heap_le.size()<heap_ri.size()-1){//保持性质2 22 heap_le.push(heap_ri.top()); 23 heap_ri.pop(); 24 } 25 } 26 27 double GetMedian() 28 { 29 return (heap_le.size()+heap_ri.size())%2?heap_ri.top()*1.0:(heap_le.top()+heap_ri.top())/2.0; 30 } 31 };
2020-02-14 15:14:57
进击的小🐴农