关键词:排序 大顶堆 小顶堆
题目:数据流中的中位数
这道题我没有想到用两个堆来做。
思路:
关键:维护两个堆,一个大顶堆一个小顶堆。
大顶堆:装较小的那一半的数,它的顶就是较小那一半数的最大值。
小顶堆:装较大的那一半的数,它的顶就是较大那一半数的最小值。
来自k神的图:
插入和找中位数操作:
比较关键的是:给A加元素,先插给B,B再把B的top给A。
给B加元素,先插给A,A再把A的top给B。
复杂度计算:
时间复杂度O(logn)
空间复杂度O(N)
代码:
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
//约定好,AB一样,先给A。A比B多,给B。
if(A.size()!=B.size())//给B
{
A.push(num);//先放给A,A找到更新之后的最小,即top
B.push(A.top());//把A的最小给B
A.pop();//A的top已经给了B,所以推出
}
else//给A
{
B.push(num);
A.push(B.top());
B.pop();
}
}
double findMedian() {
if(A.size()!=B.size())//总数是奇数
return A.top();
else//总数是偶数
return (A.top()+B.top())/2.0;
}
private:
priority_queue<int,vector<int>,greater<int>> A;//小顶堆,保存较大的一半
priority_queue<int,vector<int>,less<int>> B;//大顶堆,保存较小的一半
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/