leetcode算法每天一题004: 寻找两个正序数组的中位数

4.寻找两个正序数组的中位数 python 要找到两个正序数组的中位数,并且要求时间复杂度为 (O(\log(m+n))),可以使用二分查找的方法。通过这种方法,我们可以在 (O(\log(m+n))) 的时间复杂度内找到两个正序数组的中位数。解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5。输入:nums1 = [1,2], nums2 = [3,4]输入:nums1 = [1,3], nums2 = [2]算法的时间复杂度应该为 O(log (m+n))。解释:合并数组 = [1,2,3] ,中位数 2。 阅读详情

题目描述

  • 寻找两个正序数组的中位数
  • 时间复杂度应该为 O(log (m+n))
  • 要求复杂度为log(m+n),常见的一维问题 logn复杂度的算法 多为 二分查找的变形
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

暴力解法(不可行)

  • 通常的想法是可以将两个数组通过两个循环合并起来,然后找到其k/2位置的值即可。但这样的作法会使时间复杂度变为O(m+n)。
  • 目标是寻找k/2位置的数值,可以考虑将二分法(二分,每次选择一半的方法)的变形用上

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

非暴力解法

C++

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size() + nums2.size();
        if(n%2==0){
            int left = find(nums1,0,nums2,0,n/2);
            int right = find(nums1,0,nums2,0,n/2 +1 );
            return (left+right)/2.0;
        }else{// 奇数个数值的情况
            return find(nums1,0,nums2,0,n/2 +1 );//返回一半的右侧值
        }
    }
    // i , j为开始查找位置的索引  k为从索引开始向下查找几个数值
    int find(vector<int>& nums1 , int i , vector<int>& nums2 ,int j ,int k){
        // 在查找之前先进行判断,  !!! 保持nums2数组的长于nums1 !!!
        if(nums1.size() -i > nums2.size() -j){
            return find(nums2 , j, nums1,i,k);
        }

        if(nums1.size() == i) return nums2[j+k-1];//特殊情况

        if(k == 1) return min(nums1[i],nums2[j]);//终止条件

        // 向前移动K/2
        int idx1 = min(i + k/2,(int)nums1.size());//加上min防止overflow
        int idx2 = j + k - k/2;// ind2查找的长度可能多一个

        //二分法,选择在那个数组的基础上 移动这k/2的距离
        if(nums1[idx1 -1]< nums2[idx2 -1]){// 因为k代表的是第几个所以需要减1
            return find(nums1,idx1,nums2,j, k-(idx1 -i));
        }else{
            return find(nums1,i,nums2,idx2, k-(idx2 -j));
        }



    }
};

JAVA

PYTHON

更多

这道题让我们求两个有序数组的中位数,而且限制了时间复杂度为O(log (m+n)),看到这个时间复杂度,自然而然的想到了应该使用二分查找法来求解。那么回顾一下中位数的定义,如果某个有序数组长度是奇数,那么其中位数就是最中间那个,如果是偶数,那么就是最中间两个数字的平均值。这里对于两个有序数组也是一样的,假设两个有序数组的长度分别为m和n,由于两个数组长度之和 m+n 的奇偶不确定,因此需要分情况来讨论,对于奇数的情况,直接找到最中间的数即可,偶数的话需要求最中间两个数的平均值。为了简化代码,不分情况讨论,我们使用一个小trick,我们分别找第 (m+n+1) / 2 个,和 (m+n+2) / 2 个,然后求其平均值即可,这对奇偶数均适用。加入 m+n 为奇数的话,那么其实 (m+n+1) / 2 和 (m+n+2) / 2 的值相等,相当于两个相同的数字相加再除以2,还是其本身。

这里我们需要定义一个函数来在两个有序数组中找到第K个元素,下面重点来看如何实现找到第K个元素。首先,为了避免产生新的数组从而增加时间复杂度,我们使用两个变量i和j分别来标记数组nums1和nums2的起始位置。然后来处理一些边界问题,比如当某一个数组的起始位置大于等于其数组长度时,说明其所有数字均已经被淘汰了,相当于一个空数组了,那么实际上就变成了在另一个数组中找数字,直接就可以找出来了。还有就是如果K=1的话,那么我们只要比较nums1和nums2的起始位置i和j上的数字就可以了。难点就在于一般的情况怎么处理?因为我们需要在两个有序数组中找到第K个元素,为了加快搜索的速度,我们要使用二分法,对K二分,意思是我们需要分别在nums1和nums2中查找第K/2个元素,注意这里由于两个数组的长度不定,所以有可能某个数组没有第K/2个数字,所以我们需要先检查一下,数组中到底存不存在第K/2个数字,如果存在就取出来,否则就赋值上一个整型最大值。如果某个数组没有第K/2个数字,那么我们就淘汰另一个数字的前K/2个数字即可。有没有可能两个数组都不存在第K/2个数字呢,这道题里是不可能的,因为我们的K不是任意给的,而是给的m+n的中间值,所以必定至少会有一个数组是存在第K/2个数字的。最后就是二分法的核心啦,比较这两个数组的第K/2小的数字midVal1和midVal2的大小,如果第一个数组的第K/2个数字小的话,那么说明我们要找的数字肯定不在nums1中的前K/2个数字,所以我们可以将其淘汰,将nums1的起始位置向后移动K/2个,并且此时的K也自减去K/2,调用递归。反之,我们淘汰nums2中的前K/2个数字,并将nums2的起始位置向后移动K/2个,并且此时的K也自减去K/2,调用递归即可。

