解题思路
思路:大小顶堆
不要对这两个priority_queue有什么误解
一开始想得非常简单,sort嘛,然后取中间就好了,但是很明显是超时的,因为只要数据一多你就sort超时了(每次几乎要比较所有的数据)
其实大小顶堆就是让你的操作空间一直在数据的中间.
先搞一个大顶堆,这样数据是从小到大(大的是根)的.
然后弄一个小顶堆,让数据还是从小到大(小的是根)
这样的话两个根就把中间你需要操作的部分给夹出来了.
大体就是这样,如果你往里插入数字的话只需要与两个根比较~~
为了使"夹出来"的部分一直在中间,你需要对堆进行调整,保证大顶堆(也就是数比较小的那个)的数字数量一直是等于小顶堆(数字比较大的那个)或者比小顶堆大1.这样能保证两个堆夹着的是中间.
有一个细节就是第一个数,直接放大顶堆好了
代码
#include <iostream>
#include<queue>
#include<vector>
using namespace std;
class MedianFinder {
public:
/** initialize your data structure here. */
priority_queue<int> small;
priority_queue<int,vector<int> ,greater<int> > big;
MedianFinder() {}
int number=0;
void addNum(int num) {
number++;
if(small.empty()){
small.push(num);
}
else{//比较两个堆顶
if(num<small.top()){
small.push(num);
}
else{
big.push(num);
}
//调整
int s_si=small.size();
int b_si=big.size();
if(b_si>s_si){
int temp=big.top();
small.push(temp);
big.pop();
}
else if(s_si>b_si+1){
int temp=small.top();
big.push(temp);
small.pop();
}
}
}
double findMedian() {
if(small.size()==big.size()){
return (small.top()+big.top())/2.0;
}
else{
return small.top();
}
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/