算法通关村第十四关黄金挑战——堆解决数据流的中位数和数组求中位数的方法总结

关注微信公众号:怒码少年。回复关键词【电子书】,领取多本计算机相关电子书
遇到任何问题都可以在后台向我提问,完全免费!!大家共同进步!!

大家好,我是怒码少年小码。

本篇主要是讲讲如何利用堆来求一个数组的中位数,以及求数组中位数的常见方法主题。

数据流的中位数

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

  • 例如 arr = [2,3,4] 的中位数是 3 。
  • 例如 arr = [1,2,3,4] 的中位数是 (2 + 3) / 2 = 2.5 。

分析:观察数组,偶数情况下,把数组分成两份,中位数就是前半数组的最大值和后半数组的最小值的平均值

因此,我们可以创建一个最小堆和最大堆,分别保存数组的较小的那一部分和数组中较大的一部分。要求最小堆的元素数量>= 最大堆的元素数量,两个堆中的元素数量相差不大于一个元素:

  • 两个堆中的元素数量相等。表示数组元素总数是偶数——中位数是最小堆和最大堆的堆顶元素的平均值。
  • 两个堆中的元素数量不相等(最小堆的元素数量>最大堆的元素数量)。表示数组元素总数是奇数——中位数是最小堆的堆顶元素。

堆的构建在C++和python中太麻烦,这里我们利用Java中的优先队列``来解决

PriorityQueue<Integer> minHeap;
PriorityQueue<Integer> maxHeap;public MedianFinder() {this.minHeap = new PriorityQueue<>();this.maxHeap = new PriorityQueue<>((a,b)->b-a);
}public void addNum(int num) {//num比minHeap的最小值大,说明它可以插入到最小堆中if(minHeap.isEmpty() || num > minHeap.peek()){minHeap.offer(num);//minHeap中的元素个数比maxHeap多2个元素,就平衡一下if(minHeap.size()-maxHeap.size() > 1){maxHeap.offer(minHeap.poll());}}else{maxHeap.offer(num);//确保多的那一个元素一定在最小堆,也就是总数是奇数的时候,中间值在最小堆中if(maxHeap.size() > minHeap.size() ){minHeap.offer(maxHeap.poll());}}
}public double findMedian() {if(minHeap.size() > maxHeap.size()){return minHeap.peek();}else{return (minHeap.peek() + maxHeap.peek()) / 2.0;}
}

求数组中位数的方法总结

排序法:

利用某种排序算法将数组进行排序,然后根据数组长度的奇偶性确定中位数的位置。如果数组长度为奇数,中位数即为排序后的中间元素;如果数组长度为偶数,中位数为排序后中间两个元素的平均值。

import java.util.Arrays;public class Median {public static double findMedian(int[] nums) {Arrays.sort(nums);int n = nums.length;if (n % 2 == 0) {return (nums[n / 2 - 1] + nums[n / 2]) / 2.0;} else {return nums[n / 2];}}
}

堆法:

(就是上面写的方法)利用最大堆和最小堆,将数组分成两部分。最大堆存储较小的一部分元素,最小堆存储较大的一部分元素。如果两个堆的大小相等,则中位数为两个堆顶元素的平均值;否则,中位数为较大堆的堆顶元素。

双指针法:

对数组进行两端指针的遍历。在遍历过程中,根据条件将指针向中间移动,直到找到中位数。这种方法适用于已经有序或部分有序的数组。

import java.util.Arrays;public class Median {public static double findMedian(int[] nums) {Arrays.sort(nums);int left = 0;int right = nums.length - 1;while (left < right) {left++;right--;}if (left == right) {return nums[left];} else {return (nums[left] + nums[right]) / 2.0;}}
}

快速选择算法:

基于快速排序的思想,通过每次选择一个元素作为基准点将数组分成两部分,然后根据基准点的位置继续递归搜索中位数所在的部分,直到找到中位数。

