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

news2024/9/23 7:33:48

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

  • 1. 题目描述
  • 2.详细题解
  • 3.代码实现
    • 3.1 Python
    • 3.2 Java

1. 题目描述

题目中转:4. 寻找两个正序数组的中位数
在这里插入图片描述
在这里插入图片描述

2.详细题解

   两个有序数组,寻找二者的中位数,最直观的方法是先归并这两个数组为一个有序数组,中位数则为中间的数字,算法时间复杂度为 O ( l o g ( m + n ) ) O(log(m+n)) O(log(m+n)),具体代码实现见Python方法一。
  要求时间复杂度不大于 O ( l o g ( m + n ) ) O(log (m+n)) O(log(m+n))时间复杂度,首先肯定不能先归并两个数组了,两个数组均有序,应当充分运用这个条件。
  思考什么是中位数?通俗的说,即将数据一分为二,且其中一个集合中数据最大值小于等于另一个集合中数据的最小值。
  中位数性质已经很明晰。因此,对于题目中的两个数组,相当于要在数组 1 1 1(长度为 m m m)和数组 2 2 2(长度为 n n n)中分别寻找一个位置 i i i j j j,将两个数组一分为二,两个数组的左半部分构成一个集合,右半部分构成另一个集合。 i i i j j j的取值范围分别为 [ 0 , m ] [0, m] [0,m] [ 0 , n ] [0,n] [0,n],此时左集合和右集合的元素个数应满足如下关系:
   i + j = m − i + n − j i+j = m -i + n - j i+j=mi+nj 或者 i + j = m − i + n − j + 1 i+j = m -i + n - j + 1 i+j=mi+nj+1
  上述等式分别表示 m + n m+n m+n为偶数和奇数的情况,推导可得:
   i + j = ( m + n ) / 2 i + j= (m+n)/2 i+j=(m+n)/2 i + j = ( m + n + 1 ) / 2 i + j= (m+n+1)/2 i+j=(m+n+1)/2,二者可合并为 i + j = ( m + n + 1 ) / 2 i + j= (m+n+1)/2 i+j=(m+n+1)/2,仅保留整数结果。
  进一步可得 j = ( m + n + 1 ) / 2 − i j = (m+n+1)/2 - i j=(m+n+1)/2i,因为 i i i j j j的取值范围分别为 [ 0 , m ] [0, m] [0,m] [ 0 , n ] [0,n] [0,n],因此 m < = n m<=n m<=n时该等式成立,否则当 i = m i=m i=m时,显然不能均分该两个数组,因此应首先判断两个数组的长度,将长度更小的数组作为第一个数组
  接下来进行二分条件分析,对于第一个数组,取中间值为 i = ( l e f t + r i g h t ) / / 2 i=(left+right)//2 i=(left+right)//2,则左边界值为 n u m s 1 [ i − 1 ] nums1[i-1] nums1[i1],右边界值为 n u m s 1 [ i ] nums1[i] nums1[i];随之确定第二个数组的分割为 j j j,左边界值为 n u m s 2 [ j − 1 ] nums2[j-1] nums2[j1],右边界值为 n u m s 2 [ j ] nums2[j] nums2[j],此时 n u m s 1 [ i − 1 ] < = n u m s 1 [ i ] nums1[i-1]<=nums1[i] nums1[i1]<=nums1[i] n u m s 2 [ j − 1 ] < = n u m s 2 [ j ] nums2[j-1]<=nums2[j] nums2[j1]<=nums2[j]肯定是成立的(因为有序),因此我们需要确定一个 i i i,使如下等式成立:

n u m s 1 [ i − 1 ] ≤ n u m s 2 [ j ] 且 n u m s 2 [ j − 1 ] ≤ n u m s 1 [ i ] nums1[i−1]≤nums2[j] 且 nums2[j−1]≤nums1[i] nums1[i1]nums2[j]nums2[j1]nums1[i]

  但该条件等于仅需等价于寻找最大的 i i i使得如下等式成立,因为随着 i i i递增, j j j是减小的,若 i i i是最大的,说明 i + 1 i+1 i+1不成立,此时有 n u m s [ i ] > n u m s 2 [ j − 1 ] nums[i]>nums2[j−1] nums[i]>nums2[j1].

nums1[i-1]<=nums2[j]$

  因此二分条件判断如下:

n u m s 1 [ i − 1 ] < = n u m s 2 [ j ] nums1[i-1] <= nums2[j] nums1[i1]<=nums2[j]成立,此时说明 i i i可能不是最大值,可进一步探索, l e f t = i + 1 left = i + 1 left=i+1
否则,即 n u m s 1 [ i − 1 ] > n u m s 2 [ j ] nums1[i-1] > nums2[j] nums1[i1]>nums2[j],说明分界点 i i i大了,故 r i g h t = i − 1 right = i - 1 right=i1

具体实现见Python方法二和Java实现。

3.代码实现

3.1 Python

方法一:

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        res = []
        left, right = 0, 0
        m, n = len(nums1), len(nums2)
        while left < m and right < n:
            if nums1[left] <= nums2[right]:
                res.append(nums1[left])
                left += 1
            else:
                res.append(nums2[right])
                right += 1
        if left < m:
            res.extend(nums1[left:])
        if right < n:
            res.extend(nums2[right:])

        mid = (m + n ) // 2
        if (m+n) % 2 == 0:
            return (res[mid] + res[mid-1]) / 2
        else:
            return res[mid]

在这里插入图片描述
方法二:

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        m, n = len(nums1), len(nums2)
        if m > n:
            return self.findMedianSortedArrays(nums2, nums1)

        infinty = pow(10, 7)
        med1, med2 = 0, 0
        left, right = 0, m
        while left <= right:
            i = (left +right) // 2
            j = (m + n + 1) // 2 - i

            nums1_left = -infinty if i == 0 else nums1[i-1]
            nums1_right = infinty if i == m else nums1[i]
            nums2_left = -infinty if j == 0 else nums2[j-1]
            nums2_right = infinty if j == n else nums2[j]

            if nums1_left <= nums2_right:
                med1, med2 = max(nums1_left, nums2_left), min(nums1_right, nums2_right)
                left = i + 1
            else:
                right = i - 1
        return (med1 + med2) / 2 if (m + n) % 2 == 0 else med1
        

在这里插入图片描述

3.2 Java

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        if (m > n){
            return findMedianSortedArrays(nums2, nums1);
        }
        int left = 0, right = m;
        int med1 = 0, med2 = 0;
        while (left <= right){
            int i = (left + right) / 2;
            int j = (m + n + 1) / 2 - i;
            int nums1_left = i == 0 ? Integer.MIN_VALUE : nums1[i-1];
            int nums1_right = i == m ? Integer.MAX_VALUE : nums1[i];
            int nums2_left = j == 0 ? Integer.MIN_VALUE : nums2[j-1];
            int nums2_right = j == n ? Integer.MAX_VALUE : nums2[j];
            if (nums1_left <= nums2_right){
                med1 = Math.max(nums1_left, nums2_left);
                med2 = Math.min(nums1_right, nums2_right);
                left = i + 1;
            }else{
                right = i - 1;
            }
        }
        return (m + n) % 2 == 0 ? (med1 + med2) / 2.0 : med1;
    }
}

在这里插入图片描述

  执行用时不必过于纠结,对比可以发现,对于python和java完全相同的编写,java的时间一般是优于python的;至于编写的代码的执行用时击败多少对手,执行用时和网络环境、当前提交代码人数等均有关系,可以尝试完全相同的代码多次执行用时也不是完全相同,只要确保自己代码的算法时间复杂度满足相应要求即可,也可以通过点击分布图查看其它coder的code。

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

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

