295 Find Median from Data Stream 数据流的中位数
中位数是排序后列表的中间值。如果列表的大小是偶数,则没有中间值,此时中位数是中间两个数的平均值。
示例:
[2,3,4] , 中位数是 3
[2,3], 中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中增加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
例如:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
详见:https://leetcode.com/problems/find-median-from-data-stream/description/
Java实现:
参考:https://www.cnblogs.com/Liok3187/p/4928667.html
O(nlogn)的做法是开两个堆(java用优先队列代替)。
最小堆放小于中位数的一半,最大堆放较大的另一半。
addNum操作,把当前的num放到size小的堆中,通过2次poll-add操作,保证了最小堆中的所有数都小于最大堆中的数。
findMedian操作,如果size不同,就是其中一个堆顶,否则就是连个堆顶的数相加除以2。
class MedianFinder {
private Queue<Integer> maxHeap;
private Queue<Integer> minHeap; /**
* initialize your data structure here.
*/
public MedianFinder() {
this.maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
this.minHeap = new PriorityQueue<Integer>();
} public void addNum(int num) {
if (maxHeap.size() < minHeap.size()) {
maxHeap.add(num);
minHeap.add(maxHeap.poll());
maxHeap.add(minHeap.poll());
} else {
minHeap.add(num);
maxHeap.add(minHeap.poll());
minHeap.add(maxHeap.poll());
}
} public double findMedian() {
if (maxHeap.size() < minHeap.size()) {
return minHeap.peek();
} else if (maxHeap.size() > minHeap.size()) {
return maxHeap.peek();
} else {
return (minHeap.peek() + maxHeap.peek()) / 2.0;
}
}
} /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
C++实现:
方法一:
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
maxH={};
minH={};
} void addNum(int num) {
if(((minH.size() + maxH.size()) & 0x1) == 0)
{
if(!maxH.empty() && num<maxH[0])
{
maxH.push_back(num);
push_heap(maxH.begin(),maxH.end(),less<int>()); num = maxH[0];
pop_heap(maxH.begin(),maxH.end(),less<int>());
maxH.pop_back();
}
minH.push_back(num);
push_heap(minH.begin(),minH.end(),greater<int>()); }
else
{
if(!minH.empty() && num>minH[0])
{
minH.push_back(num);
push_heap(minH.begin(),minH.end(),greater<int>()); num = minH[0];
pop_heap(minH.begin(),minH.end(),greater<int>());
minH.pop_back();
}
maxH.push_back(num);
push_heap(maxH.begin(),maxH.end(),less<int>());
} } double findMedian() {
int size = minH.size() + maxH.size(); double median = 0;
if((size&0x1) == 1)
{
median = minH[0];
}
else
{
median = (minH[0]+maxH[0])*0.5;
}
return median;
}
private:
vector<int> maxH;
vector<int> minH;
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
方法二:
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() { } void addNum(int num) {
small.push(num);
large.push(-small.top());
small.pop();
if(small.size()<large.size())
{
small.push(-large.top());
large.pop();
}
} double findMedian() {
return small.size()>large.size()?small.top():0.5*(small.top()-large.top());
}
private:
priority_queue<int> small,large;
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
方法三:
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() { } 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());
}
} double findMedian() {
return small.size()>large.size()?*small.begin():0.5*(*small.begin()-*large.begin());
}
private:
multiset<int> small,large;
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
方法四:
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() { } void addNum(int num) {
if(maxH.empty()||num<=maxH.top())
{
maxH.push(num);
}
else
{
minH.push(num);
}
if(minH.size()+2==maxH.size())
{
minH.push(maxH.top());
maxH.pop();
}
if(maxH.size()+1==minH.size())
{
maxH.push(minH.top());
minH.pop();
}
} double findMedian() {
return minH.size()==maxH.size()?0.5*(minH.top()+maxH.top()):maxH.top();
}
private:
priority_queue<int,vector<int>,less<int>> maxH;
priority_queue<int,vector<int>,greater<int>> minH;
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
参考:https://blog.csdn.net/sjt19910311/article/details/50883735
https://www.cnblogs.com/grandyang/p/4896673.html
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 ☆☆☆☆☆(数据流中获取中位数)
295. Find Median from Data Stream&数据流中的中位数 295. Find Median from Data Stream https://leetcode.co ...
- 剑指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 找出数据流的中位数
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 ...
- 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 ...
- leetcode@ [295]Find Median from Data Stream
https://leetcode.com/problems/find-median-from-data-stream/ Median is the middle value in an ordered ...
- [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 ...
- LeetCode——295. Find Median from Data Stream
一.题目链接: https://leetcode.com/problems/find-median-from-data-stream 二.题目大意: 给定一段数据流,要求求出数据流中的中位数,其中数据 ...
随机推荐
- 百度UEditor富文本上传图片
项目中使用UEditor发现设置图片自定义保存路径会出现<请求后台配置项http错误,上传功能将不能正常使用!错误> /* 上传图片配置项 */ "imageActionName ...
- ios计算字符串宽高,指定字符串变色,获取URL参数集合
#import <Foundation/Foundation.h> @interface NSString (Extension) - (CGFloat)heightWithLimitWi ...
- java.lang.NoClassDefFoundError: Could not initialize class异常处理
借鉴:http://blog.csdn.net/sleepdancer/article/details/9207425 static { InputStream in = XXX.class.getR ...
- top命令查看线程信息和jstack使用介绍
top -Hp pid可以查看某个进程的线程信息 -H 显示线程信息,-p指定pid jstack 线程ID 可以查看某个线程的堆栈情况,特别对于hung挂死的线程,可以使用选项-F强制打印dump信 ...
- 旧瓶新酒之ngx_lua & fail2ban实现主动诱捕
服务器承担着业务运行及数据存储的重要作用,因此极易成为攻击者的首要目标.如何对业务服务器的安全进行防护,及时找出针对系统的攻击,并阻断攻击,最大程度地降低主机系统安全的风险程度,是企业安全从业人员面临 ...
- 从头认识Spring-2.3 注解装配-@autowired(4)-required(2)
这一章节我们来继续具体讨论一下@autowired里面的參数required.在多构造器注入的情况. 1.domain(重点) 蛋糕类: package com.raylee.my_new_sprin ...
- 使用11g DNFS建立基于DNFS的tablespace
使用11g DNFS建立基于DNFS的tablespace 參考自: Step by Step - Configure Direct NFS Client (DNFS) on Linux (11g) ...
- Redis源代码分析(六)--- ziplist压缩列表
ziplist和之前我解析过的adlist列表名字看上去的非常像.可是作用却全然不同.之前的adlist主要针对的是普通的数据链表操作. 而今天的ziplist指的是压缩链表.为什么叫压缩链表呢.由于 ...
- 动态代理3--Spring AOP分析
Spring AOP的基本实现方式 Spring AOP,一种模块化机制,能够动态的对切点添加行为,而不破坏原有的代码结构. 这是一个非常好地动态代理的应用方式.Spring AOP实现依赖于JDK ...
- 蓝桥 ADV-232 算法提高 矩阵乘法 【区间DP】
算法提高 矩阵乘法 时间限制:3.0s 内存限制:256.0MB 问题描述 有n个矩阵,大小分别为a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],现要 ...