数组-两个升序数组中位数

一、题目描述

二、解题思路

(一).基本思想:

如果列表总长度allsize( =arr1.size()+arr2.size() ) 为奇数时,中位数位置应该在两个列表排序后的第 allsize/2 位置处,如果allsize为偶数,中位数应该取 (allsize/2)-1 和 allsize/2 的平均数。

设置两个指针p1、p2,一个指向列表 arr1[0] ,一个指向列表 arr2[0] ,比较两个指针指向列表的值,值较小的指针往后移动一位

再次比较p1、p2,重复上述动作。

(二).注意:因为两个列表长度不一定相同,所以存在某一个指针p1遍历到列表末尾,但是仍然没有找到中位数,这时候中位数有可能就会出现①p1、p2均在列表中间,此时取二者较小值或者平均值、②在另一个列表中、③另一个列表中两个元素取平均值、④p1(此时在末尾)和p2取平均值、⑤p1(此时在末尾)这几种情况,下面就对各种可能出现的情况进行举例说明,以写出比较严谨的代码实现,覆盖各种可能出现的情况。

比较次数和总列表长度的奇偶性还有确定中位数位置是有关联性的,这一点可以自己在下面例子里尝试一下。

1.当allsize为奇数时:只存在一个中位数,此时比较次数为 allsize/2 次

(1).p1、p2在中间位置

        [1,2,3,8,9] 和 [4,5,6,7] ,总列表 [1,2,3,4,5,6,7,8,9]

        总长度为9,比较4次:

                第一次 p1->1,p2->4,p1<p2,p1++;

                第二次 p1->2,p2->4,p1<p2,p1++;

                第三次 p1->3,p2->4,p1<p2,p1++;

                第四次 p1->8,p2->4,p1>p2,p2++;

                此时:p1->8,p2->5 取二者较小值为5,中位数为5

(2).p1在arr1末尾,并且p1<=p2时

        [1,2,3,4]和[5,6,7,8,9],总列表 [1,2,3,4,5,6,7,8,9]

        总长度为9,比较4次:

                第一次 p1->1,p2->5,p1<p2,p1++;

                第二次 p1->2,p2->5,p1<p2,p1++;

                第三次 p1->3,p2->5,p1<p2,p1++;

                第四次 p1->4,p2->5,p1<p2,此时p1已经在末尾,不再++,设置变量标记中位数在arr2中(p2侧);

                此时:直接取p2为中位数,中位数为5

(3).p1在arr1末尾,并且p1>p2时

        [1,2,3,5]和[4,6,7,8,9],总列表 [1,2,3,4,5,6,7,8,9]

        总长度为9,比较4次:

                第一次 p1->1,p2->4,p1<p2,p1++;

                第二次 p1->2,p2->4,p1<p2,p1++;

                第三次 p1->3,p2->4,p1<p2,p1++;

                第四次 p1->5,p2->4,p1>p2,此时p2++;

                此时:p1->5,p2->6 取p1、p2二者较小值,中位数为5

2.当allsize为偶数时,中位数等于中间两个元素取平均值,此时两个元素比较次数为 allsize/2 -1 次,执行完allsize/2 -1 次判断时: 

