在日常刷题和面试中,「合并两个有序数组」是一个经典基础题。虽然属于简单难度,但它非常考察你的数组操作技巧 和代码优化能力。本篇文章将带你从基础解法入手,进阶到最简洁的三元表达式写法,理解每一行代码背后的逻辑。
📌 题目描述
给你两个按 非递减顺序 排列的整数数组
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 写法 | ✅ 高 | ❌ 稍长 | ✅ 推荐 |
三元表达式写法 | ❌ 稍低 | ✅ 极简 | ✅ 可选(加注释更好) |
📎 拓展阅读
如果你觉得这篇讲解对你有帮助,欢迎点赞、收藏和评论交流!🚀