[LeetCode]寻找两个正序数组的中位数

LeetCode 4. 寻找两个正序数组的中位数(多解法) 文章目录解法一:合并数组解法二:双指针解法三:二分解法三:进阶二分(划分数组) 解法一:合并数组 将两个数组合并后,直接根据下标找到中位数。时间复杂度O(m+n)O(m + n)O(m+n),空间复杂度 O(m+n)O(m + n)O(m+n) class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int n = nums1.length, m = nums2.length; 阅读详情

题目描述

  给定两个大小分别为 m 和 n 的 正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数 。算法的时间复杂度应该为 O(log (m+n)) 。

两种传统方法

  1. 使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。

  2. 不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 00 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

  上述的两种方法也能解决问题,并且容易想到,但是其时间复杂度不满足要求,这里不再解释和介绍。

二分思想分析问题

  分析上面的情形,对于两个数组,我们常规的思路是对两个数组分别设置两个指针,然后不断地移动指向较小数字的指针,指到找到中间位置。这个方法是逐个元素逐个元素的统计,直到找到中间位置。
  那么,我们能否找到一种方法,可以一批一批的统计元素,直到找到中间位置呢?答案是可以的。
  中位数的特点很清楚,给定一个数组,只要确定中间位置的索引,那么就可以确定中位数。但是现在是两个数组的中位数,不过其思想是相同的,即都是寻找指定位置。(偶数个元素需要寻找两个位置然后求平均值,奇数个元素需要寻找一个位置即可,就是中间位置)。现在我们的问题变成了:给定两个正序数组,寻找第 k 小的元素。
  对于这个问题,我们可以分别在两个数组左边获取一个 k2−1\frac{k}{2}-12k​−1 长度的子数组,这时会有下面的重要性质,请仔细体会一下:
  有两个数组:

[1,2,6,7,8,11,15]
[3,5,6,8,9,10,12,17,19]

  假设现在的 k = 10,得到的两个子数组(含有元素 k2−1\frac{k}{2}-12k​−1 个)如下:

[1,2,6,7]
[3,5,6,8]

  可以看出题目的意思是找到第 10 小的元素。
  可以看出两个子数组的最后一个元素 7 < 8,那么对于 7 这个子数组:

[1,2,6,7]

  一定是位于前 10 小的元素之中,为什么这么说?请想象一下,第一个数组中比 7 大的元素一定在 7 的右边,第二个数组中比 8 大的元素一定在 8 的右边,当然上述比 7 大的和比 8 大的都没有表示出来。那么谁一定比 7 小?当然是 7 左边的元素以及 7,因为每个数组的长度是 k2−1\frac{k}{2}-12k​−1,所以可以肯定含 7 的这个子数组可以移除了,现在的目标变成了从新的两个数组中寻找第 (10 - 4) 小的元素!
  上面的过程可以递归进行,不过需要注意终止条件:当目标变成寻找第 1 小的元素时,只需要返回两个数组中第一个元素的最小值即可。
  除此之外,还是需要一些问题要考虑,加入有两个数组:

[1]
[2,3,4,5,6,7,8]

   目的是寻找第 6 小的元素,显然需要取的子数组的大小是 k2−1=2\frac{k}{2}-1=22k​−1=2,此时明显超出了第一个数组的维度,这种情况下,将第一个数组取完即可,不必一定要取 k2−1\frac{k}{2}-12k​−1 大小,当然此时能够移去的元素数量也要具体情况具体分析了!
   到现在,事情还差一点就能完美了,还是上面的例子,在经历一步之后,变为下面的问题,从:

[]
[2,3,4,5,6,7,8]

   中找到第 5 小的元素,次数第一个元素已经为空,就不要在取 k2−1\frac{k}{2}-12k​−1 子数组了(提醒一下,现在的 k 是 5,不是 6 了!)问题本质上就是从一个正序数组中找到第 5 小的元素,直接返回就好了!

