【LeetCode & 剑指offer刷题】查找与排序题3:41 数据流中的中位数(295. Find Median from Data Stream)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

41 数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
 
/*
1 2 3 4 [5] + [6] 7 8 9 10
大顶堆 + 小顶堆
方法一:用两个堆(stl中的priority_queue)
过程:用于一个大顶堆实现左边容器,小顶堆实现右边容器,根据左边最大数与右边最小数得到中位数
    (1) 平均分配
    (2) 还要保证大顶堆中所有数据小于小顶堆中元素,比较新数据与大顶堆和小顶堆堆顶元素就知道该放到哪里
插入O(logn) 得到中位数O(1),空间复杂度O(n)
*/
class Solution
{
private:
    priority_queue<int> maxheap; //stl中默认为大顶堆(联系默认的二叉搜索树,
//根结点较左子树大,中序遍历从小到大,不同的是大顶堆根结点较左右子树都大)
    priority_queue<int, vector<int>, greater<int>> minheap; //小顶堆
public:
    void Insert(int num)
    {
        if(maxheap.empty() || num<maxheap.top()) maxheap.push(num); //如果新数属于小的一半(左边)
        else minheap.push(num);
       
        if(maxheap.size() < minheap.size()) //保持两边长度一致(左边比右边多一或者左右两边长度一样)
        {
            maxheap.push(minheap.top());
            minheap.pop();
        }
        else if(maxheap.size() > minheap.size() + 1)
        {
            minheap.push(maxheap.top());
            maxheap.pop();
        }
               
    }
    double GetMedian()
    {
       return (maxheap.size()>minheap.size())? maxheap.top(): (maxheap.top() + minheap.top())*0.5; //奇数时,返回中间元素,偶数时,返回中间两个数的平均数,注意浮点数的处理  
    }
};
 
 
 

 

posted @ 2019-01-05 20:08  wikiwen  阅读(125)  评论(0编辑  收藏  举报