LeetCode 88. 合并两个有序数组 | Python 最简写法 + 实战注释

在日常刷题和面试中,「合并两个有序数组」是一个经典基础题。虽然属于简单难度,但它非常考察你的数组操作技巧代码优化能力。本篇文章将带你从基础解法入手,进阶到最简洁的三元表达式写法,理解每一行代码背后的逻辑。


📌 题目描述

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

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

约定:

  • nums1 的长度为 m + n,前 m 个元素是有效数据,后 n 个是 0(占位符,用于合并)。
  • nums2 的长度为 n,且所有数据都是有效的。

🧠 解题思路:三指针倒序归并

我们采用 倒序三指针法

  • 使用 i 指向 nums1 的有效部分末尾(即 m - 1);
  • 使用 j 指向 nums2 的末尾(即 n - 1);
  • 使用 k 指向 nums1 的最后(即 m + n - 1),准备从这里倒着填充最大值。

这样做的关键好处是:不需要移动 nums1 中已有的元素,从而提升效率,避免不必要的操作。


✅ 最简 Python 解法(含三元表达式)

python 复制代码
class Solution:
    def merge(self, nums1: list[int], m: int, nums2: list[int], n: int) -> None:
        i, j, k = m - 1, n - 1, m + n - 1
        while i >= 0 and j >= 0:
            nums1[k], i, j = (nums1[i], i - 1, j) if nums1[i] > nums2[j] else (nums2[j], i, j - 1)
            k -= 1
        nums1[:j + 1] = nums2[:j + 1]

📖 逐行详解

初始化指针:

python 复制代码
i, j, k = m - 1, n - 1, m + n - 1
  • i 指向 nums1 的最后一个有效元素
  • j 指向 nums2 的最后一个元素
  • k 指向合并后数组的最后一个位置

主合并逻辑:

python 复制代码
while i >= 0 and j >= 0:
    nums1[k], i, j = (nums1[i], i - 1, j) if nums1[i] > nums2[j] else (nums2[j], i, j - 1)
    k -= 1

这是代码的核心逻辑,用了一行三元表达式简洁完成以下步骤:

  • 比较 nums1[i]nums2[j],将较大的元素放入 nums1[k]
  • 更新对应指针(哪个元素被用掉,就移动那个指针)
  • k -= 1 每次填充后向前移动一位

❗ 注意:nums1[k], i, j = ... 是 Python 中同时赋值的语法,它保证在一行中完成所有更新。


边界处理(复制剩余的 nums2):

python 复制代码
nums1[:j + 1] = nums2[:j + 1]

为什么是 j + 1

  • Python 中切片是 左闭右开 的:[:j + 1] 表示从 0j(包含 j)的位置。
  • 如果 nums1 的元素全部更大,nums2 的部分没被填进去,那就直接复制剩下的部分到 nums1 的前面。

🔍 示例图解

示例输入:

python 复制代码
nums1 = [1, 2, 3, 0, 0, 0]
m = 3
nums2 = [2, 5, 6]
n = 3

合并过程:

复制代码
初始:
i=2, j=2, k=5

比较 nums1[2]=3 和 nums2[2]=6 → 填入 nums1[5]=6,j--
比较 nums1[2]=3 和 nums2[1]=5 → 填入 nums1[4]=5,j--
比较 nums1[2]=3 和 nums2[0]=2 → 填入 nums1[3]=3,i--
比较 nums1[1]=2 和 nums2[0]=2 → 填入 nums1[2]=2,j--
比较 nums1[1]=2 和 nums2[-1]=越界 → 循环结束

最后复制剩余 nums2[:0+1] → nums2[0] → nums1[0]

最终输出:

python 复制代码
[1, 2, 2, 3, 5, 6]

⏱️ 时间与空间复杂度

指标 说明
时间复杂度 O(m + n) --- 每个元素最多处理一次
空间复杂度 O(1) --- 原地合并,不用额外空间

🎯 总结

这题是数组类题目中的高频面试题:

  • 正确做法是从后往前合并,避免大量元素移动;
  • 代码可以用三元表达式写得更简洁优雅
  • 理解 [:j+1] 的切片语法是关键细节之一。

📌 推荐写法对比

写法 可读性 简洁性 面试推荐
标准 if/else 写法 ✅ 高 ❌ 稍长 ✅ 推荐
三元表达式写法 ❌ 稍低 ✅ 极简 ✅ 可选(加注释更好)

📎 拓展阅读


如果你觉得这篇讲解对你有帮助,欢迎点赞、收藏和评论交流!🚀

相关推荐
菜鸟破茧计划2 分钟前
滑动窗口:穿越数据的时光机
java·数据结构·算法
Cloud Traveler24 分钟前
Java并发编程常见问题与陷阱解析
java·开发语言·python
山海不说话35 分钟前
PyGame游戏开发(含源码+演示视频+开结题报告+设计文档)
python·pygame
_Itachi__1 小时前
LeetCode 热题 100 101. 对称二叉树
算法·leetcode·职场和发展
少了一只鹅1 小时前
深入理解指针(5)
java·c语言·数据结构·算法
朱剑君2 小时前
第三天——贪心算法——区间问题
算法·贪心算法
阳洞洞2 小时前
leetcode 15. 三数之和
leetcode·双指针
Y3174292 小时前
Python Day 22 学习
python·学习
正在走向自律2 小时前
Python 自动化脚本开发秘籍:从入门到实战进阶(6/10)
开发语言·python
白熊1882 小时前
【计算机视觉】基于Python的相机标定项目Camera-Calibration深度解析
python·数码相机·计算机视觉