精选力扣500题 第22题 LeetCode 88. 合并两个有序数组【c++详细题解】

目录

      • 1、题目
      • 2、思路1
      • 3、代码1
      • 4、思路2
      • 5、代码2

1、题目

给你两个有序整数数组 nums1nums2,请你将 nums2 合并到 nums1中,使 nums1 成为一个有序数组。

初始化 nums1nums2的元素数量分别为 mn。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2的元素。

示例 1:

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

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]

提示:

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -109 <= nums1[i], nums2[i] <= 109

2、思路1

(二路归并) O ( n ) O(n) O(n)

  • 1、新开一个数组ans用来存贮合并后的有序元素
  • 2、定义两个指针i,和j分别指向nums1nums2,每次将两个指针所指向的较小的数添加到ans
  • 3、将ans数组赋值给num1

时间复杂度 O ( n ) O(n) O(n)

空间复杂度为: 由于新开了一个数组ans,因此空间复杂度为 O ( n ) O(n) O(n)

3、代码1

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

4、思路2

在上面二路归并算法中,需要临时一个构建一个数组,空间复杂度不是常数,通过观察题,没有充分利用题目所给的条件,nums1已经开够了足够大,如果直接在nums1上合并,便不需要额外的空间,而如果从前往后合并,则会覆盖元素得到错误结果,再通过观察,如果从后往前合并的方式,则不会覆盖,是理想的解法,时间 O ( n ) O(n) O(n),空间常数。

步骤如下

  • 1、初始化k = m + n - 1
  • 2、定义两个指针i,和j分别指向nums1nums2,每次将两个指针所指向的较大的数放在k的位置,同时i或者jk同时减1
  • 3、如果while(j >= 0)再将nums2中剩余的数放入nums1

5、代码2

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

原题链接:88. 合并两个有序数组

题目
精选力扣500题 第22题 LeetCode 88. 合并两个有序数组【c++详细题解】_第1张图片

你可能感兴趣的:(LeetCode,数据结构,leetcode,链表)