Leetcode:寻找两个正序数组的中位数

题目链接:4. 寻找两个正序数组的中位数 - 力扣(LeetCode)

题目分析

1、当只有一个有序数组时,该数组的中位数会将该数组分为两份:左子数组 和 右子数组

2、当有两个有序数组时, 我们仍然可以通过一条分隔线将两个数组分割,要求如下(前面两个是一个条件分开来写的,最后一个是一个条件,我们找到的分割线一共要满足两个条件)

  1. 两数组长度和为偶数时:分割线左右两侧元素个数相同
  2. 两数组长度和为奇数时:分割线左侧元素个数比右侧多一
  3. 分割线左侧的所有元素的数值 <= 分割线右侧所有元素的数值(交叉情况)
  • 不理解为什么要这样设置的,再想想中位数的定义,以及我们提供的数组是什么数组
  • 这样是为了确保中位数一定只与分割线两侧的元素有关,我们需要确定这条红线的位置

3、 假设两个有序数组的长度分别为m和n(这样计算可以保证分割线的第一个条件)

  • m+n为偶数时:分割线左侧元素个数为 = (m + n)/ 2 
  • m+n为奇数时:分割线左侧元素个数为 = (m + n + 1)/ 2 (因为我们之前规定中位线位于分割线左侧,所以分割线左侧元素个数要比右侧元素个数多一)
  • /是向下取整,故m+n为偶数时的计算式也可以变为(m + n + 1)/ 2,因此无论两个有序数组的长度和是奇数还是偶数,它们分割线左侧的元素个数均为(m + n + 1)/ 2

 4、只有一个有序数组时,分割线一定满足左侧所有元素 <= 右侧所有元素,但是在两个不同的有序数组的情况下不一定是这样的,我们需要对分割线进行适当调整(交叉情况)

  • 在代码中我们直接将最短的数组设置为第一个数组,因此不会存在第二个问题 

5、 由于我们需要访问分割线左右两侧的元素,因此如果某个数组过短或者两数组相等时,再去访问分割线两侧元素可能会导致越界访问的问题

  • 一个数组过短

  • 当两个数组长度相等时

补充:

1、分割线在第1个数组右边的第1个元素的下标i = 分割线在第1个数组左边的元素个数

2、分割线在第2个数组右边的第1个元素的下标j = 分割线在第2个数组左边的元素个数

普通版本(二分查找)

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {if (nums1.size() > nums2.size())  //保证数组1一定最短{swap(nums1,nums2);}int m = nums1.size();int n = nums2.size();//两个数组分割线左侧所有的元素个数(分割线第一条件)int totalLeft = (m+n+1)/2;//在第一个数组[0,m]中寻找满足第二条件的分割线://第一个数组分割线左侧的数值 <= 第二个数组分割线右侧的数值 且 第二个数组分割线左侧的数值 <= 第一个数组分割线右侧的数值 //nums1[i - 1] <= nums2 [j] && nums2[j - 1] <= nums1[i](分割线第二条件)//提示1:分割线在第1个数组右边的第1个元素的下标i = 分割线在第1个数组左边的元素个数//提示2:分割线在第2个数组右边的第1个元素的下标j = 分割线在第2个数组左边的元素个数int left = 0;//第一个数组的左边界int right = m;//第一个数组的右边界//由于已提前将最短数组固定为nums1,所以在移动查找时候,i只会右移,j只会左移//循环查找while(left <right){int i = (left + right + 1)/ 2;//开始时先取一个中间位置的下标作为第一次的iint j = totalLeft - i;//第一个数组分割线左边的数有i个,两个数组分割线左侧的数有totalLeft个,totalLeft - i得到第二个数组分割线左侧的数的个数j//如果条件不满足就移动缩小判断范围(left右移或者right左移)if(nums1[i - 1] > nums2[j]) //如果第一个数组分割线左侧的数值大于第二个数组分割线右侧的数值,right左移一位,即分割线左移{right = i - 1;//下一轮的搜索区间为[left,i - 1]}else如果第一个数组分割线左侧的数值小于第二个数组分割线右侧的数值,left向右移动,即分割线右移{//下一轮的搜索区间为[i,right]left = i ;}}//循环结束表示已经在第一个数组中找到了合适的分割线int i = left;//i此时表示第一个数组中分割线右侧数值的下标int j = totalLeft - i;//j此时表示第二个数组中分割线右侧数值的下标int nums1LeftrMax = (i == 0 ? INT_MIN : nums1[i-1]);//两个数组长度相同时,第一个数组的分割线左侧的值不能被使用,第一个数组分割线左侧的数值设为整型最小值int nums1RightMin = (i == m ? INT_MAX : nums1[i]);//两个数组长度相同时,第一个数组的分割线右侧的值不能被使用,第一个数组分割线右侧的数值设为整型最大值int nums2LeftrMax = (j == 0 ? INT_MIN : nums2[j-1]);//两个数组长度相同时,第二个数组的分割线左侧的值不能被使用,第二个数组分割线左侧的数值设为整型最小值int nums2RightMin = (j == n ? INT_MAX : nums2[j]);//两个数组长度相同时,第二个数组的分割线左侧的值不能被使用,第二个数组分割线右侧的数值设为整型最大值//到这里,已经获取了两个数组分割线左右两侧的数值if((m+n) % 2 == 1) //两数组总长度为奇数时,获取的是两数组分割线左侧两个数的最大值{return max(nums1LeftrMax,nums2LeftrMax);}else//两数组总长度为偶数时,获取的是两数组分割线左侧两个数的最大值和分割线右侧两个数的最小值的平均值{return ((max(nums1LeftrMax,nums2LeftrMax) + min(nums1RightMin,nums2RightMin)) / 2.0);//整数 / 浮点数 = 浮点数,整数 / 整数 = 整数}}
};

