public class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
//虽然题目要求返回排序的结果是nums1,但是可以新开一个数组,到时候赋值给nums1就行
//要不然直接在nums1上移动修改太麻烦,而且浪费时间
int[] res = new int[nums1.length];
int i = 0, j = 0, counter = 0;//用counter来记录合并后数组每次的位置
while(i < m && j < n){//nums1与nums2皆还有元素
if(nums1[i] <= nums2[j]){
res[counter++] = nums1[i++];
}
else{
res[counter++] = nums2[j++];
}
}
while(i < m){//nums1还没读完,while(i < m)而不是if(i < m)
res[counter++] = nums1[i++];
}
while(j < n){//nums2还没读完,while(j < n)而不是if(j < n)
res[counter++] = nums2[j++];
}
//nums1 = res;//这样修改不了实参的nums1不行,因为传进来的nums1其实只是对传入的实参的引用的拷贝
//在方法内部修改了nums1的引用的值,但因为方法内部的nums1只是一个拷贝,再修改也只是修改了拷贝的东西的地址
//所谓传入的是一个对象,是因为引用持有的是一个对象,可以通过拷贝的引用的值来修改对象(即传入方法的实参对象)
//但直接修改引用是修改不了对象的
//所以Java传入方法的过程中其实都只是值传递
//(基本类型只是一个值,不能通过方法来修改,包装类型和String虽然是引用,但定义时规定了不允许修改)
//(引用也只是传入的对象的引用地址的拷贝)
for(int t = 0; t < m + n; t++){//这样才能修改
nums1[t] = res[t];
}
}
}
解法二(换一种思路):
public class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
//解法二:解法一中说直接在nums1上进行移动不好操作是因为想法是从nums1的第一个元素往后放
//现在换一种思路,从nums1的第m+n个元素往前放,就好移动了
int i = m - 1, j = n -1, counter = m + n -1;//用counter来代表存的nums1结果的位置
while(i >= 0 && j >= 0){//nums1与nums2都还没走完
if(nums1[i] >= nums2[j]){
nums1[counter--] = nums1[i--];
}
else{
nums1[counter--] = nums2[j--];
}
}
/*while(i >= 0){//nums1没走完
nums1[counter--] = nums1[i--];
}*///写完后发现这一段没用,因为nums1没走完时,把前面的部分counter与i是相同的值,已经修改好了,没有意义
while(j >= 0){//nums2没走完
nums1[counter--] = nums2[j--];
}
}
}