最常用且高效的方法是双指针归并法,时间复杂度O(m+n),空间复杂度O(m+n)或O(1);推荐创建新数组实现,逻辑清晰、安全不修改原数组。

Java 合并两个已排序的整型数组,最常用且高效的方法是**双指针归并法**,时间复杂度 O(m + n),空间复杂度 O(m + n)(若需返回新数组)或 O(1)(若允许原地合并到其中一个数组中)。
方法一:创建新数组,双指针归并(推荐,清晰安全)
适用于大多数场景,不修改原数组,逻辑直观,不易出错。
- 初始化两个指针 i = 0(指向数组1)、j = 0(指向数组2),以及结果数组 res 和索引 k = 0
- 循环比较
nums1[i]和nums2[j],将较小值放入res[k++],对应指针前移 - 任一数组遍历完后,把另一个数组剩余元素直接复制过去
示例代码:
public static int[] mergeSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
int[] res = new int[m + n];
int i = 0, j = 0, k = 0;
while (i < m && j < n) {
if (nums1[i] <= nums2[j]) {
res[k++] = nums1[i++];
} else {
res[k++] = nums2[j++];
}
}
while (i < m) res[k++] = nums1[i++];
while (j < n) res[k++] = nums2[j++];
return res;
}
方法二:原地合并到 nums1(LeetCode 经典题型,nums1 有足够空间)
当 nums1 长度为 m + n,前 m 个有效,后 n 个为占位 0,可从后往前归并,避免覆盖。
立即学习“Java免费学习笔记(深入)”;
- 用三个指针:i = m-1(nums1 末尾有效数)、j = n-1(nums2 末尾)、k = m+n-1(nums1 真实末尾)
- 每次取较大值填入
nums1[k--],对应指针前移 - 若
nums2还剩元素,继续填入;nums1剩余部分已在原位,无需处理
注意事项与边界情况
- 空数组要单独判断(如
nums1或nums2长度为 0),否则指针越界 - 整型数组默认升序;若一个升序一个降序,需先反转或调整比较逻辑
- Java 中数组不可变长度,所以“合并”本质是生成新数组或复用已有大数组
- 如需去重合并,可在归并时跳过重复值(比较当前值与上一个写入值)
一行流?不建议
虽然可用 Stream.concat(Arrays.stream(a), Arrays.stream(b)).sorted().toArray(),但会丢失“已排序”这一前提优势,时间复杂度退化为 O((m+n) log(m+n)),仅适合极小数据或原型验证。


















