博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Find Median from Data Stream 找出数据流的中位数
阅读量:5031 次
发布时间:2019-06-12

本文共 2202 字,大约阅读时间需要 7 分钟。

 

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.5add(3) findMedian() -> 2

Credits:

Special thanks to for adding this problem and creating all test cases.

 

这道题给我们一个数据流,让我们找出中位数,由于数据流中的数据并不是有序的,所以我们首先应该想个方法让其有序。如果我们用vector来保存数据流的话,每进来一个新数据都要给数组排序,很不高效。所以之后想到用multiset这个数据结构,是有序保存数据的,但是它不能用下标直接访问元素,找中位数也不高效。这里用到的解法十分巧妙,我们使用大小堆来解决问题,其中大堆保存右半段较大的数字,小堆保存左半段较小的数组。这样整个数组就被中间分为两段了,由于堆的保存方式是由大到小,我们希望大堆里面的数据是从小到大,这样取第一个来计算中位数方便。我们用到一个小技巧,就是存到大堆里的数先取反再存,这样由大到小存下来的顺序就是实际上我们想要的从小到大的顺序。当大堆和小堆中的数字一样多时,我们取出大堆小堆的首元素求平均值,当小堆元素多时,取小堆首元素为中位数,参见代码如下:

 

解法一:

class MedianFinder {public:    // Adds a number into the data structure.    void addNum(int num) {        small.push(num);        large.push(-small.top());        small.pop();        if (small.size() < large.size()) {            small.push(-large.top());            large.pop();        }    }    // Returns the median of current data stream    double findMedian() {        return small.size() > large.size() ? small.top() : 0.5 *(small.top() - large.top());    }private:    priority_queue
small, large;};

 

上述方法是用priority_queue来实现堆功能的,下面我们还可用multiset来实现堆,参见代码如下:

 

解法二:

class MedianFinder {public:    // Adds a number into the data structure.    void addNum(int num) {        small.insert(num);        large.insert(-*small.begin());        small.erase(small.begin());        if (small.size() < large.size()) {            small.insert(-*large.begin());            large.erase(large.begin());        }    }    // Returns the median of current data stream    double findMedian() {        return small.size() > large.size() ? *small.begin() : 0.5 * (*small.begin() - *large.begin());    }private:    multiset
small, large;};

 

参考资料:

 

转载于:https://www.cnblogs.com/grandyang/p/4896673.html

你可能感兴趣的文章
关于Python开发小程序的随笔path4
查看>>
jQuery插件:跨浏览器复制jQuery-zclip
查看>>
POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
查看>>
一个简单的 Jwt Demo
查看>>
循序渐进开发WinForm项目(4)--Winform界面模块的集成使用
查看>>
DevExpress的XtraReport和微软RDLC报表的使用和对比
查看>>
代码生成工具更新--快速生成Winform框架的界面项目
查看>>
C++编程思想重点笔记(上)
查看>>
网络连接
查看>>
rest 参数和扩展运算符
查看>>
Struts中Action结果集路径解释
查看>>
SSM-WebMVC(三)
查看>>
java.lang.NoClassDefFoundError: org/apache/http/ssl/SSLContexts
查看>>
简单上传图片代码
查看>>
html 表单动态添加输入项,并以数组的形式发送
查看>>
consul-服务发现、服务隔离、服务配置
查看>>
u-boot中网口处理--硬件部分
查看>>
pickle序列化与反序列化 + eval说明
查看>>
ACM学习历程—UESTC 1222 Sudoku(矩阵)(2015CCPC H)
查看>>
CentOS6.5以runlevel 3开机时自动连接某无线设置示例
查看>>