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 二.题目大意: 给定一段数据流,要求求出数据流中的中位数,其中数据 ... 
随机推荐
- nyoj_308_Substring_201405091611
			Substring 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 You are given a string input. You are to ... 
- MySQL架构优化实战系列4:SQL优化步骤与常用管理命令
- C#中使用 Oracle的事务与存储过程
			1 存储过程 1.1 不带参数,没有返回值 创建表 create table test (ID number, NAME varchar2(), SEX varchar2(), AGE number, ... 
- WebLogic11g-创建域(Domain)及基本配置
			最近看到经常有人提问weblogic相关问题,所以闲暇之际写几篇博文(基于weblogic11),仅供大家参考. 具体weblogic的介绍以及安装,这里就不赘述了. 以域的创建开篇,虽然简单,但 ... 
- C#高级编程五十二天----有序列表
			有序列表 假设须要基于对全部集合排序,就能够使用SortedList<TKey,TValue>类.这个类依照键给元素排序.这个集合中的值和键都能够使用随意类型. 以下的样例创建了一个有序列 ... 
- Android 最火框架XUtils之注解机制具体解释
			在上一篇文章Android 最火的高速开发框架XUtils中简介了xUtils的基本用法,这篇文章说一下xUtils里面的注解原理. 先来看一下xUtils里面demo的代码: @ViewInject ... 
- unigui组件中client javascript delphi组件之间的操作
			UniLabel组件: function OnClick(sender, e){ MainForm.UniLabel1.setText('Click!');} function Onmousemove ... 
- data-toggle  data-target
			data-toggle https://stackoverflow.com/questions/30629974/how-does-the-data-toggle-attribute-work-wha ... 
- mysql中decimal的使用
			float,double,decimal区别 创建表test_float_double_decimal CREATE TABLE `test_float_double_decimal` ( `id` ... 
- 8-12 canvas专题-阶段练习一(上)
			8-12 canvas专题-阶段练习一(上) <!DOCTYPE html> <html lang="zh-cn"> <head> <me ... 
