C#解LeetCode88合并有序数组 提交结果与多环境输出不一致
C#求解LeetCode 88.合并有序数组提交失败问题
- 实现思路:尝试结合for循环与while循环完成逻辑,题目要求合并后的有序结果直接写入传入的
nums1数组,无需返回值。
相关信息
- 题目要求:

- 测试用例:
nums1 = [0], m = 0, nums2 = [1], n = 1 - LeetCode Playground运行结果:

- Visual Studio本地运行结果:

- LeetCode提交判题结果:

提交的实现代码
public void Merge(int[] nums1, int m, int[] nums2, int n) { if (m == 0) { Console.WriteLine("Num 1 Before: {0}", nums1[0]); nums1 = (int[])nums2.Clone(); Console.WriteLine("Num 1 After: {0}", nums1[0]); } else if ( n != 0 ) { int arrTwoIt = 0; for ( int i = m; i <m+n; i++) { nums1[i] = nums2[arrTwoIt++]; } int arrOneIt = 0; arrTwoIt = m; while (arrOneIt < m) { if (nums1[arrOneIt] > nums1[arrTwoIt]) { int leftItemTemp = nums1[arrOneIt]; nums1[arrOneIt] = nums1[arrTwoIt]; nums1[arrTwoIt++] = leftItemTemp; } arrOneIt++; } } }
问题现象
同一份代码在LeetCode Playground、Visual Studio本地环境运行时,控制台输出均符合预期,但提交到LeetCode判题系统后返回结果不符合要求,无法定位问题。
问题根因
1. 直接给数组参数重新赋值不会修改原数组
这是导致m=0测试用例判题失败的核心原因:
C#中数组是引用类型,不带ref/out修饰的方法参数,传递的是引用的副本。你在m==0分支中执行nums1 = (int[])nums2.Clone();时,仅仅是将方法内部的局部参数变量指向了新克隆的数组内存,完全没有修改判题系统传入的原始nums1数组的内容。
你在方法内打印nums1[0]看到1,是因为打印的是局部变量指向的新数组的值;如果在方法调用结束后,打印传入的原始nums1数组的第一个元素,会发现它还是初始值0,这就是判题系统读到的错误值。
2. 数组合并排序逻辑存在缺陷
就算修复了上面的赋值问题,现有合并逻辑也无法通过所有用例:你先把nums2的元素拼接到nums1尾部,再通过单次遍历交换相邻元素的方式,根本无法完成两个有序数组的合并排序。例如用例nums1 = [4,5,6,0,0,0], m=3, nums2=[1,2,3],n=3,拼接后数组为[4,5,6,1,2,3],单次遍历交换后得到的是[1,5,6,4,2,3],完全不符合有序要求。
修复方向
- 针对
m==0的场景,不要重新给nums1变量赋值,而是遍历nums2将元素逐个拷贝到原始nums1数组的对应下标位置:
if (m == 0) { for(int i = 0; i < n; i++){ nums1[i] = nums2[i]; } return; }
- 替换错误的排序逻辑,推荐使用双指针从两个数组的有效尾部开始遍历,从后往前填充
nums1的空间,不需要额外数组,时间复杂度为O(m+n),是这道题的标准最优解法。
内容的提问来源于stack exchange,提问作者Wasif Islam
相关产品推荐
相关产品推荐

