Leetcode.88题:归并有序数组

一、问题描述:

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:

  • The number of elements initialized in nums1 and nums2 are m and n respectively.
  • You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.

Example:

Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

Output: [1,2,2,3,5,6]

给定有序整型数组1和数组2,将数组2合并到数组1中变为一个新的有序数组。

已知数组1和数组2的初始元素数量分别为m和n。

假设数组1有足够的空间来储存来自数组2的额外元素。

二、问题思考:

方法一:暴力方法

将nums2中的元素与nums1的元素逐次比较(从后向前),找到元素当前位置,将其插入数组,再将后面的元素依次向后移动;

特点:基本思路,很容易想到,但操作起来太过麻烦

时间复杂度:最好情况下为O(n)(nums1中的最大元素小于nums2中的最小元素);

                    最差情况下为O(n+m*n)(nums1中的最小元素大于nums2中的最大元素);

空间复杂度:O(1)。

方法二:排序方法

直接将nums2的元素放入nums1中,再对nums1进行排序;

特点:思路特别简单,而且极易操作

时间复杂度:根据排序算法的选择而不同;

空间复杂度:O(1)。

方法三:逐个比较法

创建一个新数组,比较两个数组中的元素,将较小的元素放入新数组中;

特点:两个数组各遍历1次即可完成,但需要额外空间;

时间复杂度:O(m+n);

空间复杂度:O(m+n)。

方法四:从后向前直接合并

从后向前比较两个数组,将较大的数插入nums1的末位,依次向前;

特点:不容易想到,比较后每个元素放入的位置都是最后的位置,时间和空间上都是最优;

时间复杂度:O(m+n);

空间复杂度:O(1)。

代码实现:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    
    int k = m + n - 1;
    int i = m - 1;
    int j = n - 1;
    
    while(k >= 0){    
        //注意处理边界问题
        if(i < 0 || j < 0)
            break;

        if(nums1[i] >= nums2[j]){
            nums1[k] = nums1[i];
            i--;
        }
        else if(nums1[i] < nums2[j]){
            nums1[k] = nums2[j];
            j--;
        }
        k--;
    }

    /*   注意处理当nums1的元素处理完成而nums2的元素还未就位
         nums1 = {3,4,5,0,0,0}
         nums2 = {1,2,6}
    */

    while(j >= 0){
        nums1[i + j + 1] = nums2[j];
        j--;
    }

}

猜你喜欢

转载自blog.csdn.net/qq_37348221/article/details/101972809
今日推荐