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

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

相关推荐
JAVA面经实录9172 小时前
Java 数据结构与算法 (终极完整学习文档)
java·数据结构·算法
开源Z3 小时前
LeetCode 42 · 接雨水:从暴力到双指针的三步优化
算法·leetcode
旖-旎3 小时前
《LeetCode 695 岛屿的最大面积 FloodFill DFS 解法》
c++·算法·力扣·深度优先遍历·floodfill
syagain_zsx4 小时前
STL 之 vector 讲练结合
c++·算法
MartinYeung55 小时前
[论文学习]DP2Unlearning:高效且具保证的大型语言模型遗忘框架(基于差分隐私的 LLM Unlearning 方法)
学习·算法·语言模型
Tian_Hang6 小时前
C++原型模式(Protype)
开发语言·c++·算法
bIo7lyA8v6 小时前
算法复杂度的渐进分析与实际运行时间的差异的技术8
算法
yuan199976 小时前
欧拉梁静力与屈曲计算的 MATLAB 实现(有限差分法 + 解析解)
开发语言·算法·matlab
汉克老师7 小时前
GESP7级C++考试语法知识(二、指数函数(3、综合练习)
c++·算法·数学建模·指数函数·gesp7级·复利