一、题目描述

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

例如 arr = [2,3,4] 的中位数是 3 。
例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。
实现 MedianFinder 类:

MedianFinder() 初始化 MedianFinder 对象。

void addNum(int num) 将数据流中的整数 num 添加到数据结构中。

double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

示例 1:

输入
[“MedianFinder”, “addNum”, “addNum”, “findMedian”, “addNum”, “findMedian”]
[[], [1], [2], [], [3], []]
输出
[null, null, null, 1.5, null, 2.0]
解释
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.addNum(2); // arr = [1, 2]
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3); // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0

二、代码思路

首先,分析一下题目。题目要求是找中位数,中位数就是排序好的数组的中间位置,所以从这个角度来讲,可以有一种简单暴力的解法:

维护一个数组即可,然后每次添加元素对数组进行一次快排,最后根据数组的长度是偶数还是奇数找到中位数。

其次,我们从另一个角度来想,数据流会不断变化,需要有一个结构能够实时调整、存储数据流,而且还能支持动态调整维护结构的有序性,保证能够根据有序性找到中位数。

我们可以从以下考虑:

  • TreeSet: 底层是红黑树(可以理解为平衡的二叉搜索树维护有序序列)
    该数据结构顾名思义,底层是维护了一个红黑树来保证插入元素的有序性,可以自定义比较器;同时由于插入是有序的可以使用二分快速找到某一个元素;可以删除插入指定元素;缺点:没有索引,只能使用增强for和迭代器遍历。值和下标都在指定范围内 该题使用了TreeSet作为有序的滑动窗口
  • 优先级队列: 底层是堆,分为大根堆小根堆,本质上是完全二叉树的顺序存储,其是为了找到极值而诞生的数据结构。要通过建堆和调整来维护堆的数据结构。

这里我认为TreeSet 和 priorityQueue都可以,TreeSet跟第一种方法了类似,重点介绍一下priorityQueue方法:

  • 根据中位数分为左右两个堆,left 和 right。
  • left是大根堆、right是小根堆。
  • 插入元素时,如果元素数大于left堆最大元素,那么应该插入right。
  • 插入元素时,如果元素数小于left堆最大元素,那么应该插入left。
  • 同时在插入元素的时候,注意维护left 与 right 高度相差不超过1 。
  • 保持left >= right,只是为了更好维持left 与 right高度。
  • 堆顶元素即为中位数,区分奇数偶数。

LeetCode官方题解

三、代码思路

//维护两个优先级队列,分别存放中位数的左右两部分PriorityQueue<Integer> queueLeft = new PriorityQueue<>((a, b) -> {return b - a;}); //大根堆PriorityQueue<Integer> queueRight = new PriorityQueue<>((a, b) -> {return a - b;}); //小根堆//初始化public MedianFinder() {}//添加数public void addNum(int num) {//约定左队列数与右队列数量相同,或者左比右多一个//所以,如果第一次添加先加入左队列if (queueLeft.isEmpty()) {queueLeft.offer(num);return;}//1. 插入的数比左边的还小,那么加入左边if (num <= queueLeft.peek()) {queueLeft.offer(num);//1.1 如果左边比右边多两个数,那么需要保持左右相差不超过1个if (queueLeft.size() - queueRight.size() >= 2) {queueRight.offer(queueLeft.poll());}} else {//2. 插入的数比左边最大的还大,那么加入右边queueRight.offer(num);//2.1if (queueRight.size() > queueLeft.size()) {queueLeft.offer(queueRight.poll());}}}//获取数,需要考虑奇数偶数中位数不同的情况public double findMedian() {//如果两个队列元素相同(偶数)if (queueLeft.size() == queueRight.size()) {return  (queueLeft.peek() + queueRight.peek()) / 2d;} else {return queueLeft.peek();}}

【leetcode】数据流的中位数相关推荐

  1. Leetcode 295. 数据流的中位数

    1.题目要求 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个 ...

  2. LeetCode 295. 数据流的中位数 Hard难度

    295. 数据流的中位数 题目: 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 ...

  3. [LeetCode][C++]数据流的中位数

    数据流的中位数 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一 ...

  4. 一道简约而不简单的算法题——数据流的中位数 | 附动画解析

    作者 | 程序员小吴 转载自微信公众号(ID:CXYxiaowu) 题目来源于 LeetCode 上第 295 号问题:数据流的中位数.难度级别为 Hard,目前通过率为 33.5% . 题目描述 中 ...

  5. 295. 数据流的中位数

    295. 数据流的中位数 欢迎大家参加每日一题系列并提供其他版本,在你也可以按照相同格式提供你的最新的每日一题题解. 每日一题系列 题目描述: 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是 ...

  6. 堆实战(动态数据流求top k大元素,动态数据流求中位数)

    动态数据集合中求top k大元素 第1大,第2大 ...第k大 k是这群体里最小的所以要建立个小顶堆 只需要维护一个大小为k的小顶堆 即可当来的元素(newCome)> 堆顶元素(smallTo ...

  7. LeetCode 295. 数据流的中位数(大小堆)

    文章目录 1. 题目 2. 大小堆解题 1. 题目 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 ...

  8. 76. Leetcode 295. 数据流的中位数 (堆-技巧一-固定堆)

    技巧一 - 固定堆这个技巧指的是固定堆的大小 k 不变,代码上可通过每 pop 出去一个就 push 进来一个来实现.而由于初始堆可能是0,我们刚开始需要一个一个 push 进堆以达到堆的大小为k,因 ...

  9. leetcode-295 数据流的中位数

    中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操 ...

最新文章

  1. 【POJ/算法】 3259 Wormholes(Bellman-Ford算法, SPFA ,FLoyd算法)
  2. Android进阶笔记07:Android之MVC 理解
  3. openresty开发系列28--openresty中操作mysql
  4. mysql加入用户_Mysql 添加用户
  5. Windows server 2008 r2 开启Aero
  6. Qt 编码问题QTextCodec
  7. 跳转后退_羽毛球后退步法常见问题及解决方法
  8. 《视觉SLAM十四讲——从理论到实践》学习笔记
  9. NTFS文件加密初探
  10. 激活golang编辑器
  11. 计算机新安装系统后桌面上有什么图标,手把手教你全新安装完win10系统后如何设置显示桌面图标-系统操作与应用 -亦是美网络...
  12. CS5211|EDP转LVDS方案介绍|CS5211电路设计
  13. 统计学中位数概念的理解
  14. 终于把所有的 Python 库都整理出来啦
  15. 此计算机无法连接道家庭组,无法加入家庭组怎么办
  16. 你沐浴后的味道,根本让人把持不住!留香24小时,比喷了大牌香水还迷人!...
  17. 对比MIUI7和Flyme4.5 期待神秘的Flyme5
  18. linux手机E680的几个概念
  19. html标签中加入颜色,html怎么给span添加颜色
  20. 实验一:鸢尾花数据集分类

热门文章

  1. multimap 多重映照容器
  2. Android 性能优化 - 彻底解决内存泄漏
  3. 【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析
  4. 构建煤矿物联网大数据平台思路(2)-实时数据库与时序数据库
  5. 联邦身份认证——SAML
  6. AI征战奥林匹克,科技奥运未来可期
  7. Java面向对象之修饰符、封装、继承、多态详解
  8. “智慧赋能 强链塑链”|工程物资供应链管理中的数字化应用
  9. Markdown基本语法-超级全面
  10. python 爬虫 爬取食行生鲜 app