代码训练LeetCode(1)合并有序数组详解

代码训练(1)LeetCode之合并两个有序数组

Author: Once Day Date: 2024年3月5日

漫漫长路,才刚刚开始…

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客

参考文章:

  • 88. 合并两个有序数组 - 力扣(LeetCode)
  • 力扣 (LeetCode) 全球极客挚爱的技术成长平台

文章目录

      • 代码训练(1)LeetCode之合并两个有序数组
        • 1. 问题
        • 2. 分析
        • 3. 代码实现
        • 4. 结论

1. 问题

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

2. 分析

该问题是一个非常基础的编程题目,我们用C语言来实现,并且额外要求性能较高(速度90%,内存80%)。

首先,想象你有两排学生,他们分别按身高从矮到高排好了队。现在我们要将这两排学生合并成一排,同时保持身高从矮到高的顺序。这就像我们要合并的两个数组,分别是nums1nums2,它们已经按照非递减顺序(即从小到大)排列好。整数mn分别告诉我们nums1nums2中有多少个元素是有效的。

我们的目标是将nums2合并进nums1,并且保持顺序正确。需要注意的是,nums1数组的大小是m + n,前m个元素是有效的,后面n个元素被初始化为0,我们将使用这些0来填充nums2中的元素。

解题思路如下:

  1. 因为nums1的后半部分是空的,我们可以从后往前填充,这样可以避免覆盖nums1中原有的元素。
  2. 设置两个指针,分别指向nums1nums2的最后一个有效元素,还有一个指针指向nums1的最后位置。
  3. 比较这两个指针所指的元素大小,将较大的数字放入nums1的最后位置的指针处。
  4. 移动指针,重复上述过程,直到所有元素都被遍历完。

性能优化关键点:

  • 执行速度:从后往前合并可以减少数组元素的移动次数,提高执行速度。
  • 内存使用:直接在nums1数组上操作,无需额外的存储空间,这样可以节省内存。
3. 代码实现

假设nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3

  1. 我们设置指针im-1jn-1km+n-1
  2. 比较nums1[i]nums2[j]nums1[i]=3nums2[j]=6,将6放入nums1[k]
  3. 更新jk的值,此时nums1 = [1,2,3,0,0,6]
  4. 重复这个过程,直到所有元素都被合并。

下面是C语言的实现代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int i = m - 1, j = n - 1, k = m + n - 1;
    while (i >= 0 && j >= 0) {
        if (nums1[i] > nums2[j]) {
            nums1[k--] = nums1[i--];
        } else {
            nums1[k--] = nums2[j--];
        }
    }
    while (j >= 0) {
        nums1[k--] = nums2[j--];
    }
}

这段代码将两个已经排序的整数数组 nums1nums2 合并为一个单一的有序数组。合并的结果存放在 nums1 数组中,合并后的数组也是有序的。

参数说明:

  • int* nums1:第一个有序数组。
  • int nums1Sizenums1 数组的总容量,包括合并后额外的空间。
  • int mnums1 中已有元素的数量,即需要合并的部分。
  • int* nums2:第二个有序数组。
  • int nums2Sizenums2 数组的总容量。
  • int nnums2 中的元素数量。

函数逻辑:

  1. 分别使用三个指针 ijk 来跟踪 nums1nums2 和合并后数组的当前位置。inums1 的有序部分的末尾开始(索引为 m - 1),jnums2 的末尾开始(索引为 n - 1),k 从合并后数组的末尾开始(索引为 m + n - 1)。

  2. while 循环中,比较 nums1[i]nums2[j] 的值,并将较大的值放在 nums1[k] 的位置,然后相应地移动 ijk 指针。

  3. 如果 nums1[i] 大于 nums2[j],则 nums1[i] 被复制到 nums1[k],然后 ik 都递减。

  4. 如果 nums2[j] 大于或等于 nums1[i],则 nums2[j] 被复制到 nums1[k],然后 jk 都递减。

  5. 这个过程持续直到 ij 中的一个小于 0,意味着其中一个数组已经完全复制到合并后的数组中。

  6. 如果 nums2 有剩余的元素(j >= 0),则需要将这些元素复制到 nums1 中,因为 nums1 的剩余部分(如果有)已经是有序的,不需要移动。这一步是必要的,因为在 nums1nums2 的合并过程中,如果 nums2 的元素较小且在前面,需要将它们移动到 nums1 的前端。

