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

写在前面:

题目链接:LeetCode4. 寻找两个正序数组的中位数
编程语言:C++
题目难度:困难

一、题目描述

给定两个大小分别为 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 = 2.5

提示:

nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106

二、题目分析&解题思路&代码实现

2.1 归并法

看到这样的描述,大家应该很快想到了归并排序的原理,如果这里对归并排序不太了解的可以参考以下博客:
十大排序算法思路&代码实现(持续更新中)
或者也可以直接看下面的解题思路:
两个有序数组
1 , 3
2 , 4
我们只需要新建一个 vector ,然后分别从两个数组,从头到尾数组元素挨个进行比较小的就插入

        vector<int> vctResult;
        int i = 0;
        int j = 0;
        while(i< nums1.size() && j < nums2.size())
        {
            while((i < nums1.size()) && (j < nums2.size()) && nums1[i] <= nums2[j])//这里一定要注意数组越界问题
            {
            	//小的插入
                vctResult.push_back(nums1[i]);
                i++;
            }
            while((i < nums1.size()) && (j < nums2.size()) && nums2[j] <= nums1[i])
            {
                vctResult.push_back(nums2[j]);
                j++;
            }

        }
        //如果两个数组size 不相等,那么剩下的肯定就是大的数,直接插入即可
        while(i < nums1.size())
        {
            vctResult.push_back(nums1[i]);
            i++;
        }
        while(j < nums2.size())
        {
            vctResult.push_back(nums2[j]);
            j++;
        }

最后构建出一个新的数组:
1 , 2 , 3 ,4
接着我们只需要判断数组的 size 是基数还是偶数即可:

		int mid = (nums1.size() + nums2.size())/2;
        if(vctResult.size()%2==0)
        {
        	//偶数取中间两个 除以 2.0(注意返回值为 double)
            dResult = (vctResult[mid] + vctResult[mid-1])/2.0;
        }
        else
        {
        	//奇数取中间一位即可
            dResult = vctResult[mid];
        }

2.1.1 完整代码示例:

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        double dResult = 0.0;
        int mid = 0;
        mid = (nums1.size() + nums2.size())/2;
        vector<int> vctResult;//合并后的新数组
        int i = 0;
        int j = 0;
        while(i< nums1.size() && j < nums2.size())
        {
            while((i < nums1.size()) && (j < nums2.size()) && nums1[i] <= nums2[j])//这里一定要注意数组越界问题
            {
            	//小的插入
                vctResult.push_back(nums1[i]);
                i++;
            }
            while((i < nums1.size()) && (j < nums2.size()) && nums2[j] <= nums1[i])
            {
                vctResult.push_back(nums2[j]);
                j++;
            }

        }
        //如果两个数组size 不相等,那么剩下的肯定就是大的数,直接插入即可
        while(i < nums1.size())
        {
            vctResult.push_back(nums1[i]);
            i++;
        }
        while(j < nums2.size())
        {
            vctResult.push_back(nums2[j]);
            j++;
        }
        if(vctResult.size()%2==0)
        {
        	//偶数取中间两个 除以 2.0(注意返回值为 double)
            dResult = (vctResult[mid] + vctResult[mid-1])/2.0;
        }
        else
        {
        	//奇数取中间一位即可
            dResult = vctResult[mid];
        }
    return dResult;
    }
};

2.1.2 运行结果:

在这里插入图片描述
这里也是通过了,复杂度也是O(m+n) ,但同时也开辟了O(m+n)的空间,空间复杂度较高;

2.1.3 归并优化

这一步还可以再做优化,因为我们只需要合并到 新的数组size > mid 即可,后面的也不需要遍历,也不要再合并了,因此可以,将时间复杂度和空间复杂度都降低一半为:O(1/2(m+n))

代码示例:

class Solution {
public:
    bool isMidFind(vector<int>& vctResult, int& mid, double&dResult,int& size)
    {
        if(vctResult.size() > mid)
        {
            if(size %2 == 0)//偶数取中间两位
            {
                dResult = (vctResult[mid] + vctResult[mid-1])/2.0;
            }
            else//奇数直接取即可
            {
                dResult = vctResult[mid];
            }
            return true;
        }
        else
        {
            return false;
        }

    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        double dResult = 0.0;
        int mid = 0;
        mid = (nums1.size() + nums2.size())/2;
        int size = nums1.size() + nums2.size();
        vector<int> vctResult;//合并后的新数组
        int i = 0;
        int j = 0;
        while(i< nums1.size() && j < nums2.size())
        {
            while((i < nums1.size()) && (j < nums2.size()) && nums1[i] <= nums2[j])//这里一定要注意数组越界问题
            {
            	//小的数插入
                vctResult.push_back(nums1[i]);
                if(isMidFind(vctResult, mid,dResult,size))
                {	
                	//找到了直接return 即可
                    return dResult;
                }
                i++;
            }
            while((i < nums1.size()) && (j < nums2.size()) && nums2[j] <= nums1[i])
            {
                vctResult.push_back(nums2[j]);
                if(isMidFind(vctResult, mid,dResult,size))
                {
                    return dResult;
                }
                j++;
            }

        }
        //如果两个数组size 不相等,那么剩下的肯定就是大的数,直接插入即可
        while(i < nums1.size())
        {
            vctResult.push_back(nums1[i]);
            if(isMidFind(vctResult, mid,dResult,size))
            {
                return dResult;
            }
            i++;
        }
        while(j < nums2.size())
        {
            vctResult.push_back(nums2[j]);
            if(isMidFind(vctResult, mid,dResult,size))
            {
                return dResult;
            }
            j++;
        }

    return dResult;
    }
};

2.1.3.1 运行结果

在这里插入图片描述
可以看到时间和空间复杂度都有所降低。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PMP课堂模拟题目及解析(第6期)

51. 管理层将一个国际项目分配给一位新项目经理。这是该项目经理第一次与团队合作&#xff0c;团队成员位于两个国家&#xff0c;数量平均分布&#xff0c;一个团队由最合适作为个人工作的成员组成&#xff0c;另一个团队由最适合作为团队工作的成员组成。项目经理该怎么做&am…

面试题——selenium原理解析、appium原理解析

这里写目录标题 一、selenium原理解析1、目的2、技术点3、Selenium 介绍4、Selenium 自动化测试5、为什么能够支持这么多种浏览器&#xff1f;6、Selenium 工作原理 二、appium原理解析1、目的2、技术点3、Appium 介绍4、Appium 工作原理 一、selenium原理解析 1、目的 了解是…

配置JDK环境变量

文章目录 查看电脑系统下载及安装JavaSE配置系统环境变量测试环境变量配置是否成功。 查看电脑系统 运行输入框中输入&#xff1a;control 下载及安装JavaSE 这个从网上下载就行&#xff0c;jdk-8u141-windows-x64.exe&#xff0c;不提供下载方式了。 主要讲解安装过程&a…

洗稿用什么软件-洗稿软件免费

洗稿文章的主要优势 洗稿文章的主要优势在于提高文章的质量和效率。以下是洗稿文章的几个主要优势&#xff1a; 优化结构和语言 洗稿可以删除冗余、无用和重复的内容&#xff0c;同时对文章的结构和语言进行优化&#xff0c;提高文章的可读性和吸引力。这可以使文章更加专业…

操作系统内存管理笔记

计算机的硬件设备 计算机的硬件设备中&#xff0c;有三个部件最为关键&#xff0c;它们分别是中央处理器CPU、内存和I/O控制芯片。 系统软件 系统软件可以分成两块&#xff0c;一块是平台性的&#xff0c;比如操作系统内核、驱动程序、运行库和数以千计的系统工具&#xff1…

单片机的电子秤方案设计

电子秤是一种利用电子技术实现重量计量的设备&#xff0c;广泛应用于商业、工业、医疗、科学研究等领域。电子秤是一种高精度的计重装置&#xff0c;不仅精度高&#xff0c;而且使用方便、稳定可靠。下面&#xff0c;我们从结构设计、工作原理、功能参数、产品种类四个方面来介…

cout源码浅析

目录 cout源码浅析 那么对于没有定义在这之中的要怎么办呢&#xff1f; 实际使用 结语 首先来看我从cplusplus中截取的这张图&#xff1a; 注意最下面这一行字。cout其实是ostream的一个标准对象object。而上面则演示了一些继承关系。 好的&#xff0c;理解了之后&#xf…

造轮子系列】面试官问:你能手写Vuex吗(一)?

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 Vuex 是 Vue.js 的状态管理模式&#xff0c;它主要解决了组件之间共享状态时的问题。在本文…

【markdown工具配合图床】PicGo图床配置教程,一秒读懂配置

