Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
For example,
[2,3,4]
, the median is 3
[2,3]
, the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
- void addNum(int num) - Add a integer number from the data stream to the data structure.
- double findMedian() - Return the median of all elements so far.
Example:
addNum(1) addNum(2) findMedian() -> 1.5 addNum(3) findMedian() -> 2
题目大意:
按照输入命令快速求解当前已输入数据的中位数。
解题思路:
暴力排序的方法超时。
我们需要减少在新数据添加时的比较次数。
由于每次数据的数据只有一个,我们可以在每次数据之后将当前的大小顺序排列好。
利用优先队列priority_queue,将最终结果保存到两个优先队列的首位。
class MedianFinder {
public:
/** initialize your data structure here. */
priority_queue<int> lo; // 普通的优先级队列,按从大到小排序
priority_queue<int, vector<int>, greater<int>> hi; // 从小到大的优先级队列
// 每次加入的数据都会现在,从大到小这个队列中先比较一下,如果这个数非常大就会出现在首部,每一次将lo.top放到hi中
// 在返回时始终都要保持 两个队列中 lo与hi相等或者多一个,奇数时为lo的top,偶数时为lo.top和hi.top
MedianFinder() {
}
void addNum(int num) {
lo.push(num);
hi.push(lo.top());
lo.pop();
if(lo.size()<hi.size()){ // 保证最后结果取值固定
lo.push(hi.top());
hi.pop();
}
}
double findMedian() {
return lo.size() > hi.size() ? (double) lo.top() : (lo.top() + hi.top()) * 0.5;
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/