数据结构学习 jz41 数据流中的中位数

关键词:排序 大顶堆 小顶堆

题目:数据流中的中位数

这道题我没有想到用两个堆来做。

数据结构学习 jz41 数据流中的中位数_第1张图片

思路:

关键:维护两个堆,一个大顶堆一个小顶堆。

大顶堆:装较小的那一半的数,它的顶就是较小那一半数的最大值。

小顶堆:装较大的那一半的数,它的顶就是较大那一半数的最小值。

 来自k神的图:

数据结构学习 jz41 数据流中的中位数_第2张图片

插入和找中位数操作:

比较关键的是:给A加元素,先插给B,B再把B的top给A。

                        给B加元素,先插给A,A再把A的top给B。

数据结构学习 jz41 数据流中的中位数_第3张图片

复杂度计算:

时间复杂度O(logn)

空间复杂度O(N)

数据结构学习 jz41 数据流中的中位数_第4张图片

代码:

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,greater> A;//小顶堆,保存较大的一半
    priority_queue,less> B;//大顶堆,保存较小的一半
};

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

 

你可能感兴趣的:(数据结构学习,数据结构,学习,算法)