中位数是排序后列表的中间值。如果列表的大小是偶数,则没有中间值,此时中位数是中间两个数的平均值。
示例:
[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 数据流的中位数的更多相关文章

  1. [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 ...

  2. [LeetCode] 295. Find Median from Data Stream ☆☆☆☆☆(数据流中获取中位数)

    295. Find Median from Data Stream&数据流中的中位数 295. Find Median from Data Stream https://leetcode.co ...

  3. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  4. [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 ...

  5. 【LeetCode】295. Find Median from Data Stream 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 大根堆+小根堆 日期 题目地址:https://le ...

  6. 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 ...

  7. leetcode@ [295]Find Median from Data Stream

    https://leetcode.com/problems/find-median-from-data-stream/ Median is the middle value in an ordered ...

  8. [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 ...

  9. LeetCode——295. Find Median from Data Stream

    一.题目链接: https://leetcode.com/problems/find-median-from-data-stream 二.题目大意: 给定一段数据流,要求求出数据流中的中位数,其中数据 ...

随机推荐

  1. C#高级编程第9版 第一章 .NET体系结构 读后笔记

    .NET的CLR把源代码编译为IL,然后又把IL编译为平台专用代码. IL总是即时编译的,这一点的理解上虽然明白.当用户操作C#开发的软件时,应该是操作已经编译好的程序.那么此时安装在客户机上的程序是 ...

  2. I - Balancing Act POJ - 1655

    Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the t ...

  3. Codeforces 645B Mischievous Mess Makers【逆序数】

    题目链接: http://codeforces.com/problemset/problem/645/B 题意: 给定步数和排列,每步可以交换两个数,问最后逆序数最多是多少对? 分析: 看例子就能看出 ...

  4. 消息队列RabbitMQ使用教程收集

    学习应该要系统,最好的方式是看书. RabbitMQ最权威的教程应该参考官方文档. 下面是收集的一些教程: 官方: https://www.rabbitmq.com/getstarted.html h ...

  5. java代码判断文件类型(判断文件后缀名)

    1.两点需要注意 1.string.spilt("\\.")分割字符串成子字符串数组,以“.”分割,必须写成string.spilt("\\.")的方式,不能写 ...

  6. 基于cocos2d-x-3.2学习Box2D(一)

    cocos版本号:cocos2d-x-3.2 环境:Win7+VS2013 因为一些太底层的实现我如今的能力学习不到,仅仅能做一些简单的笔记,供以后翻阅.假设别人可以得到帮助,莫大的荣幸. 一.创建世 ...

  7. VS2012 ASP.NET 母版页的创建与使用

    在做牛腩新闻公布系统的过程中,须要使用ASP.NET的母版页来抽出全部网页的公共部分,以便更好的复用自己的网页布局和设计. 首先我们来看怎样创建一个新的母版页,例如以下图所看到的: 加入之后,例如以下 ...

  8. VC++6.0不能显示MSDN解决的方法

    1.搜索看系统是否有Vshelp.dll文件.没有则去站点下载一个 位操作系统直接将下载的文件放在C:\Windows\System32 位操作系统则放在C:\Windows\SysWOW64 3.点 ...

  9. hdu 1711 KMP算法模板题

    题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串 ...

  10. Javascript基本概念梳理

    javascript里的数据类型: 原始类型:数字,字符串.布尔值.(原始值:null,undefined) 对象类型:键值对,数组,function,全局对象(MATH,JSON) 保留字: abs ...