LeetCode题练习与总结:合并两个有序数组--88

2024-05-08 01:36

本文主要是介绍LeetCode题练习与总结:合并两个有序数组--88,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、题目描述

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

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

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

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。

示例 3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示:

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -10^9 <= nums1[i], nums2[j] <= 10^9

二、解题思路

1. 初始化指针

  • p1:指向 nums1 的有效元素末尾,初始值为 m - 1
  • p2:指向 nums2 的末尾,初始值为 n - 1
  • p:指向 nums1 的末尾,即合并后数组的末尾,初始值为 m + n - 1

2. 比较并合并

  • 当 p1 >= 0 且 p2 >= 0 时,比较 nums1[p1] 和 nums2[p2]
  • 将较大的元素复制到 nums1[p] 的位置,并将相应的指针向前移动一位(即 p--p1-- 或 p2--)。

3. 处理剩余元素

  • 如果 nums1 的所有元素已经合并完成(即 p1 < 0),而 nums2 还有剩余元素,直接将 nums2 的剩余元素复制到 nums1 的前端。
  • 由于 nums1 的前 m 个元素已经是排好序的,且 nums1 的长度是 m + n,所以不需要单独处理 nums1 剩余的元素。

4. 结束条件

  • 当 p2 < 0 时,表示 nums2 的所有元素已经合并完成,此时合并过程结束。

通过以上步骤,可以在不使用额外空间的情况下,将 nums2 合并到 nums1 中,并且保证合并后的数组仍然有序。

三、具体代码

class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 = m - 1; // nums1的有效元素末尾int p2 = n - 1; // nums2的末尾int p = m + n - 1; // nums1的末尾// 从后往前遍历,比较并填充nums1while (p1 >= 0 && p2 >= 0) {nums1[p--] = (nums1[p1] > nums2[p2]) ? nums1[p1--] : nums2[p2--];}// 如果nums2还有剩余元素,直接复制到nums1的前端while (p2 >= 0) {nums1[p--] = nums2[p2--];}}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 该算法的主要时间消耗在于遍历两个数组中的元素,并进行比较和复制操作。
  • while 循环会执行 m + n 次,因为每次循环都会将一个元素放到最终位置,直到所有元素都被放置完毕。
  • 因此,时间复杂度为 O(m + n)。
2. 空间复杂度
  • 该算法没有使用额外的数组空间,只是使用了几个额外的变量来存储指针位置。
  • 变量 p1p2 和 p 占用的空间是常数级别的,与输入数组的大小无关。
  • 因此,空间复杂度为 O(1),即常数空间复杂度。

综上所述,该算法的时间复杂度为 O(m + n),空间复杂度为 O(1)。

五、总结知识点

1. 数组的操作

  • 通过索引访问数组元素:nums1[p1] 和 nums2[p2]
  • 通过索引修改数组元素:nums1[p] = nums1[p1] 或 nums1[p] = nums2[p2]

2. 指针的概念

  • 使用指针(即索引变量)来跟踪数组中的位置。在这里,p1p2 和 p 都是指针,它们表示当前正在比较或复制的元素的位置。

3. 循环结构

  • 使用 while 循环来重复执行比较和复制操作,直到所有元素都被处理。

4. 条件语句

  • 使用条件语句(if-else 的三元操作符形式)来决定哪个元素应该被复制到 nums1 的当前位置。

5. 自减运算符

  • 使用自减运算符 -- 来将指针向前移动,即从数组的末尾向开始位置移动。

6. 数组合并的逻辑

  • 从两个数组的末尾开始比较,将较大的元素逐个移动到 nums1 的末尾,这样可以避免使用额外的空间,并且能够保持元素的顺序。

7. 数组的长度和索引

  • 数组的长度是从 0 开始的,所以数组的最后一个元素的索引是 length - 1

8. 边界条件的处理

  • 当 p1 或 p2 小于 0 时,表示一个数组已经处理完毕,只需要将另一个数组的剩余元素复制到 nums1 中。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

这篇关于LeetCode题练习与总结:合并两个有序数组--88的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/968947

相关文章

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

MySQL进行分片合并的实现步骤

《MySQL进行分片合并的实现步骤》分片合并是指在分布式数据库系统中,将不同分片上的查询结果进行整合,以获得完整的查询结果,下面就来具体介绍一下,感兴趣的可以了解一下... 目录环境准备项目依赖数据源配置分片上下文分片查询和合并代码实现1. 查询单条记录2. 跨分片查询和合并测试结论分片合并(Shardin