class Solution {
  public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int left = (m + n + 1) / 2;
        int right = (m + n + 2) / 2;
        return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;
    }
    //i: nums1的起始位置 j: nums2的起始位置
    public int findKth(int[] nums1, int i, int[] nums2, int j, int k){
        if( i >= nums1.length) return nums2[j + k - 1];//nums1为空数组
        if( j >= nums2.length) return nums1[i + k - 1];//nums2为空数组
        if(k == 1){
            return Math.min(nums1[i], nums2[j]);
        }
        int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;
        int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;
        if(midVal1 < midVal2){
            return findKth(nums1, i + k / 2, nums2, j , k - k / 2);
        }else{
            return findKth(nums1, i, nums2, j + k / 2 , k - k / 2);
        }        
    }
}
Leetcode 寻找两个正序数组的中位数 条件说明该怎么调nums1左边太多(或太大)i要往左缩,(else 情况)nums1左边太少(或太小)i要往右扩,满足找到了合法划分直接 return 中位数。 阅读详情

相关推荐

【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

4. 寻找两个有序数组的中位数——今天算是捡起leetcode 重新刷起来吧!!!!

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 示例 1: nums1 = [1, 3] nums2 = [2] 则中位数是 2.0 示例 2: nums1 = [1, 2] nums2 = [3, 4] 则中位数是 (2 + 3...

JStana的博客 784

【eNSP 华为模拟器】小型校园网模拟环境的设计与配置(附eNSP源文件)

【eNSP 华为模拟器】小型校园网模拟环境的设计与配置 一、实验概述 二、交换机的配置 2.1 二层交换机的配置 2.2 三层交换机的配置 三、路由器的配置 四、实验结果 五、实验总结 一、实验概述 按照以下的拓扑连接,自行设计VLAN和IP地址等网络参数,实现PC1到PC2的IP通信。其中,R1,R2为路由器;LSW1,LSW4为3层交换机;LSW2,LSW3 ,LSW6, LSW7为2层交换机;CLIENT1-CLIENT12为PC机。 拓扑图 课程设计要求:(1)IP地址自行规划设计,应该清晰地

qq_43757282的博客 4万+

Leetcode 1046. 最后一块石头的重量

优先队列

xiaohukuzai的博客 488

Linux系统下Materials Studio 2020安装避坑指南:从依赖包到许可证配置全流程

本文提供了一份在Linux系统上安装Materials Studio 2020的深度避坑指南。详细解析了从系统依赖包检查、安装流程、许可证配置到Gateway服务部署的全过程,并分享了与Slurm作业调度系统集成的实战经验,旨在帮助用户高效、稳定地完成部署。

weixin_29313547的博客 387

Token验证绕过 靶场实战

实验介绍 1.漏洞简介 在Web领域基于Token的身份验证随处可见。在大多数使用Web API的互联网公司中,tokens 是多用户下处理认证的最佳方式。 具有以下几点特性: 1)无状态、可扩展 2)支持移动设备 3)跨程序调用 4)安全 2.原理基于Token的验证原理 基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。 NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是...

weixin_54771278的博客 2251

LeetCode/Java刷题----数组及字符串专题

Java刷题,数组及字符串专题

qq_43621439的博客 1038

SAM2与Docker的完美组合:5分钟搞定Linux环境下的图像分割部署

本文详细介绍了如何在Linux环境下通过Docker快速部署SAM2图像分割模型,解决安装过程中的常见问题。文章提供了从镜像选择、CUDA版本匹配到容器构建的全流程指南,特别针对GPU加速环境下的'cudnn_frontend: No execution plans support the graph'等报错提供了实用解决方案,帮助开发者在5分钟内完成高效部署。

fern8的博客 933

leetcode---Java中数据类型的定义及算法中常用方法

定义一个map Map<Integer,TreeNode> parent = new HashMap<Integer,TreeNode>(); 定义一个set Set<Integer> visited = new HashSet<Integer>(); 定义一个list List<TreeNode> list = new ArrayList<TreeNode>(); 定义栈 Deque<TreeNode> stack =

qq_39091546的博客 270

光耦选型避坑指南:如何根据CTR参数精准计算输入输出电阻(附24V工业场景实例)

本文深入解析光耦选型核心,聚焦电流传输比(CTR)参数及其衰减特性,提供从输出需求反向推导输入输出电阻的精准计算方法。文章以24V工业场景为例,结合光电耦合器数据手册,详细阐述了如何根据CTR最小值进行降额设计,并给出包含反接保护、TVS管等在内的完整保护电路方案,旨在构建高可靠、长寿命的信号隔离电路,避免因选型或设计不当导致的系统故障。

