Little-Prince

导航

295. 数据流的中位数

295. 数据流的中位数

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:

 void addNum(int num) - 从数据流中添加一个整数到数据结构中。
 double findMedian() - 返回目前所有元素的中位数。

示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
 
 
思路:
两个优先级队列:
用于存储较小一半数字的最大堆 small
用于存储较大一半数字的最小堆 big
big 允许存储的元素最多比 small 多一个。因此,如果我们处理了 k 元素:

如果 k=2∗n+1(∀,n∈z) 则允许 big 持有 n+1元素,而 small 可以持有 n 元素。
如果 k=2∗n(∀,n∈z), 那么两个堆都是平衡的,并且每个堆都包含 n 个元素。
时间复杂度 o(log n) ,空间复杂度 o(n)
 
代码:
class MedianFinder {
    priority_queue<int, vector<int>, less<int>> small;
    priority_queue<int, vector<int>, greater<int>> big;
public:
    /** initialize your data structure here. */
    MedianFinder() {

    }
    
    void addNum(int num) {
    if(!small.empty()&&num<small.top())
    {
        big.push(small.top());
        small.pop();
        small.push(num);
    }
    else
      big.push(num);
    
      if(big.size()>small.size()+1)
        {
            small.push(big.top());
            big.pop();
        }
    }
    
    double findMedian() {
        if(big.size()==small.size())
            return (big.top()+small.top())/2.0;
        else 
            return big.top();
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

 

 

posted on 2020-08-06 21:32  Little-Prince  阅读(80)  评论(0)    收藏  举报