中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
- void addNum(int num) - 从数据流中添加一个整数到数据结构中。
- double findMedian() -
返回目前所有元素的中位数。
来源:力扣295题(LeetCode)
示例
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
通过两个优先队列对数字进行push。
需要让两个栈始终满足两个条件
- 两个优先队列的size()不能相差超过1
- 最大堆(也就是队首是最大的)堆顶小于最小堆堆顶
根据两个队列的size进行分别处理,再对数字进行分类push处理
#include<bits/stdc++.h>
using namespace std;
class MedianFinder {
public:
MedianFinder() {
}
priority_queue<int> big_queue;//最大堆,从大到小
priority_queue<int,vector<int>,greater<int> > small_queue; //最小堆,从小到大
void addNum(int num) {
if(big_queue.empty())
{
big_queue.push(num);
return;
}
if(big_queue.size()>small_queue.size()) //最大堆比最小堆多
{
if(num>=big_queue.top()){ //跟最大堆堆顶比较
small_queue.push(num);
}
else
{
small_queue.push(big_queue.top());
big_queue.pop();
big_queue.push(num);
}
}
else if(big_queue.size() == small_queue.size()) //个数相等时
{
if(num>=big_queue.top()){ //跟最大堆堆顶比较
small_queue.push(num);
}
else
{
big_queue.push(num);
}
}else //最大堆比最小堆少一个
{
if(num>=small_queue.top()){
big_queue.push(small_queue.top());
small_queue.pop();
small_queue.push(num);
}
else
{
big_queue.push(num);
}
}
}
double findMedian() {
if(big_queue.size() == small_queue.size())
{
return (big_queue.top()+small_queue.top()) / (2*1.0);
}
else if(big_queue.size() > small_queue.size())
{
return big_queue.top();
}
return small_queue.top();
}
};
int main(){
MedianFinder M;
int test[] = {1,2,3,4,5};
for(int i=0;i<4;i++)
{
M.addNum(test[i]);
printf("%lf\n",M.findMedian());
}
}