Leetcode 88:合并两个有序数组

Leetcode链接 : https://leetcode-cn.com/problems/merge-sorted-array/

问题描述:

  给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 使得 num1 成为一个有序数组。

      说明:

  • 初始化 nums1 和 nums2 的元素数量分别为 m 和 n
  • 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

示例:

输入:
  nums1 = [1,2,3,0,0,0], m = 3   nums2 = [2,5,6], n = 3 输出: 
  [1,2,2,3,5,6]

解题思路:

   数组一次遍历法:即反向遍历两个数组,每次获取两数组中的最大值,并按逆序在nums1中填充 ,程序时间复杂度O(m+n),空间复杂度O(1)。

   解题步骤:

  1.    建立整型变量i , j 表示当前nums1和nums2的位置点,起始位置i=m-1, j=n-1
  2.    建立整型变量k,表示在num1中插入值的位置,起始位置m+n=1
  3.    比较num1[ i ]<nums2[ j ]是否成立,成立则nums1[ k ]=nums2[ j ],k=k-1,j=j-1 ; 否则nums1[ k ]=nums1[ i ],k=k-1,i=i-1 ;
  4.    直到 num1 或 num2 全部遍历完,若num2先遍历完,则此时 num1 已经全部有序。若num1先遍历完,则将num2中剩余的k个元素仍有序,将他们依次插入nums1中的0~k-1位置,程序结束。

若对过程仍不理解,请结合以下程序执行图进行理解,假设有两个数组为

nums1 = [1,4,7,0,0,0], nums2 = [2,5,8]

 则程序执行过程如图所示:

该问题本质是寻找到当前剩余所有元素中的最大值然后插入nums1中,直到所有元素全部插完。

该问题C++实现代码

class Solution {
  public:
      void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
           int i=m-1;
           int j=n-1;
           int k=m+n-1;
           while(i>=0 && j>=0){
               if(nums1[i]<=nums2[j]){
                   nums1[k]=nums2[j];
                   j--;
                   k--;
               }else{
                   nums1[k]=nums1[i];
                   i--;
                   k--;
               }
           }
          while(j>=0){
              nums1[k]=nums2[j];
              k--;
              j--;
          }
      }
};

 

结束语:

此问题虽然只是一个简单的数组合并题,但仍有一些小的trick可供思考。因为本题要求的是原地插入nums1中,为何此处大小判别条件为:nums1[i]<=nums2[j],而不是nums1[i]<nums2[j],这两种条件都能保证程序输出正确的结果,这里卖个关子,希望有心的读者可以思考一下。

作图码字不易,如果对您有帮助,欢迎点击推荐关注(狗头)。。。

 
posted @ 2019-08-31 20:22  fancy_li  阅读(141)  评论(0编辑  收藏  举报