[LeetCode] 295. Find Median from Data Stream ☆☆☆☆☆(数据流中获取中位数)
295. Find Median from Data Stream&数据流中的中位数
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 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
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
解析

如上图所示,如果数据在容器中已经排序,那么中位数可以由P1和P2指向的数得到。如果容器中数据的个数是奇数,那么P1和P2指向同一个数据。
注意到,整个容器被分隔成了两部分。位于容器左边部分的数据比右边的数据小。另外 P1指向的是左边的最大数据, P2指向的是右边部分最小的数。
如果能够保证数据容器左边的数据都小于右边的数据,这样即使左右两边内部的数据没有排序,也可以根据左边最大的数和右边最小的数得到中位数。用最大推可以快速的从一个数据容器中找出最大数,最小堆可以快速的从一个数据容器中找出最小的数。
用一个最大堆实现左边的数据容器,用最小堆实现右边的数据容器。
首先,要保证数据平均分配到两个堆中。为了实现平均分配,可以在数据的总数目是偶数时把新数据插入到最小堆,否则插入到最大堆中。
还要保证最大堆中的数据都要小于最小堆中的数据。如果当前数据的总数目是偶数,也就是要插入最小堆,但是它比最大堆中的一些数还要小。此时,先将这个数插入到最大堆中,然后把最大堆中最大的数取出,插入到最小堆中。如果当前数据的总数目是奇数,也就是要插入最大堆,但是它比最小堆中的一些数还要大。此时,先将这个数插入到最小堆中,然后把最小堆中最小的数取出,插入到最大堆中。
代码实现
Time Complexity: addNum - O(logn) , findMedian - O(1), Space Complexity - O(n)
class MedianFinder {
private PriorityQueue<Integer> maxOrientedHeap;
private PriorityQueue<Integer> minOrientedHeap;
public MedianFinder() {
this.minOrientedHeap = new PriorityQueue<Integer>();
this.maxOrientedHeap = new PriorityQueue<Integer>(10, new Comparator<Integer>() {
public int compare(Integer i1, Integer i2) {
return i2 - i1;
}
});
}
// Adds a number into the data structure.
public void addNum(int num) {
maxOrientedHeap.add(num); // O(logn)
minOrientedHeap.add(maxOrientedHeap.poll()); // O(logn)
if(maxOrientedHeap.size() < minOrientedHeap.size()) {
maxOrientedHeap.add(minOrientedHeap.poll()); //O(logn)
}
}
// Returns the median of current data stream
public double findMedian() { // O(1)
if(maxOrientedHeap.size() == minOrientedHeap.size())
return (maxOrientedHeap.peek() + minOrientedHeap.peek()) / 2.0;
else
return maxOrientedHeap.peek();
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
class MedianFinder {
Queue<Integer> minPQ = new PriorityQueue<>();
Queue<Integer> maxPQ = new PriorityQueue<>(10, (Integer i1, Integer i2) -> i2 - i1);
// Adds a number into the data structure.
public void addNum(int num) {
minPQ.offer(num);
maxPQ.offer(minPQ.poll());
if (minPQ.size() < maxPQ.size()) minPQ.offer(maxPQ.poll());
}
// Returns the median of current data stream
public double findMedian() {
if (minPQ.size() == maxPQ.size()) return (minPQ.peek() + maxPQ.peek()) / 2.0;
return minPQ.peek();
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
[LeetCode] 295. 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——295. Find Median from Data Stream
一.题目链接: https://leetcode.com/problems/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@ [295]Find Median from Data Stream
https://leetcode.com/problems/find-median-from-data-stream/ Median is the middle value in an ordered ...
- 295 Find Median from Data Stream 数据流的中位数
中位数是排序后列表的中间值.如果列表的大小是偶数,则没有中间值,此时中位数是中间两个数的平均值.示例:[2,3,4] , 中位数是 3[2,3], 中位数是 (2 + 3) / 2 = 2.5设计一个 ...
- 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)
注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...
- 【LeetCode】295. Find Median from Data Stream 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 大根堆+小根堆 日期 题目地址:https://le ...
- 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 ...
- [LC] 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 ...
随机推荐
- magrittr管道操作符使用解释(一)
使用管道操作符提高代码简洁性 在编写R语言代码时,有时候需要对一个变量进行一系列的运算,例如对于一个同时包含数值列和字符串列的数据框,如果要计算所有数值列之间的相关系数,一般要分两步,第一步首先筛选数 ...
- 【BZOJ】3143: [Hnoi2013]游走
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3143 显然如果一条边期望被走过的次数越多,我们就应该给它的编号越小. 所以问题变为如何求每 ...
- fit_transform和transform的区别
来自:泡泡糖nana 来自:俞驰 1. fit_transform是fit和transform的组合. 2. fit(x,y)传两个参数的是有监督学习的算法,fit(x)传一个参数的是无监督学习的算法 ...
- [转][JSBSim]JSBSim的使用--飞行控制组件及其配置
http://www.jianshu.com/p/b5e9f1f5df95 飞行控制率.稳定增强系统.自动驾驶仪和其他飞控系统(航电.电气等)都能够在 JSBSim 中以独立的控制组件进行建模.JSB ...
- 关于UTC时间和本地时间
收藏了个类Publics 可以实现本地时间和UTC时间的转换 UCT时间=本地时间-8 本地时间比UTC时间快8小时 element-ui的日期选择器上 选择的时间显示的是本地时间 但实 ...
- maven项目, 单元测试失败提示 Class not found datastorage........
---恢复内容开始--- 单元测试失败: 提示 Class not found datastorage........ 原因: maven 环境变量问题, eclipse 没有自动更新下载 ...
- 《剑指offer》第五十六题(数组中只出现一次的两个数字)
// 面试题56(一):数组中只出现一次的两个数字 // 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序 // 找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度 ...
- Node.js 常用命令
1. 查看node版本 node --version 2. 查看npm 版本,检查npm 是否正确安装. npm -v 3. 安装cnpm (国内淘宝镜像源),主要用于某些包或命令程序下载不下来的情况 ...
- MySQL学习(七)
学习子查询 1 查出本网站最新的good_id最大的一条商品(要求取出商品名) mysql> select goos_id,goods_name from goods -> order b ...
- Qt Model/View学习(二)
Model和View的搭配使用 DEMO pro文件 #------------------------------------------------- # # Project created by ...