运行结果如下所示:

在这里插入图片描述

从运行速率来看,已达到预定目标,所以无需优化(优化需要按照目标来优化,而不能无限制优化下去)

4. 结论

合并两个有序数组的问题可以通过一种高效的从后向前的填充方法来解决,确保了在不使用额外内存的情况下,合并后的数组nums1仍然保持非递减顺序。这个方法利用了nums1数组预留的空间,通过设置三个指针,逐步比较并填充较大的元素,直到所有元素都被正确合并。这种方法的时间复杂度是O(m+n),空间复杂度是O(1),即只需要常数级别的额外空间,因此在执行速度和内存使用方面都非常优化。







Alt

Once Day

也信美人终作土,不堪幽梦太匆匆......

如果这篇文章为您带来了帮助或启发,不妨点个赞👍和关注,再加上一个小小的收藏⭐!

(。◕‿◕。)感谢您的阅读与支持~~~

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

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

相关文章

【BUG】Windows状态栏总卡死解决办法

屋漏偏逢连夜雨,正在赶deadline呢,Windows状态老卡死,一时间崩溃。 解决办法: 右键状态栏新闻和咨询关掉 这个烧笔新闻与资讯我真服了

Ubantu 18.04 如何映射IP到公网,外网可以访问

介绍一种简单的方式,就是通过路由侠 inux 系统安装路由侠,可通过两种方式进行,一种是通过直接脚本安装,一种是通过 Docker 安装。 windows下载地址:路由侠-局域网变公网 方式一:通过脚本安装 1、获取安…

赵珊珊Go语言汇编视频课程

本课程由赵珊珊老师倾情打造,旨在深入解析Go语言与汇编语言结合的高级主题。学员将系统学习Go语言底层实现原理,掌握汇编代码优化技巧,为高性能、高并发应用开发奠定坚实基础,助力学员在软件工程领域取得更大成功。 课程大小&…

Ajax+Axios+前后端分离+YApi+Vue-ElementUI组件+Vue路由+nginx【全详解】

目录 一.Ajax技术 二. Axios 三.前后台分离开发介绍 四. YAPI 五.前端工程化 六.vue工程的目录结构 七.Vue项目核心文件 八.Vue组件库ElementUI AboutView.vue最终代码 AboutView.vue最终代码 九.Vue路由 十.案例 十一.nginx介绍 一.Ajax技术 1.Ajax概述 Ajax: 全…

excel 动态列导出

excel动态列,只好用poi来写了,也并不复杂,一样就这个件事情抽像为几步,就是套路了,开发效率就上去了。 1 准备空模板 导出操作与excel模板的导出一样,可以参考excel导出标准化 2 自定义SheetWriteHandler …

Redis面试问题纯享版

基础内容 1、简单介绍以下你了解的Redis 2、对比一下Redis和Memcache的异同? 3、为什么MySQL选用Redis作为缓存? 4、详细聊聊你对Redis各种数据类型的了解? 5、Redis中五种基本数据类型的底层数据结构是什么样的? Redis线程模型…

图书推荐|Word文稿之美

让你的文档从平凡到出众! 本书内容 《Word文稿之美》是一本全面介绍Word排版技巧和应用的实用指南。从初步认识数字排版到高效利用模板、图文配置和表格与图表的排版技巧,再到快速修正错误和保护文件,全面系统地讲解数字排版的技术和能力&…

【Linux】编译器gcc | make | Makefile | 模拟进度条 | gitee

目录 1. 编译器 gcc 1.1 背景知识 1.2 gcc如何完成 2.1 Makefile背景 2.2 Makefile原理 2.3 Makefile常用符号 3. 模拟倒计时 4. 模拟进度条 5. 使用 git 命令行 5.1 安装 git 5.2 创建项目下载到本地 5.3 推送本地代码到远端仓库 1. 编译器 gcc 1.1 背景知识 预处…

