JZ63_数据流中的中位数
知识点:最大最小堆
题目链接
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
解题思路
- 这里要求中位数,最笨的方法就是放入数组中排序
- 如果是奇数个,我们希望能快速拿到中间的;偶数个,希望拿到前面部分最大的,后面部分最小的;由此我们想到最大堆和最小堆
- 我们用最大堆(根是最大的)存前面的一大半数据,最小堆存后面的数据
- 如果大根堆没有数 或者 这个数比大根堆的根小的话 就放入大根堆 否则放小根堆
- 此外,我们需要平衡两个堆的个数,保证大根堆的个数 比 小根堆最多大1 ,方便奇数使拿到中间的数
代码
#include "cheader.h"
class Solution {
public:
priority_queue<int,vector<int>> left;//大根堆
priority_queue<int,vector<int>,greater<>> right;//小根堆
void Insert(int num) {
if(left.empty() || num <= left.top())
left.push(num);
else
right.push(num);
if(left.size() == right.size()+2){
right.push(left.top());
left.pop();
}else if(left.size()+1 <= right.size()){
left.push(right.top());
right.pop();
}
}
double GetMedian() {
if(left.size() == right.size())
return 1.0*(left.top()+right.top())/2;
else
return left.top();
}
};
今天也是爱zz的一天!