You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode合并两个升序数组:为何需复制结果到nums1?有何优化方案?

关于LeetCode「合并两个升序数组」的代码疑问解答

你的Java实现代码如下:

class Solution{
public static void merge(int[] nums1, int m, int[] nums2, int n) {
    int[] result = new int[m + n];
    int i = 0, j = 0, k = 0;
    while (i < m && j < n) {
        if (nums1[i] < nums2[j]) {
            result[k++] = nums1[i++];
        } else {
            result[k++] = nums2[j++];
        }
    }
    while (i < m) {
        result[k++] = nums1[i++];
    }
    while (j < n) {
        result[k++] = nums2[j++];
    }
    System.arraycopy(result, 0, nums1, 0, m + n);
  }
}

1. 为什么必须将result数组的内容复制到nums1中?

这是题目明确要求的:LeetCode该题规定合并后的升序数组必须存储在nums1里,而非返回新数组。题目给出的nums1数组长度本身就是m+n,已经预留了足够空间容纳所有合并后的元素,判题器会直接检查nums1的最终状态来判断答案是否正确。如果不把结果拷贝到nums1,判题器会认为你没有完成题目要求的输出目标。

2. 是否有更优的实现方案?

有,从后往前双指针法是更优的方案,它可以把空间复杂度从你的实现的O(m+n)降到O(1),不需要额外开辟result数组:

  • 利用nums1末尾的空闲位置(下标从m到m+n-1的区域),从两个数组的有效元素末尾开始比较
  • 将较大的元素直接放到nums1的当前最末尾位置,逐步往前填充
  • 这样不会覆盖nums1中还未处理的有效元素,完全原地操作

实现代码如下:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i = m - 1; // nums1有效元素的末尾下标
        int j = n - 1; // nums2有效元素的末尾下标
        int k = m + n - 1; // 合并后元素要放置的末尾下标
        
        while (i >= 0 && j >= 0) {
            if (nums1[i] > nums2[j]) {
                nums1[k--] = nums1[i--];
            } else {
                nums1[k--] = nums2[j--];
            }
        }
        
        // 如果nums2还有剩余元素,直接拷贝到nums1的前面
        while (j >= 0) {
            nums1[k--] = nums2[j--];
        }
    }
}

3. 直接打印result数组时出现超时问题是怎么回事?

LeetCode的判题环境对IO操作限制很严格,大量的打印输出会占用额外的IO资源。如果测试用例规模很大(比如m和n都是十万级别),打印数组的每个元素会导致IO耗时超过题目规定的时间限制,从而触发超时。另外,判题器根本不需要你打印结果,它只检查nums1的最终状态,所以提交代码时绝对不要加打印语句。

内容的提问来源于stack exchange,提问作者shivam0277

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:04:57