【LeetCode】剑指 Offer 41. 数据流中的中位数 p214 -- Java Version
题目链接:https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof
1. 题目介绍(41. 数据流中的中位数)
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
- void addNum(int num) - 从数据流中添加一个整数到数据结构中。
- double findMedian() - 返回目前所有元素的中位数。
【测试用例】:
示例 1:
输入:
[“MedianFinder”,“addNum”,“addNum”,“findMedian”,“addNum”,“findMedian”]
[[],[1],[2],[],[3],[]]
输出:[null,null,null,1.50000,null,2.00000]
示例 2:
输入:
[“MedianFinder”,“addNum”,“findMedian”,“addNum”,“findMedian”]
[[],[2],[],[3],[]]
输出:[null,null,2.00000,null,2.50000]
【条件约束】:
限制:
- 最多会对 addNum、findMedian 进行 50000 次调用。
【相关题目】:
注意:本题与主站 295. 数据流的中位数 题目相同。
2. 题解
2.1 最大堆和最小堆(原书题解) – O(logn)
时间复杂度O(logn),空间复杂度O(n)
偶数情况:
【解题思路】:
该题的解法很多,可以通过数组、链表、二叉搜索树、AVL树、最大堆和最小堆来实现,目前最推荐的就是使用最大堆和最小堆
来解决该问题。该题可以将整个数据容器分成两部分,左边部分的数据要比右边的数据小。我们可以用一个最大堆实现左边的数据容器,用一个最小堆实现右边的数据容器。
两个保证:
- 要保证数据平均分配到两个堆中,两个堆中数据的数目之差不能超过1;
- 要保证最小堆中的所有数据都要大于最大堆中的数据
……
【实现策略】:
- 使用优先队列
PriorityQueue
实现最大堆和最小堆,优先队列的底层实现是一个最小堆,通过重写比较器的方法,可以将其改为大根堆;
更多内容可参考:堆的实现(Java)- 分配数据的插入位置,如果数据的总数目是
偶数
,则把新数据插入到小根堆
,否则则插入到大根堆
;- 保证堆中数据正确,即小根堆中所有数据都要大于大根堆中的数据,因此就要进行判断,如果出现了要插入小根堆中的数据小于大根堆中的数据的情况,那么则将该数据插入到大根堆,并将大根堆的队首元素(最大值)弹出插入到小根堆中;
- 返回中点时进行判断,如果总数是偶数,则返回中点两数的平均值,如果是奇数,则返回小根堆的最小值。
……
【注意点】:
==
运算符的优先级要大于&
运算符:
因此,在判断总数目是偶数时要注意加上括号:((minHeap.size() + maxHeap.size()) & 1) == 0
,挺麻烦的就是说,但如果你不加括号,就会出现下列问题:
更多内容可参考:Java运算符优先级
class MedianFinder {// 最小堆 PriorityQueue<Integer> minHeap;// 最大堆PriorityQueue<Integer> maxHeap;/** initialize your data structure here. */public MedianFinder() {minHeap = new PriorityQueue<>();maxHeap = new PriorityQueue<>((i1, i2) -> Integer.compare(i2, i1));}public void addNum(int num) {// 如果总数目是偶数,则将数据存到小根堆if (((minHeap.size() + maxHeap.size()) & 1) == 0){if (maxHeap.size() > 0 && num < maxHeap.peek()){maxHeap.offer(num);minHeap.offer(maxHeap.poll());}else minHeap.offer(num);} else{ // 否则存到大根堆if (minHeap.size() > 0 && minHeap.peek() < num){minHeap.offer(num); maxHeap.offer(minHeap.poll()); }else maxHeap.offer(num);}}public double findMedian() {// 总数是偶数,返回两数平均值if (((minHeap.size() + maxHeap.size()) & 1) == 0){return (double)(minHeap.peek() + maxHeap.peek())/2;}else{ // 奇数,返回小根堆return minHeap.peek();}}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();*/
代码简化:
【简化思路】:
思路与上面差不多,只不过是简化省略了一些判断过程,直接将判断的过程扔给了堆,如:我要向大根堆插入一个数据,那么我就先要插入的数据扔到小根堆中,然后我把小根堆中最小的数插入大根堆,反之亦然,这样始终能保持小根堆存储较大一半、大根堆存储较小一半。
class MedianFinder {Queue<Integer> A, B;public MedianFinder() {A = new PriorityQueue<>(); // 小顶堆,保存较大的一半B = new PriorityQueue<>((x, y) -> (y - x)); // 大顶堆,保存较小的一半}public void addNum(int num) {if(A.size() != B.size()) {A.add(num);B.add(A.poll());} else {B.add(num);A.add(B.poll());}}public double findMedian() {return A.size() != B.size() ? A.peek() : (A.peek() + B.peek()) / 2.0;}
}
3. 参考资料
[1] 面试题41. 数据流中的中位数(优先队列 / 堆,清晰图解)
相关文章:

【LeetCode】剑指 Offer 41. 数据流中的中位数 p214 -- Java Version
题目链接:https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof 1. 题目介绍(41. 数据流中的中位数) 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位…...
CSS3 知识总结
1,什么是CSS 用于定义网页的样式,包括不同设备和屏幕尺寸的设计、布局和显示变化。 2,CSS的作用优点 CSS 描述 HTML 元素如何在屏幕、纸张或其他媒体上显示 CSS 节省了大量工作。它可以一次控制多个网页的布局 3,css构成 CSS 规…...

回溯算法37:解数独
主要是我自己刷题的一些记录过程。如果有错可以指出哦,大家一起进步。 转载代码随想录 原文链接: 代码随想录 leetcode链接:37. 解数独 题目: 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则…...

【蓝桥杯-筑基篇】动态规划
🍓系列专栏:蓝桥杯 🍉个人主页:个人主页 目录 1.最大连续子段和 2.LCS 最大公共子序列 3.LIS 最长上升子序列 4.数塔 5.最大子矩阵和 6.背包问题 ①01背包问题 ②完全背包 1.最大连续子段和 这段代码是一个求最大子数组和的算法,使用…...
Unity利用Photon PUN2框架快速实现多人在线游戏实例分享
简介 Photon 是一个泛用性的 ScoketServer 套装软件,可用于多人在线游戏、聊天室、大厅游戏,并同时支持 Windows、Unity3D、iOS、Android、Flash 等平台。Photon 包含两个部分,一部分是 Socket 服务器,另一部分是其针对各个平台编写的 SDK,Unity3D 平台对应的 SDK 为 Pho…...
ChatGPT直出1.5w字论文查重率才30% - 基于物联网技术的智能家居控制系统设计与实现
文章目录ChatGPT直出1.5w字论文查重率才30% - 基于物联网技术的智能家居控制系统设计与实现一、绪论1.1 研究背景与意义1.2 国内外研究现状分析1.3 研究内容与目标1.4 研究方向和思路二、物联网技术与智能家居概述2.1 物联网技术原理与应用2.2 智能家居的概念与发展历程2.3 智能…...

特斯拉的操作系统是用什么语言编写的?
总目录链接>> AutoSAR入门和实战系列总目录 文章目录特斯拉车辆操作系统特斯拉GitHub中使用的语言Ruby和GoPythonSwift 和 Objective CQt我们知道操作系统至少需要一些非常低级的代码,这些代码在系统首次启动时运行,必须使用接近硬件的语言编写。…...

C++学习8-C++提高编程
文章目录前言一、模板1.1 模板的概念1.2 函数模板1.2.1 函数模板语法1.2.2 函数模板注意事项1.2.3 函数模板案例复习:计算数组长度1.2.4 普通函数与函数模板的区别1.2.5 普通函数与函数模板的调用规则1.2.6 模板的局限性1.3 类模板1.3.1 类模板语法1.3.2 类模板与函…...
ubuntu安装git server
一安装 要在Ubuntu上安装Git服务器,需要按照以下步骤进行操作: 安装Git: sudo apt-get update sudo apt-get install git 创建一个Git用户和一个Git仓库目录: sudo adduser git sudo mkdir /home/git/repo.git sudo chown git:git /home/git/repo.git 初始化Git仓库: c…...

物流云数据分析平台
物流云数据分析服务平台 http://project.webcats.cn/bx/36569/2455/index.html 本次系统模拟的是湖南省数据,解释权归杭氏集团所有! 1、系统简介: 物流大数据集成展示系统旨在通过大屏幕全面显示指定地区的物流运营车辆、物流公司和货主的相关信息和…...

配置OBS存储功能、新搭建obs
通过应用开发环境与OBS(Object-based Storage Service)对接,实现对象或者Widget资产存储功能。 背景信息 对象存储服务(Object-based Storage Service,OBS)是一个基于对象的海量存储服务,为客…...

基于DPDK收包的suricata的安装和运行
操作系统版本:Ubuntu 20.04.5 suricata版本: suricata-7.0.0-rc1 suricata是一个基于规则的入侵检测和防御引擎,功能强大,但性能可能 差强人意,不过目前最新的7版本已经支持DPDK收包了,DPDK是Intel提供的高…...

浅谈23种设计模式
创建型模式 有5种设计模式 抽象工厂(Abstract Factory):多套方案 抽象工厂模式是对创建不同的产品类型的抽象。对应到工作中,我们的确应该具备提供多套方案的能力,这也是我们常说的,要提供选择题。当你有这…...

JetBrains Rider 2022.3.3 Crack
具有 ReSharper 强大功能的令人难以置信的 .NET IDE!Rider 在我们使用 Windows 和 macOS 的整个开发团队中使用。 什么是骑士? JetBrains Rider 是一个基于 IntelliJ 平台和 ReSharper 的跨平台 .NET IDE。 支持许多 .NET 项目类型 JetBrains Rider 支持…...

浅理解扁平数据结构转Tree(树形结构)
文章目录📋前言🎯扁平数据结构🎯树形数据结构🎯使用递归将扁平数据转换为树形数据📝最后📋前言 在前端开发中,我们经常需要将扁平数据结构转换为树形结构(Tree)。比如在…...
前端开发——JavaScript的条件语句
世界不仅有黑,又或者白 世界而是一道精致的灰 ——Lungcen 目录 条件判断语句 if 语句 if else 语句 if else if else 语句 switch语句 break 关键字 case 子句 default语句 while循环语句 do while循环语句 for循环语句 for 循环中的三个表达式 for 循环嵌套 for …...

2.11 循环赛日程表
博主简介:一个爱打游戏的计算机专业学生博主主页: 夏驰和徐策所属专栏:算法设计与分析 目录 书本内容: 我的理解: 更优化的算法: 总结 1.注意实现问题 2.当用C语言和C实现循环赛日程表算法时ÿ…...

SpringBoot——SB整合mybatis案例(残缺版本)第三集
了解完使用阿里云存储的操作后,现在需要在案例里面集成阿里云进行开发。云服务——阿里云OSS的入门使用_北岭山脚鼠鼠的博客-CSDN博客 阿里云OSS——集成 对于前端传过来的图片要先上传到OSS,然后获取图片在云端的访问地址,存储到数据库里面…...

Baumer工业相机堡盟相机不满帧如何使用CameraExplorer设置相机参数让它的帧率达到满帧
项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具…...

巴黎爱情回忆 NFT 作品集
由 Metaverse Studio 制作。 欢迎来到浪漫之都巴黎!尽情游览美丽壮观的地标,探索法国文化。在离开之前,别忘了从《巴黎爱情回忆》NFT 作品集中带走一件纪念品。从世界著名的法国人物到标志性资产,这些 NFT肯定会为您的钱包带来巴黎…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...