【力扣刷题】day3-4. 寻找两个正序数组的中位数

news2024/11/27 10:48:15

力扣刷题笔记day3

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

题意

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

算法的时间复杂度应该为 O(log (m+n)) 。

输入: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.5

分析

首先可以先合并数组,然后求中位数

class Solution7 {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int[] num=new int[2000];
        int n=0,m=0;
        int i=0;
        while (n<nums1.length&&m<nums2.length){
            num[i]=Math.min(nums1[n],nums2[m]);
            i++;
            if(nums1[n]>nums2[m]){
                m++;
            }
            else{
                n++;
            }
        }
        if(n==nums1.length){
            while (m<nums2.length){
                num[i]=nums2[m];
                i++;
                m++;
            }
        }
        else{
            while (n<nums1.length){
                num[i]=nums1[n];
                i++;
                n++;
            }
        }
        int flag=(nums1.length+nums2.length)%2;
        int flag1=(nums1.length+nums2.length)/2;
        return flag==0?((double) num[flag1-1]+(double) num[flag1])/2:(double) num[flag1];
    }
}

但是时间复杂度达不到要求,实际上,不需要全部合并,只需要合并到中间即可

于是可以优化代码

class Solution6 {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int flag = (nums1.length+nums2.length)/2+1;

            int n,m;
            int n1=0,m1=0;
            double front=0,next=0;
            for (int i = 0; i < flag; i++) {
                n=n1==nums1.length?1000000:nums1[n1];
                m=m1==nums2.length?1000000:nums2[m1];
                if(n>m){
                    front=next;
                    next=m;
                    m1++;
                }
                else{
                    front=next;
                    next=n;
                    n1++;
                }
            }
        if((nums1.length+nums2.length)%2==0){
            return (front+next)/2;
        }
        return next;
    }
}

但是仍然达不到要求。

这里贴大佬的解法

假设我们要找第 7 小的数字。
请添加图片描述
我们比较两个数组的第 k/2 个数字,如果 k 是奇数,向下取整。也就是比较第 33 个数字,上边数组中的 44 和下边数组中的 33,如果哪个小,就表明该数组的前 k/2 个数字都不是第 k 小数字,所以可以排除。也就是 11,22,33 这三个数字不可能是第 77 小的数字,我们可以把它排除掉。将 13491349 和 4567891045678910 两个数组作为新的数组进行比较。

更一般的情况 A[1] ,A[2] ,A[3],A[k/2] … ,B[1],B[2],B[3],B[k/2] … ,如果 A[k/2]<B[k/2] ,那么A[1],A[2],A[3],A[k/2]都不可能是第 k 小的数字。A 数组中比 A[k/2] 小的数有 k/2-1 个,B 数组中,B[k/2] 比 A[k/2] 小,假设 B[k/2] 前边的数字都比 A[k/2] 小,也只有 k/2-1 个,所以比 A[k/2] 小的数字最多有 k/1-1+k/2-1=k-2个,所以 A[k/2] 最多是第 k-1 小的数。而比 A[k/2] 小的数更不可能是第 k 小的数了,所以可以把它们排除。
橙色的部分表示已经去掉的数字。

请添加图片描述

由于我们已经排除掉了 3 个数字,就是这 3 个数字一定在最前边,所以在两个新数组中,我们只需要找第 7 - 3 = 4 小的数字就可以了,也就是 k = 4。此时两个数组,比较第 2 个数字,3 < 5,所以我们可以把小的那个数组中的 1 ,3 排除掉了。

image.png

我们又排除掉 2 个数字,所以现在找第 4 - 2 = 2 小的数字就可以了。此时比较两个数组中的第 k / 2 = 1 个数,4 == 4,怎么办呢?由于两个数相等,所以我们无论去掉哪个数组中的都行,因为去掉 1 个总会保留 1 个的,所以没有影响。为了统一,我们就假设 4 > 4 吧,所以此时将下边的 4 去掉。

image.png

由于又去掉 1 个数字,此时我们要找第 1 小的数字,所以只需判断两个数组中第一个数字哪个小就可以了,也就是 4。

所以第 7 小的数字是 4。

我们每次都是取 k/2 的数进行比较,有时候可能会遇到数组长度小于 k/2的时候。

image.png

此时 k / 2 等于 3,而上边的数组长度是 2,我们此时将箭头指向它的末尾就可以了。这样的话,由于 2 < 3,所以就会导致上边的数组 1,2 都被排除。造成下边的情况。

image.png

由于 2 个元素被排除,所以此时 k = 5,又由于上边的数组已经空了,我们只需要返回下边的数组的第 5 个数字就可以了。