代码

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1 = nums1.size(),len2 = nums2.size();
        double res1 = findK(nums1,0,len1-1,nums2,0,len2-1,(len1+len2)/2+1);
        if((len1+len2)%2==1) return res1;
        else{
            double res2 = findK(nums1,0,len1-1,nums2,0,len2-1,(len1+len2)/2);
            return (res1+res2)/2.0;
        }
    }

    double findK(vector<int>& nums1,int start1,int end1,vector<int>& nums2,int start2,int end2,int K){
        // 处理越界问题
        if(start1>end1) return nums2[start2+K-1];
        if(start2>end2) return nums1[start1+K-1];

        // 终止条件
        if(K == 1) return nums1[start1]<nums2[start2]?nums1[start1]:nums2[start2];

        // 处理形如 [1;2,3,4,5,6,7] 的 K/2-1 越界问题
        if(start1+K/2-1>end1){
            int first = nums1[end1];
            int second = nums2[start2+K/2-1];   
            if(first <= second)
                return findK(nums1,end1+1,end1,nums2,start2,end2,K-end1-1);
            else
                return findK(nums1,start1,end1,nums2,start2+K/2,end2,K-K/2);
        }
        else if(start2+K/2-1>end2){
            int first = nums1[start1+K/2-1];
            int second = nums2[end2];   
            if(first <= second)
                return findK(nums1,start1+K/2,end1,nums2,start2,end2,K-K/2);
            else
                return findK(nums1,start1,end1,nums2,end2+1,end2,K-end2-1);
        }
        else{
            int first = nums1[start1+K/2-1];
            int second = nums2[start2+K/2-1];   
            if(first <= second)
                return findK(nums1,start1+K/2,end1,nums2,start2,end2,K-K/2);
            else
                return findK(nums1,start1,end1,nums2,start2+K/2,end2,K-K/2);
        }
    }
};
Leetcode 寻找两个正序数组的中位数 条件说明该怎么调nums1左边太多(或太大)i要往左缩,(else 情况)nums1左边太少(或太小)i要往右扩,满足找到了合法划分直接 return 中位数。 阅读详情

相关推荐

力扣(LeetCode)4. 寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组nums1 和nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 解法: public static double findMedianSortedArra..

安卓开发&音视频开发 2万+

(Java)leetcode-4 Median of Two Sorted Arrays(寻找两个正序数组的中位数)

二分查找

不思量 490

【Leetcode】4. 寻找两个正序数组的中位数

给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2。请你找出并返回这两个正序数组的中位数。算法的时间复杂度应该为Ologmn))。输入:nums1 = [1,3], nums2 = [2]输出:2.00000解释:合并数组 = [1,2,3] ,中位数 2输入:nums1 = [1,2], nums2 = [3,4]输出:2.50000解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5nu。

weixin_46153372的博客 1149

【解题笔记】leetcode寻找两个正序数组的中位数

文章目录问题转化解题步骤第一个条件:第二个条件:根据上述两个条件编码:极端情况:得到中位数注意完整代码 问题转化 首先,考虑只有一个有序数组的情况:寻找中位数的问题可以转化为寻找一条分割线,满足以下两个条件: 这条分割线在数组元素个素为奇数的时候,分割线左边的元素比右边多一个,中位数就是分割线左边的元素。 数组元素个数为偶数的时候,分割线左边的元素与右边的元素一样多。中位数是分割线左右两个元素的平均值。 下面考虑两个有序数组,我们可以在两个数组上都划分一条分割线,这两条分割线有以下两个条件 : 两条分

RRie1的博客 674

【力扣Leetcode题解系列之0004. Median of Two Sorted Arrays:寻找两个正序数组的中位数解题攻略】

本文介绍了力扣算法题"Median of Two Sorted Arrays"的解题方法。给定两个正序数组,要求在O(log(m+n))时间复杂度内找到它们的中位数。核心思路是使用二分查找,通过合理划分两个数组的位置,使得左半部分元素都小于右半部分。文章提供了C++和Go两种语言的实现代码,并分析算法的时间复杂度为O(log(m+n)),空间复杂度为O(1)。该解法充分利用二分查找的高效性,是解决这类问题的经典方法。

