LeetCode合并有序数组问题:C语言解法报错求排查
问题排查与修正方案
首先,你的代码有两个核心问题导致无法通过测试:
1. 从数组头部合并会覆盖nums1未处理的有效元素
题目明确nums1的总长度是m + n(前m个是有效元素,后n个是预留的空位置),但你从头部k=0开始合并时,会覆盖nums1中还没来得及比较的原始元素。举个实际测试用例的例子:
nums1 = [1,3,5,0,0,0], m=3; nums2 = [2,4,6], n=3
第二次循环时,nums1[1]的3会被nums2的2覆盖,后续再也无法访问到这个3,最终合并结果必然出错。
2. 函数返回值不符合声明要求
你的函数声明是void merge(...),说明不需要返回值,但代码最后写了return nums1;,这会触发编译警告甚至错误。
修正后的代码(从尾部向前合并)
正确的思路是从两个数组的尾部开始比较,把较大的元素放到nums1的尾部预留位置,这样完全不会覆盖任何未处理的有效元素:
void merge(int* nums1, int m, int* nums2, int n) { // 指向nums1有效元素的尾部 int i = m - 1; // 指向nums2有效元素的尾部 int j = n - 1; // 指向nums1最终数组的尾部(预留位置的最后一个) int k = m + n - 1; // 从后往前合并两个数组的有效元素 while (i >= 0 && j >= 0) { if (nums1[i] > nums2[j]) { nums1[k] = nums1[i]; i--; } else { nums1[k] = nums2[j]; j--; } k--; } // 如果nums2还有剩余元素,直接拷贝到nums1的前面位置 while (j >= 0) { nums1[k] = nums2[j]; j--; k--; } // nums1剩余的元素本来就在正确位置,无需额外处理 }
方案可行性说明
- 利用nums1尾部的预留空间,彻底避免了覆盖未处理元素的问题
- 当其中一个数组的元素全部处理完后,剩下的元素要么已经在正确位置(nums1的剩余元素),要么直接批量拷贝即可(nums2的剩余元素)
- 移除了无效的返回语句,完全符合
void类型函数的要求
内容的提问来源于stack exchange,提问作者Rohit Sharan
相关产品推荐
相关产品推荐

