• Find Median from Data Stream


    Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

    Examples: 

    [2,3,4] , the median is 3

    [2,3], the median is (2 + 3) / 2 = 2.5

    Design a data structure that supports the following two operations:

    • void addNum(int num) - Add a integer number from the data stream to the data structure.
    • double findMedian() - Return the median of all elements so far.

    For example:

    add(1)
    add(2)
    findMedian() -> 1.5
    add(3) 
    findMedian() -> 2

    思路:要获得中位数,要设置两个堆,一个堆存储较小的那一半数,这里构建一个大顶堆small,从而就能获得这一半数中的最大值。

    另一个堆为小顶堆large,存储较大的那一半数,堆顶为这一半数中的最小值。

    具体实现时,我们将所有的数一个个地先插入到small中,插入后,所有的数重新排序后,堆顶为所有数中的最大值,将其从堆中弹出并插入到large中。这里要判断下small中数量是否比large要少,少的话则要从large中再取回一个数到small中。如果不添加这一步的话,则small中的数会一直添加到large中,最后small为空。这样做能让两堆数数量达到平衡。

    在实际实现中,我们用优先队列来实现。C++里的优先队列是大顶堆,因此large在实现时要将所有的数都取负,这样原本的最小值取负后就是现在的最大值了。这也给我们一个提示,如果不想写堆的代码,可以直接用优先队列。

     1 class MedianFinder {
     2 public:
     3     priority_queue<long long> small;
     4     priority_queue<long long> large;
     5     // Adds a number into the data structure.
     6     void addNum(int num) {
     7         small.push(num);
     8         large.push(-small.top());
     9         small.pop();
    10         if (small.size() < large.size())
    11         {
    12             small.push(-large.top());
    13             large.pop();
    14         }
    15     }
    16 
    17     // Returns the median of current data stream
    18     double findMedian() {
    19         return small.size() > large.size() ?
    20             small.top() : (small.top() - large.top()) / 2.0;
    21     }
    22 };
    23 
    24 // Your MedianFinder object will be instantiated and called as such:
    25 // MedianFinder mf;
    26 // mf.addNum(1);
    27 // mf.findMedian();
  • 相关阅读:
    吴军博士:物联网和人工智能将再造一个英特尔和微软 | 万物互联
    速来膜拜!20位活跃在Github上的国内技术大牛
    创建带Mipmap的osg::Image
    C#文件系统管理【转】
    C#文本文件(.txt)读写 [转]
    C#连接SQL Server数据库进行简单操作[转]
    shell脚本把一些请求量非常高的ip给拒绝掉
    linux获取精准进程PID之pgrep命令
    Kubernetes的Cron Job
    StatefulSet和Deployment的区别
  • 原文地址:https://www.cnblogs.com/fenshen371/p/4949395.html
Copyright © 2020-2023  润新知