[LeetCode] 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
Credits:
Special thanks to @Louis1992 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<long> 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<long> small, large;
};
参考资料:
https://leetcode.com/discuss/64850/short-simple-java-c-python-o-log-n-o-1
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Find Median from Data Stream 找出数据流的中位数的更多相关文章
- [LeetCode] 295. 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 ...
- LeetCode——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 ...
- 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)
注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...
- [LeetCode] Find Median from Data Stream
Find Median from Data Stream Median is the middle value in an ordered integer list. If the size of t ...
- [LeetCode] 295. Find Median from Data Stream ☆☆☆☆☆(数据流中获取中位数)
295. Find Median from Data Stream&数据流中的中位数 295. Find Median from Data Stream https://leetcode.co ...
- LeetCode OJ: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 ...
- 【LeetCode】295. Find Median from Data Stream 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 大根堆+小根堆 日期 题目地址:https://le ...
- leetcode@ [295]Find Median from Data Stream
https://leetcode.com/problems/find-median-from-data-stream/ Median is the middle value in an ordered ...
- LeetCode——295. Find Median from Data Stream
一.题目链接: https://leetcode.com/problems/find-median-from-data-stream 二.题目大意: 给定一段数据流,要求求出数据流中的中位数,其中数据 ...
随机推荐
- GDB调试命令
1.查看源码: list [函数名][行数] 2.暂停程序 (1)设置断点: a.break + [源代码行号][源代码函数名][内存地址] b.break ... if condition .. ...
- DotLiquid模板引擎简介
DotLiquid是一个在.Net Framework上运行的模板引擎,采用Ruby的Liquid语法,这个语法广泛的用在Ruby on rails和Django等网页框架中. DotLiquid相比 ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)
Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...
- Oracle 中的sql函数以及分页
SELECT LPAD(,'*.') "LPAD example" FROM DUAL; 1.分页查询 (1)方法一:使用 between and 来实现分页 select * ...
- JSP 9大内置对象详解
一.内置对象特点: 1.由JSP规范提供,不用编写者实例化. 2. 通过Web容器实现和管理 3.所有JSP页面均可使用 4.只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%> ...
- 前端开发:css技巧,如何设置select、radio 、 checkbox 、file这些不可直接设置的样式 。
前言: 都说程序员有三宝:人傻,钱多,死得早.博主身边的程序“猿”一大半应了这三宝,这从侧面说明了一个问题,只有理性是过不好日子的.朋友们应该把工作与生活分开,让生活变得感性,让工作变得理性,两者相提 ...
- C#开发微信门户及应用(16)-微信企业号的配置和使用
在本系列随笔的前面,主要就是介绍微信公众号的门户应用开发,最近把整个微信框架进行了扩展补充,增加了最新的企业号的API封装和开发,后续主要介绍如何利用C#进行微信企业号的开发工作,本篇作为微信企业号的 ...
- 充电时间 Go中的数组、切片、map简单示例
数组是固定长度的,依稀让我想起了VB:切片是动态的:map一般是键值对 package main import ( "fmt" ) func main() { var userna ...
- PHP 观察者模式
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. [观察者模式中主要角色] 1.抽象主题(Subject)角色: 抽象主题提供了增加 ...
- 时间戳TimeStamp处理
我获得这个时间戳是得想除以1000再处理的,看看你们的需要先除多少再处理 //时间戳处理 NSInteger time = timeStamp / 1000; NSNumber *timer = [ ...