LeetCode 88. Merge Sorted Array 题解

LeetCode 88. Merge Sorted Array 题解

题目描述

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

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

注意: 最终,合并后数组不应由函数返回,而是存储在数组 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 中。

解题思路

方法:双指针(从后向前)

思路

  • 使用两个指针,分别指向 nums1nums2 的末尾
  • 使用一个指针,指向 nums1 的最终位置(即 m + n - 1
  • 比较 nums1nums2 的末尾元素:
    • 如果 nums1 的元素大于 nums2 的元素,将 nums1 的元素移动到最终位置,然后移动 nums1 的指针
    • 否则,将 nums2 的元素移动到最终位置,然后移动 nums2 的指针
  • 重复上述过程,直到其中一个指针到达数组的开头
  • 如果 nums2 还有剩余元素,将其复制到 nums1 的开头

复杂度分析

  • 时间复杂度:O(m + n),其中 m 和 n 分别是 nums1nums2 的长度。只需要遍历数组一次。
  • 空间复杂度:O(1),只需要常数级的额外空间。

代码实现

方法:双指针(从后向前)

python 复制代码
class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        # 初始化指针
        p1 = m - 1  # nums1 的末尾指针
        p2 = n - 1  # nums2 的末尾指针
        p = m + n - 1  # nums1 的最终位置指针
        
        # 比较 nums1 和 nums2 的末尾元素,将较大的元素移动到 nums1 的末尾
        while p1 >= 0 and p2 >= 0:
            if nums1[p1] > nums2[p2]:
                nums1[p] = nums1[p1]
                p1 -= 1
            else:
                nums1[p] = nums2[p2]
                p2 -= 1
            p -= 1
        
        # 如果 nums2 还有剩余元素,将其复制到 nums1 的开头
        while p2 >= 0:
            nums1[p] = nums2[p2]
            p2 -= 1
            p -= 1

测试用例

测试用例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3

输出:[1,2,2,3,5,6]

测试用例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0

输出:[1]

测试用例 3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1

输出:[1]

总结

本题是双指针的经典应用问题,主要考察对双指针技巧的理解和使用。通过使用双指针从后向前遍历,我们可以高效地合并两个有序数组,而不需要额外的空间。

双指针的核心思想是:使用两个指针分别指向两个数组的末尾,比较它们的元素,将较大的元素移动到 nums1 的末尾,然后移动相应的指针。

这种方法不仅适用于合并两个有序数组问题,还可以应用于许多其他需要合并有序数组的场景。掌握双指针的使用,对于解决这类问题非常重要。

相关推荐
a11177635 分钟前
LM 算法迭代过程动画演示(SLAM)
算法
头茬韭菜37 分钟前
Context 的生死抉择:四层压缩、截断算法与 Session Memory
算法·ai
Jerry1 小时前
LeetCode 541. 反转字符串 II
算法
Jerry1 小时前
LeetCode 344. 反转字符串
算法
搞科研的小刘选手1 小时前
【香港大学主办&IEEE出版】第六届计算机视觉、应用与算法国际学术会议(CVAA 2026)
算法·计算机视觉·应用·学术会议
Java小白笔记2 小时前
Codex config.toml配置实战指南
人工智能·算法·chatgpt·ai编程·集成学习
王老师青少年编程2 小时前
2026年6月GESP真题及题解(C++七级):消消乐
数据结构·c++·算法·真题·gesp·2026年6月
z小猫不吃鱼2 小时前
模型剪枝经典论文精读:Pruning Filters for Efficient ConvNets
算法·机器学习·剪枝
Fox爱分享4 小时前
字节二面:1000瓶酒,有一瓶是毒药,多少只老鼠可以查出来?
算法·面试·程序员
+wacyltd大模型备案算法备案4 小时前
大模型评估测试题库怎么建?风险分类、测试样本的完整方法
人工智能·算法·安全·分类·大模型·大模型备案·大模型上线登记