zoukankan      html  css  js  c++  java
  • LeetCode295. 数据流的中位数

    暴力做法是维护一个数组,每次插入一个元素就对数组进行排序,然后通过有序数组寻找中位数就很简单了。
    但是因为每次插入一个元素都要对数组进行排序,调整的时间代价太大了,超时。

    我们可以用两个优先级队列,一个小根堆,一个大根堆分别存储大于等于和小于当前中位数的所有数。
    且小根堆的大小总是和大根堆的大小相等,或者比大根堆的大小多一。如果插入一个元素时两个堆的大小不满足这个关系,就从一个堆里
    弹出堆顶元素到另一个堆里。

    这样,如果两个堆的大小相等时,说明元素个数是偶数,两个堆的堆顶元素就是中间的两个元素,我们返回这两个数的平均值即可。
    如果小根堆的大小比大根堆的大小多1,说明元素个数是奇数,且小根堆的堆顶元素就是中位数。

    这种做法,每次维护堆的时间是O(logn),所以总的时间复杂度是O(nlogn)。

    代码如下:

    class MedianFinder {
    public:
        priority_queue<int> smaller;                        
        priority_queue<int, vector<int>, greater<int>> larger;
    
        /** initialize your data structure here. */
        MedianFinder() {
    
        }
        
        void addNum(int num) {
            if(smaller.empty() || num <= smaller.top()) {            
                smaller.push(num);
            } else {
                larger.push(num);
            }
            if(smaller.size() > larger.size() + 1) {
                int topElement = smaller.top();
                smaller.pop();
                larger.push(topElement);
            } else if(larger.size() > smaller.size()) {
                int topElement = larger.top();
                larger.pop();
                smaller.push(topElement);
            }
        }
        
        double findMedian() {
            if(smaller.size() == larger.size()) {
                return (smaller.top() + larger.top()) / 2.0;
            }
            return smaller.top();
        }
    };
    
    /**
     * Your MedianFinder object will be instantiated and called as such:
     * MedianFinder* obj = new MedianFinder();
     * obj->addNum(num);
     * double param_2 = obj->findMedian();
     */
    
  • 相关阅读:
    101-PHP二维数组的元素输出三,封装成函数
    100-PHP二维数组的元素输出三
    099-PHP二维数组的元素输出二
    098-PHP二维数组的元素输出
    097-PHP循环使用next取数组元素二
    096-PHP循环使用next取数组元素
    095-PHP遍历关联数组,并修改数组元素值
    094-PHP遍历索引数组和关联数组
    093-PHP数组比较
    092-PHP定义索引数组
  • 原文地址:https://www.cnblogs.com/linrj/p/13572261.html
Copyright © 2011-2022 走看看