stm32学习笔记:I2C通信外设原理(未完)

软件实现和硬件实现 串口通信为异步时序,用软件实现很麻烦,基本上用硬件实现 而I2C协议通信为同步时序,软件实现简单且灵活,硬件实现比较麻烦,故软件比较常用 但I2C硬件实现功能比较大,执行效率高&#xff…

Electron-builder打包安装包——编译篇

突然有一天想打包个桌面程序,没有打包过,经过九牛二虎之力终于打包出来,在此感谢那些热于分享的前辈! 本篇只讲打包运行和出现的问题 一、准备工作:提前下载相关资源包,否则在国内环境下可能因为网络问题…

python+django_vue旅游酒店预订出行订票系统pycharm项目lw

a.由于对管理信息方面的内容了解尚浅且没有足够的经验,因而很难对数据庞大的线上旅行信息管理系统建立完善的数据库。 b.线上旅行信息管理系统拥有很大的信息量,其中包括数据库的前期开发和后期更新,因此对数据库的安全性,一致性和…

【Java】CAP理论以及它的实际应用案例

目录 简介 不是所谓的“3 选 2” CAP 实际应用案例 总结 CAP 理论/定理起源于 2000年,由加州大学伯克利分校的Eric Brewer教授在分布式计算原理研讨会(PODC)上提出,因此 CAP定理又被称作 布鲁尔定理(Brewer’s the…

html标签之表格标签,程序员必看

突破困境: 1. 提升学历 前端找工作,学历重要吗? 重要。谁要是告诉你不重要那一定是在骗你。现实情况是大专吃紧,本科够用,硕士占优,大专以下找到工作靠运气和 戳这里领取完整开源项目:【一线大…

嵌入式面试

1.关键字static的作用是什么?为什么static变量只初始化一次? 1)修饰局部变量:使得变量变成静态变量,存储在静态区,存储在静态区的数据周期和程序相同, 在main函数开始前初始化,在退…

HTML入门:05HTML多媒体

HTML入门:05HTML多媒体 1 video标签1.1 控制按钮:controls1.2 宽度和高度:width和heightt1.3 预载:preload1.4 静音:muted1.5 自动播放:autoplay1.6 无限循环:loop1.7 poster 2 audio标签 在早期…

从零学习Linux操作系统 第三十二部分 ansible中剧本的应用

一、什么是playbook及playbook的组成 1.Playbook的功能 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 play就是一个个模块用列表的方式体现出来 playbook的语法是用YAML的预防进行书写的 2.YAML 简介 是一种表达资料序列的格式,类似XM…

ShardingSphere-SQL 解析 Issue 处理流程

ShardingSphere-SQL 解析 Issue 处理流程 这是之前给社区写的 SQL 解析 Issue 的处理流程,可以帮助社区用户快速参与到 ShardingSphere-SQL 解析任务当中。 ShardingSphere SQL 解析 issue 列表 Issue 背景说明 当前 Issue 使用自定义的爬虫脚本从对应的数据库官…

php采集类snoopy2.0使用说明

我们经常采集一些网站数据时会被识别为机器人被网页被拒绝访问,类似这种: failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden网宿云安全平台检测到您当前的访问行为存在异常,请稍后重试... 云安全平台检测到您当前的访问…

【Azure 架构师学习笔记】- Azure Service Endpoint

本文属于【Azure 架构师学习笔记】系列。 前言 在做Azure 架构时,经常会被问到Service Endpoint这个点,那么这篇文章来介绍一下Service Endpoint(SE)。 Azure Service Endpoint 首先它是一个专用通道,在Azure 资源之…

Kosmos-2: 在多模态大语言模型中引入基准和指代能力

Kosmos-2: 在多模态大语言模型中引入基准和指代能力 FesianXu 20240304 at Baidu Search Team 前言 之前笔者在博文中介绍过kosmos-1模型 [1],该模型脱胎于MetaLM采用『因果语言模型作为通用任务接口』的思想,采用了多种形式的多模态数据进行训练得到。…