问题1:int right = m; 为什么不是 m-1

        在二分查找中,right 的初始化为 m 而不是 m-1 是因为我们需要包括所有可能的分割线位置,包括数组的末尾。对于一个数组 numsm 是数组的长度,nums[m] 是有效的位置(\0)

  • 初始化 left = 0right = m 意味着我们在 [0, m] 范围内寻找分割线位置。
  • 如果初始化 right = m-1,则会遗漏数组的末尾分割位置,这是不正确的

问题2:/2.0/2 的区别

        在计算中位数时,为什么要使用 /2.0 而不是 /2,这是因为 2.0 是一个浮点数,使用浮点数除法可以确保结果是浮点数,而 /2 是整数除法,会丢失小数部分:

double result = (max(nums1LeftMax, nums2LeftMax) + min(nums1RightMin, nums2RightMin)) / 2.0;
  • /2.0 会进行浮点数除法,确保结果是 double 类型
  • /2 是整数除法,如果被除数是整数,则结果会是整数,丢失小数部分,导致计算不准确

 

~over~

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

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

相关文章

社区供稿丨GPT-4o 对实时互动与 RTC 的影响

以下文章来源于共识粉碎机 &#xff0c;作者AI芋圆子 前面的话&#xff1a; GPT-4o 发布当周&#xff0c;我们的社区伙伴「共识粉碎机」就主办了一场主题为「GPT-4o 对实时互动与 RTC 的影响」讨论会。涉及的话题包括&#xff1a; GPT-4o 如何降低延迟&#xff08;VAD 模块可…

LabVIEW中进行步进电机的位置控制

在LabVIEW中进行步进电机的位置控制&#xff0c;通常涉及以下几个关键步骤&#xff1a;设置硬件、配置通信、编写控制算法和实施反馈控制。以下是一个详细的介绍。 硬件设置 步进电机&#xff1a;选择合适的步进电机&#xff0c;根据负载和应用需求选择适当的步数和转矩。 驱…

FL Studio21.2.8中文版让你的音乐创作如鱼得水

在音乐的世界里&#xff0c;我们都是探索者&#xff0c;追求着无尽的创新和可能性。而在这个过程中&#xff0c;我们往往会遇到各种挑战和困扰。如何快速高效地创作出满意的音乐作品&#xff1f;如何将我们的创意完美地呈现出来&#xff1f;这些问题可能一直困扰着你。今天&…

成都欣丰洪泰文化传媒有限公司助力品牌快速崛起

在当今数字化浪潮汹涌的时代&#xff0c;电商行业作为新经济的代表&#xff0c;正以其独特的魅力和无限的潜力&#xff0c;引领着商业模式的创新与变革。在这个充满机遇与挑战的领域里&#xff0c;成都欣丰洪泰文化传媒有限公司凭借其专业的电商服务能力和前瞻性的战略眼光&…

如何在.htaccess文件创建一个自定义404页面

本周有一个客户&#xff0c;购买Hostease的虚拟主机&#xff0c;询问我们的在线客服&#xff0c;如何在.htaccess文件创建一个自定义404页面&#xff1f;我们为用户提供相关教程&#xff0c;用户很快解决了遇到的问题。在此&#xff0c;我们分享这个操作教程&#xff0c;希望可…

MVC和MVVM

MVC Model层&#xff1a;用于处理应用程序数据逻辑的部分&#xff0c;通常负责在数据库中存取数据 View&#xff08;视图&#xff09;处理数据显示的部分。通常视图是依据模型数据创建的 Controller&#xff08;控制器&#xff09;是处理用户交互的部分。通常控制器负责从视…

从零开始学Vue3--环境搭建

1.搭建环境 下载nodejs nodejs下载地址 更新npm npm install -g npm 设置npm源&#xff0c;加快下载速度 npm config set registry https://registry.npmmirror.com 使用脚手架创建项目 npm create vuelatest 根据你的需要选择对应选项 进入新建的项目下载依赖 npm in…