从上边可以看到,无论是找第奇数个还是第偶数个数字,对我们的算法并没有影响,而且在算法进行中,k 的值都有可能从奇数变为偶数,最终都会变为 1 或者由于一个数组空了,直接返回结果。

所以我们采用递归的思路,为了防止数组长度小于 k/2,所以每次比较 min(k/2,len(数组) 对应的数字,把小的那个对应的数组的数字排除,将两个新数组进入递归,并且 k 要减去排除的数字的个数。递归出口就是当 k=1 或者其中一个数字长度是 0 了。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int n = nums1.length;
    int m = nums2.length;
    int left = (n + m + 1) / 2;
    int right = (n + m + 2) / 2;
    //将偶数和奇数的情况合并,如果是奇数,会求两次同样的 k 。
    return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;  
}
    
    private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
        int len1 = end1 - start1 + 1;
        int len2 = end2 - start2 + 1;
        //让 len1 的长度小于 len2,这样就能保证如果有数组空了,一定是 len1 
        if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
        if (len1 == 0) return nums2[start2 + k - 1];

        if (k == 1) return Math.min(nums1[start1], nums2[start2]);

        int i = start1 + Math.min(len1, k / 2) - 1;
        int j = start2 + Math.min(len2, k / 2) - 1;

        if (nums1[i] > nums2[j]) {
            return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));
        }
        else {
            return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));
        }
    }

