- 我的原始人解法:先处理一下特殊情况, n = 0 直接 return 即可, m = 0 的话直接把 nums2 给 n1 即可。接着就是用双指针,慢指针指向要插入的 nums2 中的数字,如果发现 nums1 中某个数大于慢指针指向的数,比如示例 1 中
nums1[2]
(也就是 3) 大于nums2[0]
(也就是 2) 了,就让 nums1 从数字 3 开始整体后移一位,插入 2 并更新慢指针为。或者如果快指针已经指向了 nums1 中不需要处理的数字了(换言之,nums1 中的 m 个数字已经合并完了),那就直接插入 nums2 -
public void merge(int[] n1, int m, int[] n2, int n) { if(n == 0){ return; } if(m == 0){ for(int i=0;i<m+n;i++){ n1[i]=n2[i]; } return; } for(int i=0,j=0;i<m+n && j<n;i++){ if(n1[i]>n2[j]){ for(int k=m+n-1;k>=i+1;k--){ n1[k] = n1[k-1]; } n1[i] = n2[j]; j++; // 每合并一个 i 就要多往后移一位才算是处理完了 nums 1 中的数组 // 因为 nums [1] 中要处理的数字被往后移了一位 }else if(i >= m+j){ n1[i] = n2[j]; j++; } } }
- 在我解的时候,感觉与其每次发现 nums2 有比 nums1 大的数就让 nums1 整体后移给 nums2 让位置,还不如用一个辅助数组记录每个数字应该在的位置,最后把值赋给 nums1 即可。看完他人题解发现好像这就是归并排序。具体实现也是用两个指针 i,j 记录 nums1 和 nums2 当前指向,每次比较 nums1[i] 和 nums2[j],大的那个把值给辅助数组然后指针 + 1。但是如果 nums1 的值加完了,那就直接加 nums2 即可,nums2 加完了同理。
-
public void merge(int[] nums1, int m, int[] nums2, int n) { int temp[] = new int[m + n]; int index = 0; int i = 0; int j = 0; while (i + j < m + n) { // nums1 加完了 if(i >= m){ temp[index++] = nums2[j++]; // nums2 加完了 }else if(j >= n){ temp[index++] = nums1[i++]; }else if (nums1[i] <= nums2[j]) temp[index++] = nums1[i++]; else temp[index++] = nums2[j++]; } for (int k = 0; k < m + n; k++) { nums1[k] = temp[k]; } }