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

使用双指针解LeetCode合并数组问题:for循环i=0后不递减?

问题分析与解决思路

你的代码并非i不再递减,而是触发了数组越界异常导致程序提前终止。问题出在条件判断的逻辑上:当ptr1变为-1(nums1的有效元素已全部处理完毕)时,你仍会执行nums1[ptr1]的访问操作,这在Java中会直接抛出ArrayIndexOutOfBoundsException,程序崩溃后自然无法继续执行后续循环。

核心问题点

原条件if(ptr2 < 0 || nums1[ptr1] > nums2[ptr2])存在逻辑漏洞:当ptr1 < 0但ptr2 >=0时,会先执行nums1[ptr1]的访问,直接触发越界异常。

修正方案

调整判断逻辑的优先级,先确保ptr1的合法性,再进行元素比较:

  • 优先判断ptr1是否还有未处理的元素,同时结合ptr2的状态和元素大小关系
  • 当ptr1已耗尽(<0),直接取nums2的剩余元素;当ptr2已耗尽,直接取nums1的剩余元素

修正后的代码

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int ptr1 = m - 1, ptr2 = n - 1;
        // 从nums1的末尾开始填充
        for(int i = m + n - 1; i >= 0; i--) {
            if (ptr1 >= 0 && (ptr2 < 0 || nums1[ptr1] > nums2[ptr2])) {
                // ptr1还有元素,且要么ptr2已耗尽,要么当前nums1元素更大
                nums1[i] = nums1[ptr1--];
            } else {
                // 要么ptr1已耗尽,要么nums2元素更大,取nums2的元素
                nums1[i] = nums2[ptr2--];
            }
        }
    }
}

额外优化说明

可以在循环中提前终止:当ptr2 < 0时,nums2的元素已全部处理完毕,nums1剩余的前m个元素本来就是有序的,无需继续循环,能减少不必要的迭代:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int ptr1 = m - 1, ptr2 = n - 1;
        int i = m + n - 1;
        while (ptr2 >= 0) {
            if (ptr1 >= 0 && nums1[ptr1] > nums2[ptr2]) {
                nums1[i--] = nums1[ptr1--];
            } else {
                nums1[i--] = nums2[ptr2--];
            }
        }
    }
}

这种写法更高效,因为当nums2的元素全部合并完成后,剩下的nums1前半部分已经是有序状态,不需要再处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:40:22