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

  1. class MedianFinder {
  2. private Queue<Integer> maxHeap;
  3. private Queue<Integer> minHeap;
  4.  
  5. /**
  6. * initialize your data structure here.
  7. */
  8. public MedianFinder() {
  9. this.maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>() {
  10. @Override
  11. public int compare(Integer o1, Integer o2) {
  12. return o2.compareTo(o1);
  13. }
  14. });
  15. this.minHeap = new PriorityQueue<Integer>();
  16. }
  17.  
  18. public void addNum(int num) {
  19. if (maxHeap.size() < minHeap.size()) {
  20. maxHeap.add(num);
  21. minHeap.add(maxHeap.poll());
  22. maxHeap.add(minHeap.poll());
  23. } else {
  24. minHeap.add(num);
  25. maxHeap.add(minHeap.poll());
  26. minHeap.add(maxHeap.poll());
  27. }
  28. }
  29.  
  30. public double findMedian() {
  31. if (maxHeap.size() < minHeap.size()) {
  32. return minHeap.peek();
  33. } else if (maxHeap.size() > minHeap.size()) {
  34. return maxHeap.peek();
  35. } else {
  36. return (minHeap.peek() + maxHeap.peek()) / 2.0;
  37. }
  38. }
  39. }
  40.  
  41. /**
  42. * Your MedianFinder object will be instantiated and called as such:
  43. * MedianFinder obj = new MedianFinder();
  44. * obj.addNum(num);
  45. * double param_2 = obj.findMedian();
  46. */

C++实现:

方法一:

  1. class MedianFinder {
  2. public:
  3. /** initialize your data structure here. */
  4. MedianFinder() {
  5. maxH={};
  6. minH={};
  7. }
  8.  
  9. void addNum(int num) {
  10. if(((minH.size() + maxH.size()) & 0x1) == 0)
  11. {
  12. if(!maxH.empty() && num<maxH[0])
  13. {
  14. maxH.push_back(num);
  15. push_heap(maxH.begin(),maxH.end(),less<int>());
  16.  
  17. num = maxH[0];
  18. pop_heap(maxH.begin(),maxH.end(),less<int>());
  19. maxH.pop_back();
  20. }
  21. minH.push_back(num);
  22. push_heap(minH.begin(),minH.end(),greater<int>());
  23.  
  24. }
  25. else
  26. {
  27. if(!minH.empty() && num>minH[0])
  28. {
  29. minH.push_back(num);
  30. push_heap(minH.begin(),minH.end(),greater<int>());
  31.  
  32. num = minH[0];
  33. pop_heap(minH.begin(),minH.end(),greater<int>());
  34. minH.pop_back();
  35. }
  36. maxH.push_back(num);
  37. push_heap(maxH.begin(),maxH.end(),less<int>());
  38. }
  39.  
  40. }
  41.  
  42. double findMedian() {
  43. int size = minH.size() + maxH.size();
  44.  
  45. double median = 0;
  46. if((size&0x1) == 1)
  47. {
  48. median = minH[0];
  49. }
  50. else
  51. {
  52. median = (minH[0]+maxH[0])*0.5;
  53. }
  54. return median;
  55. }
  56. private:
  57. vector<int> maxH;
  58. vector<int> minH;
  59. };
  60.  
  61. /**
  62. * Your MedianFinder object will be instantiated and called as such:
  63. * MedianFinder obj = new MedianFinder();
  64. * obj.addNum(num);
  65. * double param_2 = obj.findMedian();
  66. */

方法二:

  1. class MedianFinder {
  2. public:
  3. /** initialize your data structure here. */
  4. MedianFinder() {
  5.  
  6. }
  7.  
  8. void addNum(int num) {
  9. small.push(num);
  10. large.push(-small.top());
  11. small.pop();
  12. if(small.size()<large.size())
  13. {
  14. small.push(-large.top());
  15. large.pop();
  16. }
  17. }
  18.  
  19. double findMedian() {
  20. return small.size()>large.size()?small.top():0.5*(small.top()-large.top());
  21. }
  22. private:
  23. priority_queue<int> small,large;
  24. };
  25.  
  26. /**
  27. * Your MedianFinder object will be instantiated and called as such:
  28. * MedianFinder obj = new MedianFinder();
  29. * obj.addNum(num);
  30. * double param_2 = obj.findMedian();
  31. */

