题目链接:点击这里
思路:对顶堆
动态维护一个最大堆与一个最小堆,最大堆存储一半数据,最小堆存储一半数据,时时刻刻只要维护两个状态:
- 最大堆和最小堆的元素个数差值小于等于1
- 最大堆的堆顶比最小堆的堆顶小。
添加元素的情况分析:
获取中位数的情况分析:
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
//如果大根堆为空,直接添加进大根堆就好
if(big_queue.empty()) {
big_queue.push(num);
return ;
}
//如果大根堆和小根堆元素个数相同,情况1
if(big_queue.size()==small_queue.size()) {
if(num>big_queue.top()) { //若num大于大根堆堆顶,则进小根堆
small_queue.push(num);
}
else { //num小于大根堆堆顶,则进大根堆
big_queue.push(num);
}
}
//如果大根堆元素个数比小根堆多 ,情况2
else 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);
}
}
//如果小根堆元素个数比大根堆多,情况3
else if(small_queue.size()>big_queue.size()) {
if(num<small_queue.top()) {
big_queue.push(num);
}
else {
big_queue.push(small_queue.top());
small_queue.pop();
small_queue.push(num);
}
}
}
double findMedian() {
if(big_queue.size()==small_queue.size()) {
return (big_queue.top()+small_queue.top())/2;
}
else if(big_queue.size()>small_queue.size()) {
return big_queue.top();
}
return small_queue.top();
}
private:
priority_queue<double> big_queue; //默认构造大根堆
priority_queue<double, vector<double>, greater<double> > small_queue; //构造小根堆
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/