时间复杂度:每进行一次循环,我们就减少 k/2 个元素,所以时间复杂度是 O(log(k),而 k=(m+n)/2,所以最终的复杂也就是 O(log(m+n)O(log(m+n)。

空间复杂度:虽然我们用到了递归,但是可以看到这个递归属于尾递归,所以编译器不需要不停地堆栈,所以空间复杂度为 O(1)O(1)。

作者:windliang
链接:https://leetcode.cn/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/
来源:力扣(LeetCode)

总结

本题难点在于如何达到对应复杂度,对于log(m+n)应想到使用二分的解法。归并排序在解决有序数组合并时有很大用处,本题需要多刷。

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

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

相关文章

【通讯录管理系统】C++全栈体系(六)

通讯录管理系统 第一章 系统需求 通讯录是一个可以记录亲人、好友信息的工具。 本教程主要利用C来实现一个通讯录管理系统 系统中需要实现的功能如下&#xff1a; 添加联系人&#xff1a;向通讯录中添加新人&#xff0c;信息包括&#xff08;姓名、性别、年龄、联系电话、…

人工智能算法模型--Alpha-Beta剪枝算法学习笔记

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; (*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &a…

【华为机试真题详解】不含 101 的数【2022 Q4 | 100分】

文章目录前言题目描述输入描述输出描述示例 1示例2题目解析参考代码前言 《华为机试真题详解 Python实现》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试&#xff0c;期间有想了解的可以私信我&#xff0c;我会尽可能帮您解答&#xff0c;也可…

逻辑漏洞渗透与攻防(五)之权限类逻辑漏洞

目录 权限类逻辑漏洞 平行权限跨越 基于用户身份ID 基于对象ID 基于文件名 垂直权限跨越 未经授权访问 权限类逻辑漏洞 越权漏洞又分为平行越权&#xff0c;垂直越权和交叉越权。 平行越权&#xff1a;权限类型不变&#xff0c;权限ID改变&#xff0c;垂直越权&#xff1…

SQL ORDER BY 关键字

ORDER BY 关键字用于对结果集进行排序。 SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。 ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序&#xff0c;您可以使用 DESC 关键字。 SQL ORDER BY 语法 SELECT c…

太适合小白了!11招,高手都在用的数据分析招式!

阅读本文大概需要3分钟菜鸟独白用Python来玩转数据分析实在是太爽了&#xff0c;因为有强大的Pandas来处理数据非常方便&#xff0c;我个人对数据分析情有独钟&#xff0c;探索数据的秘密非常好玩&#xff01;前段时间写过一篇小白学数据分析入门招式&#xff0c;但是进阶的部分…

蓝桥杯基础练习合集九 1.回文词2.猜数字游戏的提示3.生成元4.环状序列5.刽子手游戏

目录 1.回文词 2.猜数字游戏的提示 3.生成元 4.环状序列 5.刽子手游戏 1.回文词 问题描述 输入一个字符串&#xff0c;判断它是否为回文串以及镜像串。输入字符串保证不含数字0。所谓回文串&#xff0c;就是反转以后和原串相同&#xff0c;如abba和madam。所有镜像串&…

docker 安装mysql5.7

拉取镜像 非常快 因为上一篇安装的是阿里云的centos7并且配置了阿里云的镜像加速 docker pull mysql:5.7 拉取成功检验 启动镜像 docker run -p 3306:3306 --name mymysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASS…

软件测试行业未来职业规划是什么

随着软件工程活动的不断演化&#xff0c;软件测试岗位已经成为了软件开发中极其重要的一个环节&#xff0c;因而市场对于软件测试人才的需求也在日益扩大。相信不少想入行软件测试的小伙伴都难免会有这样的疑问&#xff0c;软件测试行业究竟怎么样&#xff1f;职业发展应该如何…

代码层面解决 The channelMax limit is reached. Try later.

该问题也是非常的严重&#xff0c;没有合适处理即导致消息丢失&#xff1b; 解决方案 设置连接工厂配置 CachingConnectionFactory connectionFactory new CachingConnectionFactory();connectionFactory.setChannelCheckoutTimeout(30000);解析 该报错根本原因是**”连接池…

2023年1月伊凡梳理如何快速安装git并且配置本地gitee账号权限方便拉代码

本文优雅草伊凡投稿一颗优雅草科技&#xff0c;欢迎其他朋友们来投稿&#xff08;一定会详细署名&#xff09;还是那个原因因为重装了因此git信息已经没有了&#xff0c;还是那个原因因为网上各类文章鱼龙混杂有好的有坏的&#xff0c;真正可用的其实还是不好找的&#xff0c;自…

延迟低于1.55毫秒,韩国ETRI研发远程实时触觉渲染系统

相比于AR/VR这种视觉模拟技术&#xff0c;体感、触觉模拟技术远不够成熟&#xff0c;依然受到体积、延迟、人体工学等方面限制。尽管如此&#xff0c;科研界不断探索多种体感模拟方案&#xff0c;以实现轻薄、灵活的穿戴式设计&#xff08;比如体感手套&#xff09;。近期&…

imutils简介

imutils对一系列OpenCV函数进行二次封装&#xff0c;执行基本任务&#xff0c;如平移、旋转、调整大小和骨架提取。 1.安装 这个包假设您已经安装了NumPy和OpenCV(如果您打算使用opencv2matplotlib函数&#xff0c;还安装了matplotlib)。 要安装库&#xff0c;只需使用以下命…

【OpenDDS开发指南V3.20】第九章:DCPS信息库

DCPS信息存储库选项 下表显示了DCPInfoRepo服务器的命令行选项: 表9-1 DCPS信息存储库选项 选项描述默认值-o file将DCPInfo对象的IOR写入指定文件repo.ior-NOBITS禁用发布内置主题发布内置主题-a address内置主题的侦听地址(发布内置主题时)随机端口-z启用详细传输日志记…

关系数据库概述

一、数据模型 一般地讲&#xff0c;数据模型是严格定义的一组概念的集合&#xff0c;通常由数据结构、数据操作和完整性约束三部分组成。 1.1 数据结构 数据结构描述数据库的组成对象以及对象之间的联系。数据结构是刻画一个数据模型性质最重要的方面。因此在数据库系统中&…

数据的存储【详解】【强烈推荐!!!】

数据的存储1. 数据类型介绍1.1 类型的基本归类2. 整型在内存中的存储2.1 原码、反码、补码2.2 大小端介绍2.3 练习3. 浮点型在内存中的存储3.1 一个例子3.2 浮点数存储规则1. 数据类型介绍 基本的内置类型、大小&#xff08;字节&#xff09;&#xff08;VS编译器&#xff09;…

bootstrap校验laydate起止日期联动失效

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目中用到bootstrapValidator&#xff0c;以及laydate&#xff08;by:贤心&#xff0c;插件效果美观&#xff09;。 项目表单中&#xff0c;有两处需要联动校验&#xff1a;开始日期&#xff0c;结束…

第04讲:HTTP操作之ElasticSearch高级查询

3.1.4、高级查询 Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询 定义数据 : # POST /student/_doc/1001 {"name":"zhangsan", "nickname":"zhangsan", "sex":"男","age":30 } # POST…

MySQL innodb引擎架构分析-Change Buffer

系列文章目录 1. MySQL innodb引擎架构分析-Buffer Pool 2. MySQL innodb引擎架构分析-Redo log 3. MySQL innodb引擎架构分析- Double Write Buffer 4.MySQL innodb引擎架构分析-Change Buffer 文章目录系列文章目录前言一、Change Buffer是什么&#xff1f;二、Change Buffe…

日本市场的Starday开始对智能家居下重手

自从21世纪以来&#xff0c;物联网就开始进入大众视野&#xff0c;因此作为物联网基础应用的智能家居已经成为人们对生活场景的一种涉嫌。因此在国外市场当中&#xff0c;跨境电商卖家们通过物联网的智慧家居的售卖&#xff0c;获得了大量的资金&#xff0c;可知“跨境沃土”大…