中位数是排序后列表的中间值。如果列表的大小是偶数,则没有中间值,此时中位数是中间两个数的平均值。
示例:
[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. chdoj38 K-partite Graph(补图)

    题意: 若一个无向图G的节点能够分成k(k>=2)个非空集合,对于每对点,当且仅当他们属于不同的集合,存在一条边(ui,vi)连接他们.那么这个图就是一个完全k分图. 现在给出一个n点,m条边的 ...

  2. Ubuntu 16.04开机自动挂载硬盘分区(转)

    说明:如果挂载以前旧硬盘分区时不需要第2.3步! 1.查看Linux硬盘信息: sudo fdisk -l 2.格式化新硬盘(很危险,注意操作时确定硬盘分区的位置): sudo mkfs.ext4 / ...

  3. Linux 下添加 Eclipse 桌面图标

    1. sudo gedit  /usr/share/applications/eclipse.desktop 2. 向eclipse .desktop中添加以下内容: [Desktop Entry] ...

  4. java 代理模式具体解释

    java 动态代理(JDK和cglib) 设计模式这东东每次看到就明确可过段时间又不能非常流利的说出来.今天就用具体的比喻和实例来加深自己的理解(小弟水平不高有不正确的地方希望大家能指出来). (1) ...

  5. C#字符串数组排序 C#排序算法大全 C#字符串比较方法 一个.NET通用JSON解析/构建类的实现(c#) C#处理Json文件 asp.net使用Jquery+iframe传值问题

    C#字符串数组排序   //排序只带字符的数组,不带数字的 private   string[]   aa   ={ "a ", "c ", "b & ...

  6. 异步FIFO的编程

    对于异步FIFO.最基本的两个方面是地址控制和空.满标志位的产生.首先地址控制分别为读地址和写地址,每次读写时能读写地址应该加1.计数次数为ram深度的2倍.当读写地址相等时则空标志位有效,当读写地址 ...

  7. 六:二叉树中第k层节点个数与二叉树叶子节点个数

    二叉树中第k层节点个数 递归解法: (1)假设二叉树为空或者k<1返回0 (2)假设二叉树不为空而且k==1.返回1 (3)假设二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树 ...

  8. 8148和8127中的ezsdk和dvrsdk

    http://www.dajudeng.com/d2012081009b8a9d5de87101f69f31952c.html

  9. what is Servlet Container[转载]

    1 在这个博客中,我将描述一下web服务器.Servlet容器的基本概念,以及Servlet容器和jvm之间的关系.我想要证明的是Servlet容器不过就是一个java程序. 2 什么是web服务器 ...

  10. java中间变量缓存机制

    public class Demo { public static void main(String[] args){ method_1(); method_2(); } private static ...