nept的博客 1040

智启古文字新章:AI、ML与大数据驱动的知识图谱构建

摘要:本文聚焦AI、ML与大数据驱动的古文字知识图谱构建。开篇点明古文字研究困境,凸显技术革新迫切性。随后阐释AI、ML、大数据基础概念,详解其在图谱构建里的数据采集、知识抽取、关系挖掘运作流程,穿插线性代数、概率论等数学原理。实战展示殷商甲骨文图谱搭建全程,含数据处理、模型训练。还探讨跨模态融合等前沿挑战应对,兼述技术融合衍生的教育科普革新、伦理文化责任、国际合作交流,勾勒古文字数字永生的长远愿景。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1615

Java实现Leetcode题(数组)

Leetcode704(二分查找)Leetcode27(移除数组)Leetcode997(有序数组的平方)Leetcode209(长度最小的子数组)Leetcode59(螺旋矩阵II)

weixin_47059164的博客 125

使用Matlab simulink的PLC coder功能进行算法搭建与处理

使用的案例如下: Anti-Windup PID Control Demonstration with Feedforward Control 将其中的PID块生成SCL语言再导入TIA 使用的平台如下: Matlab 2019b TIA portal 15.1 应用:可以在PLC中搭载一些并不方便使用的,或者比较难使用的算法 步骤如下: 首先打开案例,案例地址我放在最下面,点击Run运行仿真,必...

苦走一口田 1万+

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

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

m0_56069910的博客 8879

第四天 Labview交互也很轻松(4.1 DAQ数据采集)

LabVIEW DAQ数据采集有很大的优势,NI提供了超过5千万条I/O通道,支持多种主流总线(如USB、PCI、PCIe、PXI等),并为所有这些设备提供统一的编程接口,实现软硬件的无缝集成。LabVIEW包含全套范例,覆盖各类应用,用户无需从头创建整个数据采集系统,可以快速启动并执行这些范例程序。所有NI DAQ硬件都采用NI-DAQmx驱动程序,支持多种编程语言,并包含了这些编程语言的示例代码,使得与NI硬件的通信变得更加便捷。

weixin_38637405的博客 2617

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

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

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

珍惜 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

LeetCode第四题:寻找两个正序数组的中位数(Java)

题目:寻找两个正序数组的中位数 给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2。请你找出并返回这两个正序数组的中位数。 示例: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2 方法一:合并成一个数组,找中间数。 不考虑最优解的情况下,第一反应就是这个思路。 public static double findMedianSortedArrays(int[] num...

巨坑的菜比的博客 4665

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

寻找两个正序数组的中位数-LeetCode(Java)   ​ 寻找两个正序数组的中位数-LeetCode(Java) 题目:4. 寻找两个正序数组的中位数 给定两 分析:     1.暴力解法      (1)思路:      (2)代码:     2.进阶:归并排序      (1)思路:      (2)代码:     3.二分查找      (1)思路:      (2)代码      4.划分数组      (1)思路:      (2)代码

m0_60416689的博客 1617

【力扣高频题】004.两个正序数组的中位数

如何寻找两个有序但不一定等长的数组中第 K 小的数的方法

weixin_46879314的博客 1035

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

个元素一定是小于我们目标值的,因此可以排除这一段(如上图中灰色部分),在剩余元素中继续寻找第(3. 如果某个数组完全被排除掉了,则直接在剩余的另一个数组中定位目标元素即可。题目给出的条件都用上了,时空复杂度也得到了提升,但仍然不符合题目要求的。1. 如果k=1, 则首先比较两个数组首位元素,取最小的一个。(对于长度为偶数的情况,需要寻找两次,并取平均值)智谱清言给出了一种新的解法,划分数组二分法。合并成一个新数组,然后sort,取中位数。接下来,人生苦短,我用Python~个元素,较小的一个数组中的第1~

zaishaoyi的专栏 1172

算法-寻找两个正序数组的中位数

题目:4.寻找两个正序数组的中位数(LeetCode)问题描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2,请找出并返回这两个正序数组的中位数。其中要注意算法的时间复杂度应该为O(log(m+n))。

旗木白哉のblog 1092

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

【LeetCode】寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 694

LeetCode【0004】寻找两个正序数组的中位数

题目难度:困难;数据结构:数组;应用算法:二分查找。

AnFany 1473

Leetcode 004. 寻找两个正序数组的中位数 | 每日一题

给定两个大小为 m 和 n 的正序(从小到大)数组 `nums1` 和 `nums2`。请你找出并返回这两个正序数组的中位数。 **进阶:**你能设计一个时间复杂度为 `O(log (m+n))` 的算法解决此问题吗?

画漫画的程序员∙苏南 1326
上一篇: leetcode算法每天一题003:无重复字符的最长子串(max函数,滑动窗口+set)
下一篇: leetcode算法每天一题005:最长回文子串
FakeOccupational
博客等级 码龄6年 2万+粉丝 1727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值