(1).p1、p2在中间位置,并不能确定中间两个数在哪一侧产生,可能是两侧各贡献一个(包括p1或者p2没有发生移动的情况)

        两侧各贡献一个:

        (这种情况牛客里面的测试用例没有覆盖这种情况,刚开始我写的代码这部分有缺陷,所以会出现问题,下面的代码实现已经补上了处理策略,判断过程看下面加粗黄色说明部分)

        [1,2,3,8,9] 和 [4,5,6,7,10] ,总列表 [1,2,3,4,5,6,7,8,9,10]

        总长度为10,比较4次:

                第一次 p1->1,p2->4,p1<p2,p1++;

                第二次 p1->2,p2->4,p1<p2,p1++;

                第三次 p1->3,p2->4,p1<p2,p1++;

                第四次 p1->8,p2->4,p1>p2,p2++;

                此时:p1->8,p2->5,最后一次移动的是p2(作为求平均数的左值),且p2未到达末尾,需要比较(p2+1)和p1位置的值,(p2+1)->6,p1->8,取二者较小值为6,中位数为(5+6)/2=5.5

        

        [4,5,6,7,10] 和 [1,2,3,8,9] ,总列表 [1,2,3,4,5,6,7,8,9,10]

        总长度为10,比较4次:

                第一次 p2->4,p1->1,p1>p2,p2++;

                第二次 p1->4,p2->2,p1>p2,p2++;

                第三次 p1->4,p2->3,p1>p2,p2++;

                第四次 p1->4,p2->8,p1<p2,p1++;

                此时:p1->5,p2->8,最后一次移动的是p1(作为求平均数的左值),且p1未到达末尾,需要比较(p1+1)和p2位置的值,(p1+1)->6,p1->8,取二者较小值为6,中位数为(5+6)/2=5.5


        p1或者p2没有发生移动的情况:

        [1,2,3,7]和[4,5,8,9],总列表 [1,2,3,4,5,7,8,9]

        总长度为8,比较3次:

                第一次 p1->1,p2->4,p1<p2,p1++;

                第二次 p1->2,p2->4,p1<p2,p1++;

                第三次 p1->3,p2->4,p1<p2,p1++;

                此时:p1->7,p2->4  需要比较一下p1和p2+1位置的大小,如果p1>p2+1,中位数选择p2和p2+1位置元素和的平均值;如果p1<p2+1,中位数选择p1和p2的平均值。

                

        [4,5,8,9] 和 [1,2,3,7],总列表 [1,2,3,4,5,7,8,9]

        总长度为8,比较3次:

                第一次 p1->4,p2->1,p1>p2,p2++;

                第二次 p1->4,p2->2,p1>p2,p2++;

                第三次 p1->4,p2->3,p1>p2,p2++;

                此时:p1->4,p2->7 需要比较一下p2和p1+1位置的大小,如果p2>p1+1,中位数选择p1和p1+1位置元素和的平均值;如果p2<p1+1,中位数选择p1和p2的平均值。


        并不能确定是否只出现在一侧的情况:

        [1,8] 和 [4,5,6,7,8,9],总列表 [1,4,5,6,7,8,8,9]

        总长度为8,比较3次:

                第一次 p1->1,p2->4,p1<p2,p1++;

                第二次 p1->8到达末尾,p2->4,p1>p2,p2++;

                第三次 p1->8到达末尾,p2->5,p1>p2,p2++;

                此时:p1->8,p2->6  p1到达末尾,p2一定是中间两个数之一,需要比较一下p2+1和p1的大小,取较小值作为另一个数,p2+1->7,p1->8,取p2+1和p2的平均数作为中位数,值为6.5。

(2).p1早已到达arr1末尾,确定两个数确定在p2侧产生

         [6,7] 和 [5,9,10,11,12,13],总列表 [5,6,7,9,10,11,12,13]

        总长度为8,比较3次:

                第一次 p1->6,p2->5,p1>p2,p2++;

                第二次 p1->6,p2->9,p1<p2,p1++;

                第三次 p1->7到达末尾,p2->9,p1<p2,p2++,且设置标志位;

                此时:中间两个数只会是p2和p2+1位置的值,计算两个数的平均数:p2->9,(p2+1)->10,平均值为8.5。

(3).p2早已到达arr2末尾,中间两个数确定在p1侧产生,这个执行过程大家自己根据上面(2)的过程推理一下。

       [5,9,10,11,12,13] 和 [6,7],总列表 [5,6,7,9,10,11,12,13]

三、代码实现

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param nums1 int整型ArrayList* @param nums2 int整型ArrayList* @return double浮点型*/public double Median (ArrayList<Integer> nums1, ArrayList<Integer> nums2) {double res = 0;int allsize = nums1.size() + nums2.size();int mididx = allsize / 2;int icounter=0;boolean oddnum=false;//奇数数if(allsize%2!=0){oddnum=true;//此时根据side判断取哪一侧的值,如果没有出现倾斜情况,则取p1、p2较小值icounter=mididx;}else{oddnum=false;//此时取p1和p2位置平均值icounter=mididx-1;}int p1 = 0, p2 = 0;boolean p1side=false,p2side=false;int lastestmove=0;while (icounter > 0) {if (p1 < (nums1.size() - 1) && nums1.get(p1) <= nums2.get(p2)) {p1++;lastestmove=1;}else if(p1 == (nums1.size() - 1)){if(!oddnum){if(!p2side&&nums1.get(p1)>nums2.get(p2)){p2++;lastestmove=2;}else if(!p2side&&nums1.get(p1)<=nums2.get(p2)){p2side=true;}else{p2++;lastestmove=2;}    }else{if(!p2side&&nums1.get(p1)>nums2.get(p2)){p2++;lastestmove=2;}else{if(!p2side){p2side=true;}else{p2++;lastestmove=2;}}}}else if (p2 < (nums2.size() - 1) && nums1.get(p1) > nums2.get(p2)) {p2++;lastestmove=2;}else if (p2 == (nums2.size() - 1)) {if(!oddnum){if(!p1side&&nums2.get(p2)>=nums1.get(p1)){p1++;lastestmove=1;}else if(!p1side&&nums2.get(p2)<nums1.get(p1)){p1side=true;}else{p1++;lastestmove=1;}    }else{if(!p1side&&nums2.get(p2)>nums1.get(p1)){p1++;lastestmove=1;}else{if(!p1side){p1side=true;}else{p1++;lastestmove=1;}}}}icounter--;}if (!oddnum) { //此时取中间两个值的平均数为中位数if(p1side){//中间两个数位于p1侧res=((double)(nums1.get(p1)) + (double)(nums1.get(p1+1))) / 2;}else if(p2side){//中间两个数位于p2侧res=((double)(nums2.get(p2)) + (double)(nums2.get(p2+1))) / 2;}else{double minright=(double)(nums2.get(p2));double minleft=(double)(nums1.get(p1));if(lastestmove==1){//此时p1为左值//偶数个数时,当最后一次移动发生在p1侧且p1侧没有到达末尾,比较p1+1和p2大小,取较小值作为右值minleft=(double)(nums1.get(p1));minright=nums1.get(p1+1)>nums2.get(p2)?nums2.get(p2):nums1.get(p1+1);}else if(lastestmove==2){//此时p2为右值//原理同上,比较p2+1和p1大小,取较小值minleft=(double)(nums2.get(p2));minright=nums2.get(p2+1)>nums1.get(p1)?nums1.get(p1):nums2.get(p2+1);}res=( minleft + minright) / 2;}} else { //此时取p1、p2两者较小的值if(p1side){res = nums1.get(p1);}else if(p2side){res = nums2.get(p2);}else{res = Math.min(nums2.get(p2),nums1.get(p1));}}return res;}
}