youngerwang的博客 536

【困难】力扣算法题解析LeetCode4:寻找两个正序数组的中位数

本文解决了在两个有序数组中寻找中位数的问题,要求在O(log(m+n))时间复杂度内完成。核心思路是将问题转化为寻找第k小的数,通过二分查找每次排除k/2个元素。实现时始终保持nums1为较短的数组以优化效率,处理各种边界情况,并动态更新查找范围。代码采用Java实现,包含详细注释和复杂度分析(O(log(min(m,n))))。测试用例覆盖了数组为空、元素相同、交叉数组等边界情况,确保算法正确性。

ylumwd的博客 782

leetcode 寻找两个正序数组的中位数

题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。 示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2 示例 2: 输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 =

m0_61802230的博客 417

告别‘火龙’:实测BES2800/RK2108等主流芯片,聊聊AI眼镜的功耗与散热‘内卷’实战

本文深入探讨了AI智能眼镜在功耗与散热方面的挑战,重点分析了恒玄BES2800和瑞芯微RK2108等主控芯片的能效表现。通过实测数据和优化策略,揭示了在6nm工艺、异构计算和系统级散热方案下的实战经验,为AI眼镜的功耗管理提供了实用解决方案。

weixin_30839881的博客 947

LeetCode 力扣: 寻找两个正序数组的中位数 (Javascript)

力扣 LeetCode (4.困难) 寻找两个正序数组的中位数

m0_73117087的博客 1631

OMNET++ INET框架学习教程(一)

在自组网学习的道路上摸石头过河,帮你快速入门OIMNET++平台下的INET框架。

NLDwangzhe的博客 6565

前沿数据解析 | 麻省理工-斯坦福-丰田研究中心电池数据集:AI驱动下的电池寿命早期预测

本文解析了麻省理工、斯坦福与丰田研究中心联合发布的电池数据集,展示了AI驱动下的电池寿命早期预测技术。通过分析124个商用锂离子电池的完整生命周期数据,研究团队仅用前100次循环数据即可准确预测电池报废时间,为电动汽车电池管理提供革命性解决方案。数据集包含LFP/石墨体系电池的详细测试记录,结合差分容量分析和梯度提升树模型,预测精度显著提升。

weixin_26950847的博客 530

力扣(leetcode)第4题寻找两个正序数组的中位数(Python)

最后,我写了一篇MySQL教程,里面详细的介绍了MySQL的基本概念以及操作指令等内容,欢迎阅读!解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5。输入:nums1 = [1,2], nums2 = [3,4]输入:nums1 = [1,3], nums2 = [2]解释:合并数组 = [1,2,3] ,中位数 2。请你找出并返回这两个正序数组的 中位数。的正序(从小到大)数组。算法的时间复杂度应该为。输出:2.00000。输出:2.50000。

qq_58737789的博客 1245

Proxmox VE网络配置踩坑实录:从Web界面无法访问到完美修复的全过程

本文详细记录了Proxmox VE服务器Web界面无法访问的完整排查与修复过程。作者从基础网络连通性测试入手,逐步排查了服务状态、SSL证书、端口监听、防火墙规则及网关配置,最终定位并解决了问题。文章提供了系统性的故障排查思路和实用的修复命令,对管理Proxmox VE网络具有重要参考价值。

weixin_29231221的博客 890

《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数

《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数详解

m0_56069910的博客 8879

成功解决安装cuda的时候,下载的文件自动消失,并且出现An unknown error has occurred

成功解决安装cuda的时候,下载的文件自动消失,并且出现An unknown error has occurred. 目录 解决问题 解决思路 解决方法 解决问题 安装cuda的时候,下载的文件自动消失,并且出现An unknown error has occurred. 解决思路 发生未知错误。 解决方法 很可能是因为当前电脑下载的cuda版本不适合当前电脑GPU支持的cuda版本! 推荐文章:CV:Win1..

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 7526

