题解 | 数据流中的中位数

数据流中的中位数

https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1

#include <queue>
class Solution {
public:
    void Insert(int num) {
        ++cnt;
        if(cnt&1){
            if(!big.empty()&&big.top()>num){
                    int temp = big.top();
                    big.pop();
                    big.push(num);
                    num = temp;
            }
            small.push(num);
        }
        else{
            if(!small.empty()&&small.top()<num){
                int temp = small.top();
                small.pop();
                small.push(num);
                num = temp;
            }
            big.push(num);
        }
    }

    double GetMedian() { 
        if(cnt&1){
            return (double) small.top();
        }
        else{
            return (double)((small.top()+big.top())/2.0);
        }
    }
    priority_queue<int, vector<int>, greater<int> > small;
    priority_queue<int> big;
    int cnt = 0;
};

谈到中位数,第一想法是排好序的,但是插入排序时间复杂度太高,不考虑。

那么有什么其他考量呢?能不能让查找的时候再处理,其他时候就插入就好(时间复杂度上)。

那么我们应该用什么数据结构来存储呢?很容易想到AVL,如果它平衡的话就会在中间。

但是AVL写起来显然是有点复杂的,而且它平衡也很花时间。

于是干脆就用两个部分来做,小的和大的,中间的就在中间。

这就需要知道小的最大和大的最小,并且能够很快调整自己的结构。

刚好stl里有优先队列,那么就写一个小根堆和一个大根堆,再讨论奇数和偶数情况。

我是优先放在小根堆里,如果你要先放大根堆差不多。

插入和删除的时间复杂度都是O(logn),但是查找可以到O(1),插入n次也在常数O(knlogn),也就是O(nlogn),符合题目要求,可以接受。

全部评论

相关推荐

被普调的六边形战士很高大:项目经历貌似和专业或者求职方向没大关系?
点赞 评论 收藏
分享
xxxxOxo:该催就催,想要你的不会因为催就挂,催了就挂的是因为本来就要挂你
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务