四、刷题链接

两个升序数组的中位数_牛客题霸_牛客网

五、近似题目

数组-在两个长度相等的有序数组中找到上中位数-CSDN博客文章浏览阅读272次,点赞4次,收藏6次。java刷题:查找两个长度相等的有序数组中的上中位数。https://blog.csdn.net/hehe_soft_engineer/article/details/139200124?spm=1001.2014.3001.5502

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

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

相关文章

【Python】 如何在Python中设置环境变量?

基本原理 在Python中&#xff0c;环境变量是一种存储系统或应用程序配置信息的方式&#xff0c;它们可以被操作系统或应用程序访问。环境变量通常用于配置应用程序的行为&#xff0c;例如指定数据库的连接字符串、API密钥、文件路径等。 Python提供了几种方法来设置和访问环境…

心电信号降噪方法(滤波器/移动平均/小波等,MATLAB环境)

对于一个正常的、完整的心动周期&#xff0c;对应的心电图波形如下图所示&#xff0c;各个波形都对应着心脏兴奋活动的生理过程&#xff0c;包含P波&#xff0c;PR段&#xff0c;QRS波群&#xff0c;ST段&#xff0c;T波&#xff0c;U波。 &#xff08;1&#xff09;P波心电图中…

OpenBMC相关的网站

openbmc官方网站 https://github.com/openbmchttps://github.com/openbmc Dashboard [Jenkins]https://jenkins.openbmc.org/ https://gerrit.openbmc.org/Gerrit Code Reviewhttps://gerrit.openbmc.org/ Searchhttps://grok.openbmc.org/ openbmc参考网站 https://www.c…

R实验 正交试验设计与一元线性回归分析

实验目的&#xff1a; 掌握正交试验设计记号的意义&#xff1b;掌握正交试验设计的直观分析和方差分析&#xff1b;掌握一元线性回归模型的相关概念&#xff1b;掌握最小二乘法的思想&#xff1b;掌握一元线性回归方程的显著性检验和预测。 实验内容&#xff1a; &#xff11;…

C++ day1 作业练习

整理思维导图 定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream> #include <cstring>using namespace std; namespace my_space {string s1; }void show() {cout<…

NASA数据集——严格校准的臭氧(O3)、甲醛(HCHO)、二氧化碳(CO2)和甲烷(CH4)混合比,以及包括三维风在内的气象数据

Alpha Jet Atmopsheric eXperiment Meteorological Measurement System (MMS) Data 阿尔法喷气式大气实验气象测量系统&#xff08;MMS&#xff09;数据 简介 Alpha Jet Atmospheric eXperiment (AJAX) 是美国国家航空航天局艾姆斯研究中心与 H211, L.L.C. 公司的合作项目&a…

SpringSecurity6从入门到实战之引言和基本概念

SpringSecurity6从入门到实战之引言和基本概念 前言 在当今数字化时代&#xff0c;随着网络应用的日益普及&#xff0c;保护用户数据和系统安全变得至关重要。作为Java开发社区的中坚力量&#xff0c;Spring框架提供了一整套解决方案来构建企业级应用程序。然而&#xff0c;随…

APM2.8飞控

