LeetCode88合并有序数组提交时出现未定义行为问题求助
LeetCode 88题《合并两个有序数组》提交报错原因分析
核心问题:数组越界访问触发未定义行为
你的代码存在非法数组下标访问的问题,这是导致提交时运行时错误的直接原因。问题出现在最后一个else if分支:
else if (iResult <= m && nums1[iResult - 1] <= nums2[iNums2] && nums1[iResult] > nums2[iNums2])
当iResult的值为0时,iResult - 1等于-1,此时访问nums1[-1]属于非法内存操作,触发未定义行为。本地测试未报错只是因为未定义行为的表现具有随机性,LeetCode判题环境严格检测到了越界问题。
测试用例执行过程复盘
针对测试用例nums1 = [2,0], m=1; nums2=[1], n=1,代码执行步骤如下:
- 初始化变量:
iNums1=0(nums1有效元素的最后下标),iNums2=0(nums2有效元素的最后下标),iResult=1(合并后数组的最后下标)。 - 第一次循环(
iResult=1):- 比较
nums2[0]=1和nums1[0]=2,1不大于2,跳过前两个分支。 - 检查最后一个分支:
iResult=1 <= m=1成立,但nums1[0] <= 1不成立,分支不执行。 iResult自减为0,进入下一轮循环。
- 比较
- 第二次循环(
iResult=0):- 循环条件
iResult>=0 && iNums2>=0成立。 - 再次比较
nums2[0]=1和nums1[0]=2,仍不满足前两个分支。 - 进入最后一个分支判断:
iResult=0 <= m=1成立,此时尝试访问nums1[iResult-1]即nums1[-1],触发数组越界,导致运行时错误。
- 循环条件
额外逻辑问题说明
代码中swap(nums2, nums1)的逻辑不符合题目要求:题目明确要求将nums2的元素合并到nums1中(nums1初始已预留足够容量),交换两个数组会直接替换nums1的内容,后续无法完成正确合并。
修复方案
合并两个有序数组的标准解法是从后往前遍历,直接将较大元素放到nums1的末尾,无需插入操作:
void Solution::merge(std::vector<int>& nums1, int m, std::vector<int>& nums2, int n) { int iNums1 = m - 1; int iNums2 = n - 1; int iResult = m + n - 1; while (iNums1 >= 0 && iNums2 >= 0) { if (nums1[iNums1] > nums2[iNums2]) { nums1[iResult--] = nums1[iNums1--]; } else { nums1[iResult--] = nums2[iNums2--]; } } // 处理nums2剩余的元素 while (iNums2 >= 0) { nums1[iResult--] = nums2[iNums2--]; } }
内容的提问来源于stack exchange,提问作者Александр Максаков
相关产品推荐
相关产品推荐

