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 的末尾,然后移动相应的指针。

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

相关推荐
加农炮手Jinx3 小时前
LeetCode 26. Remove Duplicates from Sorted Array 题解
算法·leetcode·力扣
格林威3 小时前
线阵工业相机:如何计算线阵相机的行频(Line Rate)?公式+实例
开发语言·人工智能·数码相机·算法·计算机视觉·工业相机·线阵相机
yueyue5433 小时前
透过现象看本质:以fast_lio架构的整套算法的局部避障改为TEB算法为例深度探讨——如何成为一个合格的算法架构师?
算法·架构
梨花爱跨境3 小时前
红人视频×A10算法:亚马逊转化率与流量闭环实战
算法
阿Y加油吧3 小时前
二刷 LeetCode:75. 颜色分类 & 31. 下一个排列 复盘笔记
笔记·算法·leetcode
风筝在晴天搁浅3 小时前
LeetCode 378.有序矩阵中第K小的元素
算法·矩阵
小雅痞3 小时前
[Java][Leetcode middle] 3. 无重复字符的最长子串
java·开发语言·leetcode
qeen873 小时前
【算法笔记】简单贪心
c++·笔记·算法·贪心算法
ting94520003 小时前
动手学深度学习(PyTorch版)深度详解(10): 优化算法 全解
人工智能·pytorch·深度学习·算法