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

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


📌 题目描述

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

请你将 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] 表示从 0 到 j(包含 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 写法 ✅ 高 ❌ 稍长 ✅ 推荐
三元表达式写法 ❌ 稍低 ✅ 极简 ✅ 可选(加注释更好)

📎 拓展阅读


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

相关推荐
取名真是20 分钟前
Python 算法知识点从基础到进阶
开发语言·python·算法
梦想不只是梦与想27 分钟前
PyTorch、CPU、GPU、CUDA
人工智能·pytorch·python·深度学习·机器学习·cuda
数字融合29 分钟前
透明化视频孪生危化安全管控解决方案
人工智能·python·安全
罗西的思考36 分钟前
【轻量化复刻大模型 / KIMI K3】KDA 模块交互式演示
人工智能·算法·机器学习
别问!问就是全会2 小时前
Jupyter Notebook 安装包下载|单元格分块运行,图表直接内嵌
ide·python·其他·jupyter
深蓝AI2 小时前
Python 缓存击穿实测:16 个并发请求如何只回源 1 次
python
benchmark_cc2 小时前
用 00700.HK 做港股行情清洗:字段核对、校验与个人量化开发实践
python·数据分析·pandas·量化交易·股票数据·quantdash
nm_zfyjt3 小时前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)
算法·重构·内蒙古朋友圈广告服务商·内蒙古朋友圈获客
zh路西法3 小时前
【PACE】面向永磁同步电机PMSM 执行器的参数辨识与能耗感知强化学习 Sim-to-Real
python·cma-es·pmsm·sim-to-real·issac·pace
后台模板学习4 小时前
大模型 Prompt 工程在电商订单系统中的踩坑记录
java·python·prompt