【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 ; //奇数时,返回中间元素,偶数时,返回中间两个数的平均数,注意浮点数的处理  
    }
};
 
 
 

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10225919.html
今日推荐