题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
解题思路
一般数据流我们用数组来表示,要得到中位数有很多种方法,这里介绍一种时间复杂度较小的方法,用C++种的优先级队列。
也就是剑指offer书上的方法,把数组逻辑上分成两个部分,左边为最大堆,右边为最小堆。我们始终要保证最大堆中最大的元素要小于最小堆中最小的元素即可,当然除此之外,还要判断数组中元素个数是偶数还是奇数,如果要判断我们必须要让两个堆中的元素个数之差不大于1,在这里,我们保证最大堆的元素个数可以等于最小堆元素个数+1,但是最小堆堆元素个数最多只能与最大堆相同。 那么如果两个堆的元素个数相同,那么就是偶数,那么中位数就是两个堆顶元素之和除以2,如果不相同的话,说明最大堆的元素个数多,取最大堆堆顶元素即可。
class Solution {
public:
priority_queue<int,vector<int>,less<int>> max;
priority_queue<int,vector<int>,greater<int>> min;
void insert(int num)
{
if(!max.size() || num <= max.top()){
max.push(num);
}else{
min.push(num);
}
//大堆个数比小堆多两个
if(max.size() == min.size() + 2){
min.push(max.top());
max.pop();
}
//小堆个数比大堆多1个
if(min.size() == max.size() + 1){
max.push(min.top());
min.pop();
}
}
double get(){
return (max.size() == min.size()) ? (max.top() + min.top())/2.0 : max.top();
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
for(auto x: nums1)
insert(x);
for(auto x :nums2)
insert(x);
return get();
}
};
这个堆插入也是log(m+n)的复杂度么(还有萌新不太懂优先队列和堆的区别)
是logn