Q:
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.
来解释下题干先(这题看着特简单,其实有些小细节扣一下,发现点儿tricky):
- m和n,是有效数字。比如int[] nums1 = [1,2,3,4], m =2。那么这里我们只考虑前两个sorted数字。
- 对于测试用例 { [1,2,3,5] 2, [2,4,5,7] 4 }。这个不行,m+n超过nums1的长度了。
- 虽然说是结果不会大于m+n,但其实换个说法,length of result不会大于m的值。
A:
这个代码写的比较平铺直叙,但是不够精简:
- 如果A,B数组的index值用其它字母表示,可以原地--,少些几行n--, m--。
- 另外,其实没必要再判断一个
else if(m>0)
。比如测试用例 { [3,7,9,10] 1, [1,2,3,4] 3 } 其实第一次比较的是nums1的3和nums2里的3,那么执行到else if(m>0)
, 就是先把nums1里的3放到nums1[3]的位置,然后回到for loop开始,再继续。之后,m=0,for loop后续的所有操作都是执行最后一个else if(n>0)
里的内容。得到[1,2,3,3]。
如果把第二个else if(m>0)
删掉,一旦出现相同数字3的时候,就把nums2里的3放进去,nums1那个值(3)留着下次用,反正两个都是sorted array,下一趟for loop,肯定是把nums1的3和nums2的3紧挨着放。
还有就是如果nums2为空,for loop里的判断全都失效了,自然是直接返回nums1的原有内容。
另外,最基础的概念:
- if是判断语句,while是循环。本质差别。
-
if(); else if(); else if();
这样的语法,只执行其中一个,都满足的话,只执行第一个。如果第一个不满足,后两个满足,那只执行第二个。
public void merge(int A[], int m, int B[], int n) {
for(int i = m+n-1; i>=0; i--)
{
if( m>0 && n>0) //两个数比较大小
{
if(B[n-1] > A[m-1])
{
A[i] = B[n-1];
n--;
}
else
{
A[i] = A[m-1];
m--;
}
}
else if(m>0) //当两个数一样的时候
{
A[i] = A[m-1];
m--;
}
else if(n>0)
{
A[i] = B[n-1];
n--;
}
}
}
精简版本 (no AC,Finshed all run custom testcase):
public void merge(int A[], int m, int B[], int n) {
int mi = m-1;
int ni = n-1;
for(int i = m+n-1; i>=0; i--)
{
if( mi>=0 && ni>=0) //因为在操作index值,所以要考虑 =0 的情况
{
if(B[ni] > A[mi])
{
A[i] = B[ni--];
}
else
{
A[i] = A[mi--];
}
}
else if (ni>=0) //当两个数一样的时候
{
A[i] = A[ni--];
}
}
}
Submit 时的这个OJ test case 神经病,另外上面这个还有(Runtime Limited Exceeded报错过):
这个用的while loop,思路同上,AC,精简:
public void merge(int A[], int m, int B[], int n) {
int i=m-1;
int j=n-1;
int k = m+n-1;
while(i >=0 && j>=0)
{
if(A[i] > B[j])
A[k--] = A[i--];
else
A[k--] = B[j--];
}
while(j>=0)
A[k--] = B[j--];
}