从零学算法

88.给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。

  • 我的原始人解法:先处理一下特殊情况, 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];
          }
      }
    

你可能感兴趣的:(算法学习,算法,排序算法,数据结构)