Tasker+SendSilentMail实现钉钉自动打卡

Tasker 允许用户根据自定义的“配置文件”(Profiles)&#xff0c;在特定的“背景”(Contexts)下&#xff0c;执行指定的“任务”(Tasks)。以下是关于Tasker的详细介绍&#xff1a; 强大的自定义能力&#xff1a;用户可以根据自己的需求&#xff0c;创建各种配置文件和任务&…

【BUG】流式响应requests得到: ping - 和时间戳

前情提要 运行Langchain-Chatchat项目&#xff0c;使用自定义请求访问API Server流式输出 报错展示 b: ping - 2024-05-22 00:46:04.83252000:00\r\n\r\n报错原因 这通常是由于 Server-Sent Events (SSE) 实现中使用的“心跳”机制&#xff0c;以确保连接保持活跃。一些 SSE…

Java 在Word文档中添加、删除页面

在排版或者编辑Word文档时&#xff0c;可能会需要增加新页面或删除某个已有页面&#xff0c;以便更好地呈现内容。下面将介绍如何使用国产Java控件来实现在Word文档中增删页面的功能。 目录 Java 在Word文档末尾新增一页 Java 在Word文档指定位置插入一页 Java 删除Word文档…

百度ERNIE系列预训练语言模型浅析(4)-总结篇

总结&#xff1a;ERNIE 3.0与ERNIE 2.0比较 &#xff08;1&#xff09;相同点&#xff1a; 采用连续学习 采用了多个语义层级的预训练任务 &#xff08;2&#xff09;不同点&#xff1a; ERNIE 3.0 Transformer-XL Encoder(自回归自编码), ERNIE 2.0 Transformer Encode…

用Python实现办公自动化

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

洗地机什么品牌质量好?家用洗地机排行榜

一年一度的大促节又到了&#xff0c;各大电商平台和实体店纷纷推出力度不小的折扣活动&#xff0c;吸引着消费者的关注和购买欲望。很多家庭也趁着这个机会&#xff0c;购置一些智能家居产品来提升生活品质。其中&#xff0c;洗地机作为近年来发展迅速的明星产品&#xff0c;受…

Redis篇 哈希表在redis中的命令

哈希命令 一.哈希表的基本认识二. 哈希表在redis中的命令1.hset,hget2.hdel3.hkeys,hvals4.hexists5.hgetall6.hmget7.hlen8.hincrby和hincrbyfloat 一.哈希表的基本认识 在JAVA数据结构中&#xff0c;我们就已经接触到了哈希表&#xff0c; 在当时&#xff0c;我们主要用到的哈…

React18 apexcharts数据可视化之折线图

基础折线图 import ApexChart from react-apexcharts;export function Basic() {// 数据序列const series [{name: "Desktops",data: [10, 41, 35, 51, 49, 62, 69, 91, 148]},]// 图表选项const options {// 图表chart: {height: 650,type: line,zoom: {enabled:…

springboot发送短信验证码,结合redis 实现限制,验证码有效期2分钟,有效期内禁止再次发送,一天内发送超3次限制

springboot结合redis发送短信验证码,实现限制发送操作 前言(可忽略)实现思路正题效果图示例手机号不符合规则校验图成功发送验证码示例图redis中缓存随机数字验证码&#xff0c;2分钟后失效删除redis缓存图验证码有效期内 返回禁止重复发送图验证码24小时内发送达到3次&#xf…

【Leetcode 206】 反转链表——此递归相当妙啊

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a; …

【机器学习300问】105、计算机视觉(CV)领域有哪些子任务?

计算机视觉作为人工智能的重要分支&#xff0c;发展至今已经在诸多领域取得显著的成果。在众多的计算机视觉任务中&#xff0c;图像分类、目标检测与定位、语义分割和实例分割是四个基本而关键的子任务&#xff0c;它们在不同的应用场景下扮演着重要角色。这四个子任务虽然各具…

深入理解JVM:内存结构、垃圾收集与性能调优

目录 JDK、JRE、JVM关系? 启动程序如何查看加载了哪些类&#xff0c;以及加载顺序? class字节码文件10个主要组成部分? JVM结构 画一下JVM内存结构图 程序计数器 Java虚拟机栈 本地方法栈 Java堆 方法区 运行时常量池? 什么时候抛出StackOverflowError? 例如&…

海医大三院使用先进血管外科微创技术成功救治危重主动脉夹层患者

近日,上海东方肝胆外科医院血管外科周建教授团队采用主动脉弓分支型一体化移植物联合体外开窗技术,成功救治复杂危重主动脉夹层患者,为上海嘉定首例,彰显了上海东方肝胆外科医院血管外科的优势与特色。 患者谢先生,72岁,两周前突发剧烈胸背部撕裂样疼痛,休息后症状未能得到缓解…