如何得到一个数据流中的中位数?
如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
样例
输入:1, 2, 3, 4
输出:1,1.5,2,2.5
解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。
算法一:
用STL,维护一个有序的vector数组,每次插入一个数时,先用lower_bound找到第一个大于等于x的位置,然后插入;
class Solution {
public:
vector<int> nums;
void insert(int num){
auto x = lower_bound(nums.begin(),nums.end(),num);
nums.insert(x,num);
}
double getMedian(){
int n = nums.size();
if(n&1) return nums[n/2];
return (nums[n/2] + nums[n/2-1]) / 2.0;
}
};
算法二:
用一个大根堆来维护左半边较小的数,小根堆来维护右半边较大的数,那么两个堆的对顶就是一组有序数中间相邻的两个数;
C++代码:
class Solution {
public:
priority_queue<int> max_q;
priority_queue<int,vector<int>,greater<int>> min_q;
void insert(int num){
max_q.push(num);
if(min_q.size() && min_q.top() < max_q.top()) {
int minv = min_q.top(); min_q.pop();
int maxv = max_q.top(); max_q.pop();
min_q.push(maxv); max_q.push(minv);
}
if(max_q.size() - min_q.size() > 1){
min_q.push(max_q.top());
max_q.pop();
}
}
double getMedian(){
if((max_q.size()+min_q.size())&1) return max_q.top();
return (max_q.top()+min_q.top()) / 2.0;
}
};