解题思路:
用大顶堆和小顶堆解决这个问题。
大顶堆就是首元素是最大值;小顶堆则是最小值。
现在设计一个
大顶堆get_max,用于保存比中位数小的数,首元素是最大值;
小顶堆get_min,用于保存大于或等于中位数的数,首元素是最小值。
举个例子
数据流1,2,3,4,5,6
get_max [1,2,3]
get_min [4,5,6]
分类讨论
我们规定get_min要么比get_max的容量大1个,要么等于。
所以,数据流个数是偶数个,我们只要取出get_min的最小值和get_max的最大值,然后相加除以2就是中位数。
假如数据流个数是奇数个,只要取出get_min的最小值就是中位数。
现在考虑插入数据
1 当get_min空的时候,数据插入get_min;
2 当数据num大于等get_min的首元素时,也就是说num大于中位数,那么插入get_min中;
考虑这么一种情况,get_min有4个元素,get_max有3个元素,现在来了一个元素,我们判断插入get_min中,那么get_min有5个元素了,不符合上述的规定,因此我们需要分一个值给get_max,那么就把get_min中的最小值给get_max就可以了。
即
if(get_min.size()>=get_max.size()+1){
get_max.push(get_min.top());
get_min.top();
}
3 除此之外,就是插入get_max,同样的,根据我们的规定,当get_max.size()>get_min.size(),要分一个元素给get_min。
这里补充一下大顶堆、小顶堆的用法
用的容器时
priority_queue<Type, Container, Functional>
Type是元素类型,Container是容器,Functional是哪种顶堆。
priority_queue<int,>
默认等价于
priority_queue<int,vector<int,>,less<int,>>;
less说明所有的元素都比堆顶元素大。
默认大顶堆
greater<int,>是小顶堆,greater说明所有元素都比堆顶元素大。
class Solution {
priority_queue<int,vector<int>,less<int>> get_max; //大顶堆,队头放最大值,比中位数小的值
priority_queue<int,vector<int>,greater<int>> get_min;//小顶堆,队头放最小值,比中位数大的值,小顶堆元素个数>=大顶堆
public:
void Insert(int num) {
if(get_min.empty()||num>=get_min.top()){
//先放进get_min
get_min.push(num);
//再看要不要移动元素到get_max
if(get_min.size()>get_max.size()+1){
int tmp=get_min.top();
get_min.pop();
get_max.push(tmp);
}
}else{
get_max.push(num);
if(get_max.size()>get_min.size()){
int tmp=get_max.top();
get_max.pop();
get_min.push(tmp);
}
}
}
double GetMedian() {
if(get_min.size()!=get_max.size())
return get_min.top();
else
return (get_min.top()+get_max.top())/2.0;
}
};