ArduPilotMega 主控可应用于 固定翼、直升机、多旋翼、地面车辆 APM2.8飞控供电有两种 1.电流计供电&#xff0c; 2.带BEC&#xff08;稳压功能&#xff09;的电调供电 ArduPilotMega 内部的硬件结构图&#xff1a; 调试时&#xff0c;不要使用向导&#xff0c;由于向导功能不…

[GDB] GDB调试

目录 一 简介 二 功能: 三 命令: 四 调试准备: 五 开始调试: 5.1 添加断点&#xff1a; 5.2 条件编译 5.3 断点查看 5.4 断点删除: 5.5 查看源码 5.6 单步调试(逐过程)&#xff1a; 5.7 断点调试: 5.8 单步跟踪(逐语句): 5.9 调试过程&#xff1a; 5.9.1 开始调…

在CentOS 8上卸载与安装MySQL 8的详细步骤

关键词&#xff1a;MySQL 8安装、CentOS 8、YUM源配置、卸载MySQL、MySQL残留文件删除、首次登录MySQL临时密码、服务状态检查、MySQL社区服务器 阅读建议&#xff1a;本文适合需要在CentOS 8操作系统上部署最新MySQL 8数据库的系统管理员或开发者阅读。文中步骤简洁清晰&#…

ssm145基于java的电脑硬件库存管理系统+jsp

电脑硬件库存管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对电脑硬件库存信息管理混乱&…

【设计模式】创建型-抽象工厂模式

前言 在软件开发领域&#xff0c;设计模式是一种被广泛接受的解决方案&#xff0c;用于解决特定问题并提供可维护和可扩展的代码结构。抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是其中之一&#xff0c;它提供了一种方法来创建一系列相关或相互依赖的对象…

Linux 使用 yum安装 ELK服务,yum 安装elasticsearch和Kibana(未写完)

文章目录 环境准备ELK组件介绍安装Elasticsearch安装Kibana 丢弃下载ELK 服务安装包Elasticsearch安装 Tips:关闭elasticsearch https 环境准备 ELK组件介绍 ElasticSearch &#xff1a; 是一个近实时&#xff08;NRT&#xff09;的分布式搜索和分析引擎&#xff0c;它可以用…

PyQt6实战 | 绘图画板程序 自由绘制 直线 矩形 椭圆 画笔颜色和大小选择

引言 本文将介绍如何使用 PyQt6 创建一个简单的绘图应用程序。这个应用程序实现了常用的绘图功能&#xff0c;如自由绘制、画直线、矩形和椭圆。此外&#xff0c;还提供了选择画笔颜色、调整画笔宽度、清空画布和导出图像的功能。 环境设置 首先&#xff0c;需要安装 PyQt6&a…

OrangePi AIpro评测 - AI服务篇

0. 环境 ●OrangePi AIpro ●windows电脑 ●路由器 之前我已经对OrangePi AIpro进行了些嵌入式基本操作的评测。接下来进行AI部分。来看看华为昇腾的特别之处。 1.普通CPU和AI CPU 这里请提前用调试串口或者ssh到板子上&#xff0c;记得用户名和密码&#xff0c;分别是HwHiAiUs…

【Mybatis】映射文件获取新增记录的id

我们在讲JDBC的时候讲过在插入新数据值的时候需要获得到自动生成的那个主键id的值 ①获取PreparedStatement的对象的时候 PreparedStatement st conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS ); ②在执行SQL语句后 st.executeUpdate();ResultSet rs st.ge…

马斯克:AI时代人人高收入,不需要工作,商品服务不再短缺,可能性80%

当前人工智能现状和未来如何&#xff1f;AI时代下&#xff0c;人类未来会发生哪些变化&#xff1f; 埃隆马斯克&#xff08;Elon Musk&#xff09;在2024 VivaTech大会上分享了关于地球未来的诸多愿景。 投资作业本课代表摘录了其中的要点&#xff0c;分享给大家&#xff1a…

Golang的基本使用

目录 变量的声明 Golang常用容器 defer 有趣的多态 结构体标签和reflect 反射 Golang最强的协程 channel go可能造成的内存泄露 变量的声明 方法 1:有类型,有var,不赋值 在Golang中默认值为0 方法 2:无类型,有var,赋值 方法 3:无类型,无var,赋值 多变量声明 多变…

强大友好的Nginx扩展:VeryNginx

VeryNginx&#xff1a; 简化Web管理&#xff0c;增强网站防御- 精选真开源&#xff0c;释放新价值。 概览 VeryNginx是一个基于lua-nginx-module&#xff08;openresty&#xff09;的高效、友好的Nginx版本&#xff0c;专为满足现代Web应用的需求而设计。它不仅提供了强大的We…

spring-boot 3.2 + spring-boot-starter-quartz + HikariCP配置

第一步&#xff0c;添加 spring-boot-starter-quartz 的 maven 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> 第二步&#xff0c;在 ap…