相关文章

SQLite数据库的创建和升级

SQLite数据库的创建和升级 在刚开始接触Android的时候&#xff0c;我甚至都不敢相信&#xff0c;Android系统竟然是内置了数据库的&#xff01;好吧&#xff0c;是我太孤陋寡闻了。SQLite是一款轻量级的关系型数据库&#xff0c;它的运算速度非常快&#xff0c;占用资源很少&a…

开源通用验证码识别OCR —— DdddOcr 源码赏析(一)

文章目录 [toc] 前言DdddOcr环境准备安装DdddOcr使用示例 源码分析实例化DdddOcr实例化过程 分类识别分类识别过程 未完待续 前言 DdddOcr 源码赏析 DdddOcr DdddOcr是开源的通用验证码识别OCR 官方传送门 环境准备 安装DdddOcr pip install ddddocr使用示例 示例图片如…

Datawhale X 魔搭 AI夏令营第四期 魔搭-AIGC方向全过程笔记

task1: 传送门 task2&#xff1a; 传送门 task3: 传送门 目录 Task1 赛题内容 可图Kolors-LoRA风格故事挑战赛 baseline要点讲解(请配合Datawhale速通教程食用) Step1 设置算例及比赛账号的报名和授权 Step2 进行赛事报名并创建PAI实例 Step3 执行baseline Step4…

软件架构:架构模式、特征及实践指南-读书笔记(1)

第二章 架构思维 2.1 架构与设计 为了使架构落地&#xff0c;必须打破阻碍在架构师和开发人员之间的所有障碍&#xff0c;从而使架构师和开发团队之间形成双向的强关联。如图2-3所示&#xff0c;架构师和开发人员必须在同一个虚拟团队中才能使架构落地。该模型不仅促进了架构师…

关于使用conda安装opencv-python失败的解决方法

当你想使用conda环境安装opencv-python时&#xff0c;会弹出&#xff1a; conda install opencv-python Collecting package metadata (current_repodata.json): done Solving environment: failed with initial frozen solve. Retrying with flexible solve. Collecting packa…

【网络】网络基础概念背景TCP/IP 五层模型跨网络传输详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.计算机网络发展 1.1 独立模式 1.2 网络互联 1.3 局域网 LAN 1.4 广域网 WAN 2.协议 2.1 初识协议 2.2 协议分层 2…

应急响应:挖矿木马-实战 案例一.【Linux 系统-排查和删除】

什么是挖矿木马 挖矿木马是一种恶意软件&#xff0c;它在未经用户许可的情况下&#xff0c;利用用户的计算资源来挖掘加密货币&#xff0c;从而为攻击者带来非法收益。这类软件通常通过多种手段传播&#xff0c;例如利用系统漏洞、弱密码爆破、伪装正常软件等方法感染目标设备…

TI官网下载芯片原理图文件和封装文件导入Altium Designer 21.0.9

1、TI文件下载以 UCC27614为例 打开TI官网直接找到元器件资料界面 在设计与开发栏中找到封装模型文件下载 确认封装 选择封装导出的目标软件–AD 2、文件导入AD软件中 解压压缩包找到项目文件使用AD打开 导入AD输出芯片封装 打开UL_Import.pas然后点击Run 出现UL Import 选择…

20240818 每日AI必读资讯

3人干翻谷歌&#xff01;免费学术搜索比谷歌学术相关性高5倍&#xff0c;已获YC投资 - 三人团队打造的学术搜索引擎&#xff1a;Lumina - 目前已处理了超30万次查询&#xff0c;支持24种语言 - 号称搜索结果相关性平均比谷歌学术高5倍&#xff0c;能搜索超1亿个研究对象&…

类和对象(下)(1)

类和对象&#xff08;下&#xff09; 再探构造函数 我们之前在实现构造函数的时候&#xff0c;初始化成员变量使用的方式都是在函数体内进行赋值&#xff0c;其实构造函数初始化成员变量还有一种方式&#xff1a;初始化列表。 初始化列表不只是为了写得方便&#xff0c;还能解…

