归并排序中合并两个有序数组的核心是双指针法:i、j 分别遍历升序数组 a、b,k 写入结果数组,每次取较小元素,时间复杂度 O(m+n),空间复杂度视是否原地合并而定。

归并排序中两个有序数组的合并,核心是用双指针从头开始逐个比较、取小值填入结果数组。不需要额外排序,时间复杂度稳定为 O(m + n),空间复杂度 O(m + n)(若需返回新数组)或 O(1)(若原地合并到足够长的目标数组中)。
双指针同步遍历,取较小元素追加
设数组 a 和 b 均升序,分别用索引 i 和 j 从 0 开始;结果数组 res 用索引 k 记录写入位置:
- 当
i :比较 <code>a[i]和b[j],将较小者复制到res[k++],对应指针前移 - 当其中一数组遍历完,直接把另一数组剩余元素全部复制过去(无需再比较)
Java 示例代码(返回新合并数组)
注意:不修改原数组,适合归并排序的 merge 阶段
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
public static int[] merge(int[] a, int[] b) {
int m = a.length, n = b.length;
int[] res = new int[m + n];
int i = 0, j = 0, k = 0;
// 双指针主循环:两数组均未耗尽
while (i < m && j < n) {
if (a[i] <= b[j]) {
res[k++] = a[i++];
} else {
res[k++] = b[j++];
}
}
// 复制 a 剩余部分
while (i < m) res[k++] = a[i++];
// 复制 b 剩余部分
while (j < n) res[k++] = b[j++];
return res;
}
原地合并(如 LeetCode 88 题:nums1 有足够空间)
当 nums1 长度为 m + n,前 m 个有效,后 n 个为占位 0,可从**末尾反向合并**,避免覆盖:
立即学习“Java免费学习笔记(深入)”;
- 三指针:
i = m-1,j = n-1,k = m+n-1 - 每次选
nums1[i]和nums2[j]中较大者填入nums1[k],对应指针前移 - 若
nums2有剩余(j >= 0),继续填入nums1;nums1剩余无需处理(已在正确位置)
关键细节提醒
- 边界判断必须严格,防止数组越界(尤其
i 要先于 <code>a[i]访问) - 相等时优先取左数组(
a[i] )可保持稳定性 - 不要在循环内反复调用
length,提前存为变量更清晰 - 若输入可能为空数组(
length == 0),上述 while 结构天然兼容,无需额外判空

















