295. 数据流的中位数(难)

news/2025/3/16 9:43:08/文章来源:https://www.cnblogs.com/lushuang55/p/18774599

目录
  • 题目
  • 题解:排序
  • 法二、二分
  • 法三、最大堆和最小堆

题目

  • 中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
    例如 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

题解:排序

  • 超出时间限制,时间复杂度O(nlogn),每次调用 findMedian 都需要排序,造成整体效率低下。
var MedianFinder = function() {this.arr = []
};/** * @param {number} num* @return {void}*/
MedianFinder.prototype.addNum = function(num) {this.arr.push(num)
};/*** @return {number}*/
MedianFinder.prototype.findMedian = function() {const n = this.arr.lengththis.arr.sort((a, b) => a - b); // 确保数组是排序的if(n%2==0) {//偶数return (this.arr[n/2-1]+this.arr[n/2])/2}else{//奇数return this.arr[Math.floor(n/2)]}
};

法二、二分

  • 时间复杂度O(n)
var MedianFinder = function() {this.arr = []; // 初始化一个空数组
};/** * 添加数字到数组中* @param {number} num - 要添加的数字* @return {void}*/
MedianFinder.prototype.addNum = function(num) {// 使用二分查找插入元素,以保持数组的排序let left = 0;let right = this.arr.length;while (left < right) {const mid = Math.floor((left + right) / 2);if (this.arr[mid] < num) {left = mid + 1;} else {right = mid;}}// 在找到的位置插入元素this.arr.splice(left, 0, num);
};/*** 查找当前数组的中位数* @return {number} - 中位数*/
MedianFinder.prototype.findMedian = function() {const n = this.arr.length; // 获取数组长度if (n % 2 === 0) { // 如果长度为偶数return (this.arr[n / 2 - 1] + this.arr[n / 2]) / 2; // 返回中间两个数的平均值} else { // 如果长度为奇数return this.arr[Math.floor(n / 2)]; // 返回中间的数}
};

法三、最大堆和最小堆

  • 时间复杂度O(log n)