【一 扣子客户案例合集】【 1.3 识典古籍基于扣子智能助手的古籍数字化全流程技术解析】

古籍数字化智能处理系统全流程解析 本文详细介绍了基于扣子智能助手的古籍数字化解决方案,核心技术包括: 多层级架构设计:采用"云-边-端"三层次架构,整合高精度扫描设备与AI处理模块,实现从物理古籍到结构化数据的全流程自动化。 智能图像处理:通过12道预处理工序(包括畸变校正、污渍去除和对比度增强)处理古籍图像,采用改进的EAST算法和ViT模型实现高精度文字检测与识别,准确率达98.7%。 NLP增强处理:结合Transformer-XL预训练模型和N-gram语言模型进行文本校正,基于

商务合作|问题讨论|交流学习 请联系作者微信,加微信请务必注明来意,博客主页有联系方式 1442

LeetCode - 4 寻找两个正序数组的中位数

题目来源 4. 寻找两个正序数组的中位数 - 力扣(LeetCode) 题目描述 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。 示例 1 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2 示例 2 输入:nums1 = [1,2], nums2 = [3,4]

优快云 1075

【网络基础2】路由器的 “两扇门”:二层接口和三层接口到底有啥不一样?

家里的路由器背后总有几个网线接口,有的标着 “LAN”,有的标着 “WAN”;公司机房的路由器上,接口更是五花八门,有的插着网线,有的连着光纤,旁边还贴着 “GE0/0/1”“Eth-Trunk1” 这样的标签。你可能会想:不就是插网线的地方吗?有啥区别?其实,这些接口分 “二层接口” 和 “三层接口”,它们的作用差得远了 —— 就像你家的门,有的是 “小区内的单元门”(只通小区内部),有的是 “小区的大门”(能通往外面的世界)。接下来,咱们用大白话 + 生活例子,一点点把这两种接口讲透。

jundao1997的专栏 567

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

Leetcode 4. 寻找两个正序数组的中位数1、问题分析2、问题解决3、总结 1、问题分析 题目链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/submissions/ 具体思路是: 1、 根据两个数组的总长度计算是否是 奇数还是偶数, 2、然后和两个链表合并的思路类似   代码我已经进行了详细的注释,理解应该没有问题,读者可以作为参考,如果看不懂(可以多看几遍),欢迎留言哦!我看到会解答一下。 2、问题解决   笔者以

珍惜 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

力扣——寻找两个正序数组的中位数

合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5。4. 寻找两个正序数组的中位数 - 力扣(LeetCode)合并数组 = [1,2,3] ,中位数 2。请你找出并返回这两个正序数组的。的正序(从小到大)数组。算法的时间复杂度应该为。

2301_77433167的博客 477

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

力扣LeetCode第4题寻找两个正序数组的中位数

力扣LeetCode第4题寻找两个正序数组的中位数

weixin_44061444的博客 728

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

力扣热门100题 - 4.寻找两个正序数组的中位数

力扣刷题记录

zxwyhzy的博客 924

力扣-4-寻找两个正序数组的中位数

剩下两个数组长度不一致,此时判断B2 > C1 则B2为第五小,否则排除B2两个数组调用函数一得到的上中位数即为第五小。(因为排除A2、B2,再调用函数一得到第三小,即1+1+3=5)因为只排除掉4个数,剩余两个数组长度为3,调用函数一后获取的上中位数为第3小,4 + 4 = 7 小于8,所以两个数组都排除掉一个最小数,此时4 + 2 + 2 = 8;k取2,两个数组都取2个数,调用函数一得到的上中位数即第二小的数。k取8,D2至多第七小,所以排除A2、B2、C2、D2;

lan_jianwen的博客 513

力扣4.寻找两个正序数组的中位数(java)

力扣4.寻找两个正序数组的中位数题目思路代码 LeetCode笔记汇总 题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2 示例 2: 输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3)

k_surge的博客 1459
上一篇: C++ 虚继承和多态性
Aaron__Peng
博客等级 码龄7年 0粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值