import java.util.Random;public class Median {public static double findMedian(int[] nums) {int n = nums.length;if (n % 2 == 0) {return (quickSelect(nums, 0, n - 1, n / 2 - 1) + quickSelect(nums, 0, n - 1, n / 2)) / 2.0;} else {return quickSelect(nums, 0, n - 1, n / 2);}}private static int quickSelect(int[] nums, int left, int right, int k) {int pivotIndex = partition(nums, left, right);if (pivotIndex == k) {return nums[k];} else if (pivotIndex < k) {return quickSelect(nums, pivotIndex + 1, right, k);} else {return quickSelect(nums, left, pivotIndex - 1, k);}}private static int partition(int[] nums, int left, int right) {int randomIndex = new Random().nextInt(right - left + 1) + left;swap(nums, randomIndex, right);int pivot = nums[right];int i = left - 1;for (int j = left; j < right; j++) {if (nums[j] <= pivot) {i++;swap(nums, i, j);}}swap(nums, i + 1, right);return i + 1;}private static void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}

END

关关难过,关关过!算法就是要长期练习!大家加油!!

关注微信公众号:怒码少年。
遇到任何问题都可以在后台向我提问,完全免费!!大家共同进步!!

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

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

相关文章

软件测试/测试开发丨性能测试体系学习笔记

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/28412 一、性能测试体系 1.性能测试介绍 为什么要做性能测试 有效的性能测试能给研发&#xff0c;运维团队提供有效的容量规划能力&#xff0c;系统风险…

Oracle 安装及 Spring 使用 Oracle

参考内容&#xff1a; docker安装oracle数据库史上最全步骤&#xff08;带图文&#xff09; Mac下oracle数据库客户端 Docker安装Oracle docker能安装oracle吗 Batch script for add a auto-increased primary key for exist table with records Docker 安装 Oracle11g 注意&a…

element 弹窗浏览器后退-遮照层还存在问题 以及跟vue keep-alive冲突

问题&#xff1a;element 弹窗浏览器后退-遮照层还存在问题 查询官网可以设置 modal-append-to-body“false” 可以全局设置 ElementUI.Dialog.props.modalAppendToBody.default false 后续 基本到这能解决问题&#xff0c;不过本项目比较特殊&#xff0c;使用了 keep-alive…

自定义拖拽列表

效果图 DataAnalysis.vue <template><div class"app-container"><div class"operate"><el-select class"t_select" v-model"templateName" clearable placeholder"模版" size"default" cle…

java计算机毕业设计SpringBoot在线答疑系统

项目介绍 本文从学生的功能要求出发&#xff0c;建立了在线答疑系统&#xff0c;系统中的功能模块主要是实现管理员权限&#xff1b;首页、个人中心、学生管理、教师管理、问题发布管理、疑难解答管理。教师权限&#xff1a;首页、个人中心、疑难解答管理、试卷管理、试题管理…

Halcon WPF 开发学习笔记(1):Hello World小程序

文章目录 文章专栏视频链接Hello World训练图片训练目的 开始训练图像预处理导入图像三通道处理调用算子通道选取 滤波什么是好的滤波 增加对比度 区域选取阈值处理算子参数选择运行结果(红色为选择区域) 区域分割运行结果 特征筛选参数代码第二次&#xff0c;面积筛选 画选中十…

技术分享 | 想做App测试就一定要了解的App结构

app 的结构包含了 APK 结构和 app 页面结构两个部分 APK结构 APK 是 Android Package 的缩写&#xff0c;其实就是 Android 的安装包。通过将 APK 文件直接传到 Android 模拟器或 Android 手机中执行即可安装。 APK 文件其实是 zip 格式&#xff0c;但后缀名被修改为 apk&am…

插入损耗——线对上的信号衰减

“您好&#xff0c;我需要您的帮助。我在测试长距离线缆的时候&#xff0c;插入损耗没有通过测试&#xff01;”这是在对铜缆布线进行验收测量时&#xff0c;我们经常能够听到的问题。针对这一情况&#xff0c;我们必须了解这一电气特性的基础知识&#xff0c;才能提供更专业的…

