数据流的中位数


动态维护一个最大堆和一个最小堆,最大堆存储一半数据,最小堆存储一半数据,维持最大堆的堆顶比最小堆的堆顶小

偶数个数时,中位数就是两个堆顶的一半。奇数个数时,就是某一个堆顶。

添加元素时堆顶的调整:

1.最大堆与最小堆元素个数相同时:来一个数,这个数比最大堆堆顶小的话,添加进最大堆。这个数比最小堆堆顶大的话,push进最小堆

2.最大堆比最小堆多一个元素时:这个数比最大堆堆顶小的话,将最大堆堆顶push进最小堆,并在最大堆中弹出它,然后把新来的这个数push到最大堆。这个数比最大堆堆顶大的话,直接push到最小堆

3.最大堆比最小堆少一个元素时:刚好相反。如果来的这个数比最小堆堆顶大的话,将最小堆堆顶push到最大堆,然后在最小堆pop,将新来的数再添加到最小堆。如果新的这个数比最小堆堆顶小的话,Push到最大堆


class MedianFinder {
public:
    /** initialize your data structure here. */
    priority_queue<int> big_heap;
    priority_queue<int,vector<int>,greater<int> > small_heap;
    
    MedianFinder() {       
    }
    
    void addNum(int num) {
        if(big_heap.empty())
        {
            big_heap.push(num);
            return;
        }
        
        if(big_heap.size() == small_heap.size())//
        {
            if(num<big_heap.top())
                big_heap.push(num);
            else
                small_heap.push(num);
        }
        else if(big_heap.size() > small_heap.size())//
        {
            if(num > big_heap.top())
            {
                small_heap.push(num);
            }else
            {
                small_heap.push(big_heap.top());
                big_heap.pop();
                big_heap.push(num);
            }
                
        }
        else if(big_heap.size() < small_heap.size())//
        {
            if(num < small_heap.top())
                big_heap.push(num);
            else
            {
                big_heap.push(small_heap.top());
                small_heap.pop();
                small_heap.push(num);
            }
        }
        
    }
    
    double findMedian() {
        if(big_heap.size() == small_heap.size())
            return 1.0*(big_heap.top() + small_heap.top())/2;//注意乘以1.0,这个错误我找了很久,麻蛋
        else if(big_heap.size() > small_heap.size())
            return big_heap.top();
        
            return small_heap.top();
    }
    

};

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值