信用贷款“并发”能做多少?“并发”前,得做好几件事

最近&#xff0c;咱们聊聊一个挺热门的话题——信用贷的“并发”现象&#xff0c;还有大家最关心的&#xff0c;信用贷款并发能做多少&#xff1f;“并发”操作过程中哪些是需要注意的。 信用贷款并发能做多少&#xff1f; 信用贷能贷多少&#xff0c;这事儿得从俩角度考虑&am…

问题: vue--elementUI 关于 Drawer 抽屉能打开而受蒙版影响不能正常关闭问题解决

对于一个后端为主的小白来说&#xff0c;刚接手Element 遇到的第一个大问题。 vue–elementUI 关于 Drawer 抽屉能打开而受蒙版影响不能正常关闭问题解决> 分享并且记录一下下 其实问题很简单。我们既然能打开。先定位问题。 当我们发现到问题的时候&#xff0c;我觉得应该 …

基于javaEE的校园二手书交易平台的设计与实现

TOC springboot287基于javaEE的校园二手书交易平台的设计与实现 第1章 绪论 1.1 研究背景 互联网概念的产生到如今的蓬勃发展&#xff0c;用了短短的几十年时间就风靡全球&#xff0c;使得全球各个行业都进行了互联网的改造升级&#xff0c;标志着互联网浪潮的来临。在这个…

NGINX 基础参数与功能

章节 1 NGINX 的源码安装 2 NGINX 核心配置详解 3 NGINX 之 location 匹配优先级 4 NGINX 基础参数与功能 目录 1 实现 Nginx 账户认证功能 1.1 创建htpasswd 认证文件 1.2 创建数据目录 1.3 指定认证文件路径 1.4 测试效果 2 定义重定向错误日志 2.1 指定错误日志访问路…

深度学习的量化和剪枝

一&#xff1a;背景 如果要将深度学习的AI模型部署到受限设备&#xff08;FPGA&#xff09;上&#xff0c;往往需要更小的存储需求和最低的计算复杂度。当然&#xff0c;还得保持一定的性能&#xff08;下降在能够接受的范围&#xff09;。受限设备资源的环境&#xff0c;一般是…

掌握ChatGPT写作艺术:从入门到精通的四个层次

这些周末我仔细研究了如何通过优化提示词提升ChatGPT输出内容的质量。 关于如何使用ChatGPT辅助我们的写作&#xff0c;我归纳了以下规律&#xff0c;希望能为你带来启发。 一、写作步骤 撰写一篇文章&#xff0c;思路上必须是从抽象到具体逐步深入。 首先我们需要明确写什么…

【数据结构与算法】冒泡排序

冒泡排序目录 一.冒泡排序原理二.图示三.冒泡排序具体实现四.冒泡排序升级版五.完整代码 一.冒泡排序原理 还是老样子,我们如何对这个进行排序呢? 冒泡排序的原理是,将两两进行比较,如果前面较大的我们就进行交换到后面. 然后再对交换后的这个和下一个进行比较,一轮过后,最大值…

spfa()算法(求最短路)

spfa算法是对bellman_ford算法的优化&#xff0c;大部分求最短路问题都可以用spaf算法来求。 注意&#xff1a; &#xff08;1&#xff09;如若图中有负权回路&#xff0c;不能用spfa算法&#xff0c;要用bellman_ford算法&#xff1b;若只有负权边&#xff0c;则可以用 spf…

Feign的基本使用

一、在项目中引入相关的依赖 创建两个微服务,分别为userservice、orderservice 现在需要在orderservie中查询用户相关的数据,所以需要使用feign进行远程调用userservice 1.1、在orderservice的pom.xml文件中添加下面的依赖 <dependency><groupId>org.springfram…