前言 看到这篇文章的大佬&#xff0c;我默认大家都会配置git&#xff0c;已经配置好ssh公钥。 此时你看到的这篇文章就是基于markdown工具&#xff08;VSCode&#xff0c;Typora&#xff09;编写的。 PicGo作为图床转换工具&#xff0c;并配合gitee作为图片服务器&#xff0…

搭建Serv-U FTP服务器共享文件并外网远程访问「无公网IP」

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 转载自内网穿透工具的文章&#xff1a;使用Serv-U搭建FTP服务器并公网访问【内网穿透】 1. 前言…

【Vue面试题】Vue2.x生命周期?

文章目录 1.有哪些生命周期&#xff08;系统自带&#xff09;?beforeCreate( 创建前 )created ( 创建后&#xff09;beforeMount (挂载前)mount (挂载后)beforeUpdate (更新前)updated (更新后)beforeDestroy&#xff08;销毁前&#xff09;destroy&#xff08;销毁后&#xf…

vue3:自定义指令

一、理解vue指令 1.1、指令 在 vue 中提供了一些对于页面和数据更为方便的输出&#xff0c;这些操作就叫做指令&#xff0c;以 v-xxx 表示&#xff0c;比如 html 页面中的属性 <div v-xxx ></div>。自定义指令很大程度提高了开发效率&#xff0c;提高了工程化水平…

git简介和使用、基础命令

文章目录 一、git的安装与配置二、Git工作区原理三、Git的使用和仓库的创建四、Git的常用操作五、配置公钥六、IDEA中配置Git 一、git的安装与配置 https://tortoisegit.org/ 下载对应版本安装即可 注意&#xff1a;配置中输入邮箱和密码一定要和自己的git账户一致 git的配置…

面试华为测试岗,收到offer后我却毫不犹豫拒绝了....

我大学学的是计算机专业&#xff0c;毕业的时候&#xff0c;对于找工作比较迷茫&#xff0c;也不知道当时怎么想的&#xff0c;一头就扎进了一家外包公司&#xff0c;一干就是2年。我想说的是&#xff0c;但凡有点机会&#xff0c;千万别去外包&#xff01; 在深思熟虑过后&am…

【模拟IC学习笔记】 反馈

反馈的作用&#xff1a;增益灵敏度降低 采用开环的方式实现一个精确的增益比较困难&#xff0c;但是可以实现高增益。 增益灵敏度衍生出来的另外两个特点 1、增加系统带宽。 2、改变输出阻抗&#xff0c;提高驱动能力。 反馈的作用&#xff1a;增加带宽 带宽的增加来源于…

ChatGPT实现markdown 格式与 emoji 表情

markdown 格式与 emoji 表情 书写文章时&#xff0c;巧妙的使用一些小图标&#xff0c;可以给文章增加不少的灵动感&#xff0c;读者也会感觉更加轻松。恰当的图标也能增进读者对内容的理解。ChatGPT 目前不能直接联网&#xff0c;但可以使用 emoji 表情文字来达到类似的效果。…

C++之数据对齐

目录 关于对齐数据对齐结构体对齐原则原理分析 关于对齐 对齐方式&#xff1a;表示的是一个类型的对象存放的内存地址应满足的条件好处&#xff1a;对齐的数据在读写上有性能优势对于不对齐的结构体&#xff0c;编译器会自动补齐以提高CPU的寻址效率 数据对齐 四个函数/描述…

机器学习实战:带你进入AI世界!

机器学习是人工智能领域的一个重要分支&#xff0c;可以帮助我们从大量数据中发现规律&#xff0c;进行预测和分类等任务。然而&#xff0c;想要真正掌握机器学习算法&#xff0c;并将其应用到实际问题中&#xff0c;还需要进行大量的实战练习。 本文将介绍几个常见的机器学习实…

6、Flutterr聊天界面网络请求

一、准备网络数据 1.1 数据准备工作 来到网络数据制造的网址,注册登录后,新建仓库,名为WeChat_flutter;点击进入该仓库,删掉左侧的示例接口,新建接口. 3. 接着点击右上角‘编辑’按钮,新建响应内容,类型为Array,一次生成50条 4. 点击chat_list左侧添加按钮,新建chat_list中的…

PAT A1032 Sharing

1032 Sharing 分数 25 作者 CHEN, Yue 单位 浙江大学 To store English words, one method is to use linked lists and store a word letter by letter. To save some space, we may let the words share the same sublist if they share the same suffix. For example, l…
最新文章