var MedianFinder = function() {this.maxHeap = []; // 最大堆(存储较小的一半)this.minHeap = []; // 最小堆(存储较大的一半)
};/** * 添加数字到堆中* @param {number} num - 要添加的数字* @return {void}*/
MedianFinder.prototype.addNum = function(num) {// 将数字添加到最大堆this.maxHeap.push(num);this.maxHeap.sort((a, b) => b - a); // 最大堆需要降序排列// 确保最大堆的最大元素小于或等于最小堆的最小元素if (this.minHeap.length > 0 && this.maxHeap[0] > this.minHeap[0]) {const maxToMin = this.maxHeap.shift(); // 从最大堆移除最大元素this.minHeap.push(maxToMin);this.minHeap.sort((a, b) => a - b); // 最小堆需要升序排列}// 重新平衡堆的大小if (this.maxHeap.length > this.minHeap.length + 1) {const moveToMin = this.maxHeap.shift();this.minHeap.push(moveToMin);this.minHeap.sort((a, b) => a - b);} else if (this.minHeap.length > this.maxHeap.length) {const moveToMax = this.minHeap.shift();this.maxHeap.push(moveToMax);this.maxHeap.sort((a, b) => b - a);}
};/*** 查找当前数组的中位数* @return {number} - 中位数*/
MedianFinder.prototype.findMedian = function() {if (this.maxHeap.length > this.minHeap.length) {return this.maxHeap[0]; // 最大堆的顶端是中位数} else {return (this.maxHeap[0] + this.minHeap[0]) / 2; // 两个堆的顶端的平均值}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/899686.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9图看2025中国新质生产力发展举措

发展新质生产力,政府工作报告这样说: ①推动商业航天、低空经济等新兴产业安全健康发展 ②培育生物制造、量子科技、具身智能、6G等未来产业 ③促进专精特新中小企业发展壮大,支持独角兽企业、瞪羚企业发展 ④支持大模型广泛应用 ⑤大力发展智能网联新能源汽车、人工智能手机…

manim边学边做--三维图形的场景类

在Manim中,ThreeDScene是一个专门为三维场景设计的类。 它通过配置三维相机、支持复杂的相机运动以及管理物体与相机的交互关系,为科学可视化、工程仿真、数学教育等领域提供了强大的工具。 典型应用场景包括:三维几何图形的动态演示(如旋转立方体、莫比乌斯环) 物理过程的…

第三章 准确估算的价值

3.1 高估更好还是低估更好 3.1.1 反对高估的观点 管理人员和其他项目干系人有时会担心,如果项目被高估了,帕金森法则就会起作用——也就是所有可以用来完成工作的时间都会被浪费掉。因此,为了避免帕金森法则,某些管理人员会有意识地 "压缩" 这估算值。 另一个顾虑…

Windows中conda的安装与使用

下载安装miniconda 说明: Miniconda是一款管理python环境的软件工具 第一步:下载miniconda 代码如下: win+r后,输入cmd指令按回车 在终端中输入: curl https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py39_4.12.0-Windows-x86_64.exe --output 按照…

CHT 另解

引入 CHT 又叫 凸包优化,是一种利用一次函数(斜率)来优化 Dp 的一种方法。 它的独特之处在于,传统斜率优化依靠的是一个一个的点,而凸包优化是利用一条条直线来优化,省去了一些码量。 我们用一道例题引入。 例1 HDU-3480 Dp 暴力 Link 题目是说,将 \(n\) 个数划分到 \(m…

PHP 发送电子邮件 功能 用法运用 详解

PHP发送电子邮件功能、用法及运用详解 一、PHP发送电子邮件的基本概述 PHP提供了多种方式来发送电子邮件,其中最常用的方法是使用内置的mail()函数或通过SMTP(Simple Mail Transfer Protocol)协议。随着技术的发展,许多开发者更倾向于使用第三方库(如PHPMailer)来增强邮件…

Linux 离线安装 zstd

前言:本文操作是在 CentOS-7 下执行的,不确定在其他 Linux 发布版是否能同样正常执行。1、检查前置依赖组件在安装 zstd 之前,需要确认已安装了相关依赖组件: gcc 。 rpm -qa | grep gcc前置依赖组件的具体离线安装方法请参考:CentOS-7离线安装gcc 2、下载zstd安装包 官方…

HarmonyOS Next开发教程之地图定位

今天分享一下在鸿蒙开发中的地图定位问题,也就是在地图中如何定位自己所在的位置。 关于如何加载显示地图在之前的文章已经详细介绍过,有问题的友友可以点击查看: HarmonyOS NEXT实战教程-实现Keep运动轨迹 将地图定位到自己所在的位置,有几种方法: 一种是在初始化地图前先…

HarmonyOS Next实战教程:实现中间凹陷的异形tabbar

今天要和大家分享的实战案例是实现中间凹陷的tabar前些天在做墨迹天气的时候看到了这种异形的tabbar,看起来比较有挑战性,因为鸿蒙版的墨迹天气app还没有这个东西,我决定尝试做一下。 系统的Tabs肯定是不行了,我们需要自定义。 难度直接拉满,直接做最难的部分,就是这个中…

HarmonyOS NEXT实战:高仿墨迹天气开发手记(附源码)

老余说3月份的神秘产品是为纯血鸿蒙而生的一款全新形态的手机,别人想象不到的手机产品,这次的保密工作真是非常到位,让人十分期待。 闲言少叙,今天为大家分享新年的第一个实战项目,高仿墨迹天气 这个项目中有一些复杂的动效和曲线,对于新手友友来说可能会有一点难,不过没…

VSCode + CMake + MinGW 在 Windows 下的简易调试指南

VSCode + CMake + MinGW 在 Windows 下的简易调试指南 目录VSCode + CMake + MinGW 在 Windows 下的简易调试指南准备工作下载VSCode下载CMake下载MinGW待编译源码VSCode调试task.json 配置launch.json 配置开始调试鉴于网络上关于VSCode的调试的教程不多,并且掺杂着大量的随机…

指令集并行与开发进阶算法

进阶算法 基础算法无法解决中断恢复的问题,即假如有两个写寄存器的操作,指令1,指令2,可能乱序执行时指令2的结果已经将写回了寄存器,但是指令1还未执行,此时发生中断后,从指令1重新开始执行,就会重新进行两次写入,将会发生错误。 只要保证后面指令修改机器状态时, 前面…