jenkins gitlab CI/CD

jenkins的安装教程就不说了&#xff1a;Jenkins docker 一键发布 (一)_jenkins 一键发布-CSDN博客 最近打算从svn切换到gitlab&#xff0c;所以配置了一下jenkins的git 很简单&#xff0c;直接上图 1 选择 Git 2 录入gitlab的http地址&#xff08;由于我的git地址不是22端口&…

【Spring】使用注解装配bean

目录 使用注解的两个必要步骤 正文 Cat Dog Animal beans.xml 测试 Qualifier 使用注解的两个必要步骤 1.导入约束 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:…

3线SPI驱动 HX8347 TFT屏

老五家2.8寸屏&#xff0c;3线SPI驱动 前言 要知道屏幕的驱动芯片都小的惊人&#xff0c;想必是不会打上丝印的。从几百个引脚中判断哪个是哪个&#xff0c;想想就晕。 大佬们都太厉害了&#xff0c;看看PFC就知道屏幕的接线定义。一直好奇这种神技是怎么练成的。也尝试自己来…

ASUS华硕灵耀X2 Duo UX481FA(FL,FZ)_UX4000F工厂模式原装出厂Windows10系统

下载链接&#xff1a;https://pan.baidu.com/s/1sRHKBOyc3zu1v0qw4dSASA?pwd7nb0 提取码&#xff1a;7nb0 带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、MyASUS华硕电脑管家等预装程序所需要工具&#xff1a;16G或以上…

按键精灵中的UI界面操作

1. 按键精灵中UI界面常用的控件 1. 文字框 界面1: {标签页1:{文字框:{名称:"文字框1",显示内容:"显示内容",文字大小:0,高度:0,宽度:0,注释:"文字大小、高度、宽度是可选属性&#xff0c;如需使用默认值&#xff0c;可保持值为0或直接删除此属性&qu…

Gluster安装

环境 操作系统&#xff1a;centos8 gluster 9版本 server22 192.168.6.22 gluster-server server23 192.168.6.23 gluster-server server26 192.168.6.26 gluster-client 提前关闭防火墙 准备磁盘 在22 23节点上准备一个新磁盘 /sdc&#xff0c; 使用 XFS 文件系统格式…

技术分享 | App常见bug解析

功能Bug 内容显示错误 前端页面展示的内容有误。 这种错误的产生有两种可能 1、前端代码写的文案错误 2、接口返回值错误 功能错误 功能错误是在测试过程中最常见的类型之一&#xff0c;也就是产品的功能没有实现。比如图中的公众号登录不成功的问题。 界面展示错乱 产品…

网络溯源-PSEXEC-简单

题干&#xff1a; 我们的入侵检测系统&#xff08;IDS&#xff09;已发出警报&#xff0c;指示涉及使用PsExec的可疑横向移动活动。为了有效响应此事件&#xff0c;您作为 SOC 分析师的角色是分析存储在 PCAP 文件中的捕获网络流量。 攻击者首次攻击成功的计算机源网络IP地址…

【服务器】Java连接redis及使用Java操作redis、使用场景

一、Java连接redis-No-SQL 1、导入依赖 在你的项目里面导入redis的pom依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version> </dependency> 2、连接redis 连接redis //…

AI:61-基于深度学习的草莓病害识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

高压放大器能够在哪里使用呢

高压放大器是一种重要的电子设备&#xff0c;可以在许多不同的领域和应用中使用。下面西安安泰将详细介绍高压放大器的应用。 医学影像&#xff1a;高压放大器在医学影像领域具有广泛的应用。医学影像设备&#xff08;如X射线机、CT扫描仪等&#xff09;需要高压来产生足够的能…

竞赛选题 深度学习手势识别算法实现 - opencv python

文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习手势识别算法实现 - opencv python 该项目较为新颖…