LeetCode295之数据流的中位数(相关话题:优先队列)
题目描述
中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
- 例如
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
提示:
-105 <= num <= 105- 在调用
findMedian之前,数据结构中至少有一个元素 - 最多
5 * 104次调用addNum和findMedian
思路分析
一开始没看懂题目,以为只要用List存储数据,取中位数即可,认真审题可以发现,中位数是有序整数列表中的中间值,所以必须对插入的数据先排序才能求中位值
在数据流中,数据会不断涌入结构中,那么也就面临着需要多次动态调整以获得中位数。 因此实现的数据结构需要既需要快速找到中位数,也需要做到快速调整。
首先能想到就是二叉搜索树,在平衡状态下,树顶必定是中间数,然后再根据长度的奇偶性决定是否取两个数。
此方法效率高,但是手动编写较费时费力。
根据只需获得中间数的想法,可以将数据分为左右两边,一边以最大堆的形式实现,可以快速获得左侧最大数, 另一边则以最小堆的形式实现。其中需要注意的一点就是左右侧数据的长度差不能超过1。 这种实现方式的效率与AVL平衡二叉搜索树的效率相近,但编写更快
显然,为了可以在 O(1) 的复杂度内取得当前中位数,我们应当令 l 为大根堆,r 为小根堆,并人为固定 l 和 r 之前存在如下的大小关系:
- 当数据流元素数量为偶数:l 和 r 大小相同,此时动态中位数为两者堆顶元素的平均值;
- 当数据流元素数量为奇数:l 比 r 多一,此时动态中位数为 l 的堆顶原数。
为了满足上述说的奇偶性堆大小关系,在进行 addNum 时,我们应当分情况处理:
插入前两者大小相同,说明插入前数据流元素个数为偶数,插入后变为奇数。我们期望操作完达到「l 的数量为 r 多一,同时双堆维持有序」,进一步分情况讨论:
- 如果 r 为空,说明当前插入的是首个元素,直接添加到 l 即可;
- 如果 r 不为空,且 num <= r.peek(),说明 num 的插入位置不会在后半部分(不会在 r 中),直接加到 l 即可;
- 如果 r 不为空,且 num > r.peek(),说明 num 的插入位置在后半部分,此时将 r 的堆顶元素放到 l 中,再把 num 放到 r(相当于从 r 中置换一位出来放到 l 中)。
插入前两者大小不同,说明前数据流元素个数为奇数,插入后变为偶数。我们期望操作完达到「l 和 r 数量相等,同时双堆维持有序」,进一步分情况讨论(此时 l 必然比 r 元素多一):
- 如果 num >= l.peek(),说明 num 的插入位置不会在前半部分(不会在 l 中),直接添加到 r 即可。
- 如果 num < l.peek(),说明 num 的插入位置在前半部分,此时将 l 的堆顶元素放到 r 中,再把 num 放入 l 中(相等于从 l 中替换一位出来当到 r 中)。
代码实现
class MedianFinder {//大顶堆PriorityQueue<Integer> l = new PriorityQueue<>((a,b)->b-a);//小顶堆(默认)PriorityQueue<Integer> r = new PriorityQueue<>((a,b)->a-b);public void addNum(int num) {int s1 = l.size(), s2 = r.size();if (s1 == s2) {if (r.isEmpty() || num <= r.peek()) {l.add(num);} else {l.add(r.poll());r.add(num);}} else {if (l.peek() <= num) {r.add(num);} else {r.add(l.poll());l.add(num);}}}public double findMedian() {int s1 = l.size(), s2 = r.size();if (s1 == s2) {return (l.peek() + r.peek()) / 2.0;} else {return l.peek();}}
}
相关文章:
LeetCode295之数据流的中位数(相关话题:优先队列)
题目描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化 Media…...
助你加速开发效率!告别IDEA卡顿困扰的性能优化技巧
在现代软件开发中,IDE(集成开发环境)是一个必不可少的工具。IntelliJ IDEA是一个广受欢迎的IDE,但有时候IDE的性能可能会受到影响,导致开发人员的工作效率降低。本文将介绍一些可以提高IDE性能的技巧,帮助开…...
Java设计模式-适配器模式
1、简介 适配器模式是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。 2、适配器模式分类 目标接口(Target&#x…...
Linux 练习六 (IPC 管道)
文章目录1 标准管道流2 无名管道(PIPE)3 命名管道(FIFO)3.1 创建删除管道文件3.2 打开和关闭FIFO文件3.3 管道案例:基于管道的客服端服务器程序使用环境:Ubuntu18.04 使用工具:VMWare workstati…...
合并两个有序链表(精美图示详解哦)
全文目录引言合并两个有序链表题目描述方法一:将第二个链表合并到第一个思路实现方法二:尾插到哨兵位的头节点思路实现总结引言 在前面两篇文章中,我们介绍了几道链表的习题:反转链表、链表的中间结点、链表的倒数第k个结点&…...
33 JSON操作
目录 一、介绍 二、JSON的特点 三、JSON语法 1、json中的数据类型 四、JSON文件的定义 五、读取JSON文件 1、读取json文件的两种方式 (1)read、write (2)json.load 2、使用json.load读取json文件的步骤 3、练习读取json文件 六、练…...
三八妇女节快乐----IT女神活动随笔
献丑了,一首小小散文诗,请大家轻喷 O(≧口≦)O 我的答案 天下芸芸众生,好似夜幕漫天繁星。 与你相识,只是偶然。 简单的一个招呼,于是开始了一段故事。 我们或是诉说,或是分享; 我们彼此倾听&…...
【PSO-PID】使用粒子群算法整定PID参数控制起动机入口压力值
最近在学优化算法,接触到了经典寻优算法之粒子群PSO,然后就想使用PSO算法来调节PID参数,在试验成功之后将此控制算法应用到了空气起动系统上,同时与之前的控制器进行对比看看哪种控制效果最好。 0 引言 PID参数整定主要有两种&…...
当代数据分析指南:激发商业洞见的七个方法(上)
如果说眼下的发生的事能证明什么,那就是基于实时可信的数据分析正在变得越来越重要。但是要是想要在需要的时候准确地获取中肯的洞察,我们所需要的可不只是漂亮的可视化。 如何让你的员工都有能力和机会都做出最好的决策,不管这个决策会有多…...
javaWeb核心02-JSP、EL、JSTL、MVC
文章目录JSP1,JSP 概述2,JSP 快速入门2.1 搭建环境2.2 导入 JSP 依赖2.3 创建 jsp 页面2.4 编写代码2.5 测试3,JSP 原理4,JSP 脚本4.1 JSP 脚本分类4.2 案例4.2.1 需求4.2.2 实现4.2.3 成品代码4.2.4 测试4.3 JSP 缺点5࿰…...
spring-boot+mybatis-plus连接Oracle数据库,及查询相关数据
配置java 略(这里我用的是jdk1.8) 配置maven 环境变量: M2_HOME:D:\LJ\software\java\maven\apache-maven-3.6.3 Path:%M2_HOME%\bin 仓库/jdk/镜像云设置(./config/sitting) 仓库 <localRepository> D:/…...
电商使用CRM系统有什么好处,如何选择
数据显示,使用电商CRM客户管理系统后,企业销售额提高了87%,客户满意度提高了74%,业务效率提高了73%。要在竞争激烈的电商市场取得成功,与目标受众的有效沟通是有效的方法。下面说说什么是电商CRM系统?电商C…...
Nacos2.2.0多数据源适配oracle12C-修改Nacos源码
从2.2.0版本开始,可通过SPI机制注入多数据源实现插件,并在引入对应数据源实现后,便可在Nacos启动时通过读取application.properties配置文件中spring.datasource.platform配置项选择加载对应多数据源插件.本文档详细介绍一个多数据源插件如何实现以及如何使其生效。 文章目录一…...
第十四届蓝桥杯三月真题刷题训练——第 5 天
目录 题目1:数的分解 题目描述 运行限制 代码: 题目2:猜生日 题目描述 运行限制 代码: 题目3:成绩分析 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码: 题目4:最大和…...
大数据框架之Hive:第3章 DDL(Data Definition Language)数据定义
第3章 DDL(Data Definition Language)数据定义 3.1 数据库(database) 3.1.1 创建数据库 1)语法 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPER…...
概率论小课堂:统计学是大数据方法的基础
文章目录 引言I 统计学1.1 统计学的内容1.2 统计学的目的II 用好数据的五个步骤2.1 设立研究目标2.2 设计实验,选取数据。2.3 根据实验方案进行统计和实验,分析方差。2.4 通过分析进一步了解数据,提出新假说。2.5 使用研究结果III 数据没用好的原因3.1 霍桑效应3.2 数据的稀…...
监控集群概念讲解
监控概述 1、监控的重要性 监控是运维日常的重要工作之一; 监控是有多重要? 监控可以帮助运维监控服务器的状态;要及时解决; 如果淘宝、腾讯宕机了1个小时? 损失是无法估量的; 服务器是否故障、宕不…...
如何通过DAS连接GaussDB
文章目录1 实验介绍2 实验目的3 配置DAS服务4 SQL使用入门1 实验介绍 本实验主要描述如何通过华为云数据管理服务 (Data Admin Service,简称DAS) 来连接华为云GaussDB数据库实例,DAS是一款专业的简化数据库管理工具,提供优质的可视化操作界面…...
支持在局域网使用的项目管理系统有哪些?5款软件对比
一、选择私有部署的原因以及该方案的优点有很多可能的原因导致人们更倾向于使用私有部署的企业管理软件,其中一些原因可能包括:1.数据安全性要求:一些企业管理软件包含敏感的商业数据和隐私信息,为了保护这些信息不被未经授权的第…...
Linux CentOS7 MySQL 5.7安装
准备工作 //创建目录 mkdir /opt/mysql //跳转目录 cd /opt/mysql下载MySQL 请耐心等待,也可以在Windows下载以后上传到 /opt/mysql目录 wget http://dev.mysql.com/get/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar解压 tar -xvf mysql-5.7.26-1.el7.x86_64.rpm-b…...
避坑指南:Prescan8.5安装常见报错解决方案(含MATLAB集成配置)
Prescan8.5安装避坑指南:7类典型报错与MATLAB集成深度解析 当仿真工程师第一次打开Prescan8.5安装包时,很少有人能预料到接下来可能遭遇的"技术迷宫"。作为自动驾驶仿真领域的重要工具,Prescan的安装过程就像它的功能一样复杂——从…...
51单片机Proteus仿真实战:从零构建流水灯系统
1. 环境准备:搭建51单片机开发环境 第一次接触51单片机的朋友可能会被各种工具软件搞晕,其实只需要两个核心工具就能完成流水灯仿真:Proteus和Keil。我刚开始学单片机时也踩过不少坑,这里把最稳定的版本和安装要点分享给大家。 Pr…...
antd vue表单实战:getFieldDecorator、getFieldValue、setFieldValue保姆级教程
Ant Design Vue 表单开发深度指南:数据绑定与动态操作实战 在当今前端开发领域,表单处理一直是构建交互式应用的核心挑战之一。Ant Design Vue 作为企业级 UI 设计语言和 React 实现,提供了一套强大而灵活的表单解决方案,特别适合…...
VScode 高效开发 Springboot 应用的完整指南
1. 环境准备与项目创建 第一次用VScode开发Springboot项目时,我对着空白编辑器发呆了半小时。后来发现只要装对插件,效率能翻倍。先打开VScode的扩展商店,这三个插件是必装的: Java Extension Pack:包含语言支持、调…...
Logisim音乐盒背后的数字电路:计数器、ROM与蜂鸣器如何奏出《终生误》
Logisim音乐盒背后的数字电路:计数器、ROM与蜂鸣器如何奏出《终生误》 当一段熟悉的旋律从蜂鸣器中流淌而出,很少有人会思考这背后隐藏的数字魔法。本文将带您拆解一个基于Logisim的音乐盒设计,揭示计数器如何像指挥家一样协调时序、ROM怎样扮…...
解锁自定义键盘体验:用Vial-QMK打造个性化配置指南
解锁自定义键盘体验:用Vial-QMK打造个性化配置指南 【免费下载链接】vial-qmk QMK fork with Vial-specific features. 项目地址: https://gitcode.com/gh_mirrors/vi/vial-qmk 核心价值:为什么选择Vial-QMK定制键盘? 在机械键盘的世…...
python-flask-djangol框架的食品仓库管理系统
目录需求分析与功能规划技术栈选择系统架构设计开发与测试流程安全与性能优化部署方案项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作需求分析与功能规划 明确食品仓库管理系统的核心需求,包括库存管理、食品分类、…...
VuePress/Hexo博客作者必看:VSCode Paste Image插件路径配置避坑指南
VuePress/Hexo博客作者必看:VSCode Paste Image插件路径配置避坑指南 当你沉浸在VSCode中撰写技术博客时,是否遇到过这样的场景:本地预览时图片显示完美,但一旦部署到线上,所有图片都变成了令人沮丧的404错误ÿ…...
Llama-3.2V-11B-cot惊艳案例:电影截图角色关系推演与剧情发展预测展示
Llama-3.2V-11B-cot惊艳案例:电影截图角色关系推演与剧情发展预测展示 1. 视觉推理工具简介 Llama-3.2V-11B-cot是基于Meta多模态大模型开发的高性能视觉推理工具,专为双卡4090环境深度优化。该工具不仅修复了视觉权重加载的关键问题,还支持…...
Obsidian Full Calendar:5步构建个人知识与时间管理一体化系统
Obsidian Full Calendar:5步构建个人知识与时间管理一体化系统 【免费下载链接】obsidian-full-calendar Keep events and manage your calendar alongside all your other notes in your Obsidian Vault. 项目地址: https://gitcode.com/gh_mirrors/obs/obsidian…...
