题目:Numbers are randomly generated and stored into an (expanding) array. How would you keep track of the median?
思路分析:使用两个堆,一个最大堆(存储小于中位数的一半的元素),一个最小堆(存储大于中位数的一半的元素),只要维护好这两个堆,根据堆顶元素就能得到中位数。我们的程序保证左右两个堆的元素个数差不能超过1,设最大堆堆顶元素为x1,最小堆堆顶元素为x2,则若插入元素x>x2,则将该元素插入最小堆中,若最小堆元素个数-最大堆元素个数>1,将最小堆堆顶元素弹出到最大堆中去;若x1<=x<=x2,插入任意一个堆中;若x<x1,同x>x2的情况。
#include<iostream>
#include<queue>
using namespace std;
//最后的> >中间要有一个空格,避免被编译器理解为移位操作
//大顶堆
priority_queue<int,vector<int>,less<int> > maxheap;
//小顶堆
priority_queue<int,vector<int>, greater<int> > minheap;
void insert(int x){
//insert into any heap
if(maxheap.size()==0&&minheap.size()==0)
maxheap.push(x);
//rebalance it
else if(maxheap.size()==0&&minheap.size()==1){
if(x>minheap.top()){
maxheap.push(minheap.top());
minheap.pop();minheap.push(x);
}else{
maxheap.push(x);
}
}
//rebalance it
else if(maxheap.size()==1&&minheap.size()==0){
if(x<maxheap.top()){
minheap.push(maxheap.top());
maxheap.pop();maxheap.push(x);
}else{
minheap.push(x);
}
}
//insert
else{
if(x>minheap.top()){
minheap.push(x);
if(minheap.size()-maxheap.size()>1){
int tmp=minheap.top();minheap.pop();
maxheap.push(tmp);
}
}else if(x<maxheap.top()){
maxheap.push(x);
if(maxheap.size()-minheap.size()>1){
int tmp=maxheap.top();maxheap.pop();
maxheap.push(tmp);
}
}else{
//插入任意一个
if(maxheap.size()==minheap.size()){
maxheap.push(x);
}else if(maxheap.size()-minheap.size()==1){
minheap.push(x);
}else{
maxheap.push(x);
}
}
}
}
int getMid(){
if(minheap.size()-maxheap.size()==1)
return minheap.top();
else if(maxheap.size()-minheap.size()==1)
return maxheap.top();
else
return min(maxheap.top(),minheap.top());//这一句很重要,可能出现最大堆是:5 5 最小堆是:6 6 这种情况,我们必须取两者中的最小值。
}