方法三:

  1. class MedianFinder {
  2. public:
  3. /** initialize your data structure here. */
  4. MedianFinder() {
  5.  
  6. }
  7.  
  8. void addNum(int num) {
  9. small.insert(num);
  10. large.insert(-*small.begin());
  11. small.erase(small.begin());
  12. if(small.size()<large.size())
  13. {
  14. small.insert(-*large.begin());
  15. large.erase(large.begin());
  16. }
  17. }
  18.  
  19. double findMedian() {
  20. return small.size()>large.size()?*small.begin():0.5*(*small.begin()-*large.begin());
  21. }
  22. private:
  23. multiset<int> small,large;
  24. };
  25.  
  26. /**
  27. * Your MedianFinder object will be instantiated and called as such:
  28. * MedianFinder obj = new MedianFinder();
  29. * obj.addNum(num);
  30. * double param_2 = obj.findMedian();
  31. */

方法四:

  1. class MedianFinder {
  2. public:
  3. /** initialize your data structure here. */
  4. MedianFinder() {
  5.  
  6. }
  7.  
  8. void addNum(int num) {
  9. if(maxH.empty()||num<=maxH.top())
  10. {
  11. maxH.push(num);
  12. }
  13. else
  14. {
  15. minH.push(num);
  16. }
  17. if(minH.size()+2==maxH.size())
  18. {
  19. minH.push(maxH.top());
  20. maxH.pop();
  21. }
  22. if(maxH.size()+1==minH.size())
  23. {
  24. maxH.push(minH.top());
  25. minH.pop();
  26. }
  27. }
  28.  
  29. double findMedian() {
  30. return minH.size()==maxH.size()?0.5*(minH.top()+maxH.top()):maxH.top();
  31. }
  32. private:
  33. priority_queue<int,vector<int>,less<int>> maxH;
  34. priority_queue<int,vector<int>,greater<int>> minH;
  35. };
  36.  
  37. /**
  38. * Your MedianFinder object will be instantiated and called as such:
  39. * MedianFinder obj = new MedianFinder();
  40. * obj.addNum(num);
  41. * double param_2 = obj.findMedian();
  42. */

参考: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. HDU - 2059 龟兔赛跑(多阶段决策dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=2059 初始把起点和终点也算做充电站,设dp[i]是到第i个充电站的最短时间,那么dp[n+1]即是乌龟到达终点的 ...

  2. 02-js变量学习

    <html> <head> <title>js的变量学习</title> <meta charset="UTF-8"/> ...

  3. FlashChart json数据配置 中文文档

    http://www.riaos.com/ria/2274 FlashChart json数据配置说明 有朋友要用flashchart,感觉这个还不错.就整理了一份文档. 基本包括了所有json配置的 ...

  4. [React] Build a slide deck with mdx-deck using Markdown + React

    In this lesson we'll use mdx-deck to create a slide deck using Markdown and React. We'll look at add ...

  5. Chromium硬件加速渲染的UI合成过程分析

    在Chromium中.Render端和WebGL端绘制出来的UI终于是通过Browser端显示在屏幕上的.换句话说.就是Browser端负责合成Render端和WebGL端的UI.这涉及到不同Open ...

  6. C++之桟的应用---括号匹配

    刚開始学习数据结构.用桟写了一个经典的应用,括号匹配. 算法思路: 输入字符串时.将 '(' , '['  压入桟.遇到 ')'  ']'  时,再栈顶出桟.进行括号匹配.假设成功匹配.则继续进行.否 ...

  7. 【code】flex_进度条样式

    近期打算吧硬盘中的资料记录在博客中,实用的就当是个分享,无用的就当是个备份,还望大家不要见怪. 一共4个文件: JinDuTiaoItem.mxml: <?xml version="1 ...

  8. Java集合类汇总记录--JDK篇

    接口类图 Java Collection由两套并行的接口组成,一套是Collection接口,一套是Map接口.例如以下图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkb ...

  9. nginx-Proxy Cache缓存

      1.创建目录 mkdir /export/Data/nginx_proxy_cache mkdir /export/Data/nginx_proxy_temp   2.修改http,打开缓存 文件 ...

  10. projecteuler----&gt;problem=12----Highly divisible triangular number

    title: The sequence of triangle numbers is generated by adding the natural numbers. So the 7th trian ...