LeetCode88(力扣88):合并两个有序数组 C++(含有测试代码)多种思路与解法想详细

合并两个有序数组

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

说明:

初始化 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]

提示:

-10^9 <= nums1[i], nums2[i] <= 10^9
nums1.length == m + n
nums2.length == n

我的提交代码

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        vector<int>temp(nums1.begin(),nums1.begin()+ m);
        int p1 = 0, p2 = 0, t = 0;
   
        while (p2<n&&t<m)
        {
            if (nums2[p2] < temp[t]) {
                nums1[p1++] = nums2[p2++];
            }
            else {
                nums1[p1++] = temp[t++];
            }
        
        	while(p2 == n && t<m) {
                nums1[p1++]=temp[t++];
        	}
        	while (t==m && p2 < n) {
            	nums1[p1++]=nums2[p2++];
       		}
        }
        if (m == 0) {
            nums1 = nums2;
        }
        if (n == 0) {
            nums1 = nums1;
        }
    }
};

我的测试代码


#include<vector>
#include<iostream>
using namespace std;

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        vector<int>temp(nums1.begin(),nums1.begin()+ m);
        int p1 = 0, p2 = 0, t = 0;
   
        while (p2<n&&t<m)
        {
            if (nums2[p2] < temp[t]) {
                nums1[p1++] = nums2[p2++];
            }
            else {
                nums1[p1++] = temp[t++];
            }
        
        while(p2 == n && t<m) {
            nums1[p1++]=temp[t++];
        }
        while (t==m && p2 < n) {
            nums1[p1++]=nums2[p2++];
        }
        }
        if (m == 0) {
            nums1 = nums2;
        }
        if (n == 0) {
            nums1 = nums1;
        }
    }
};

Solution s;

int main() {
    vector<int>nums1;
    vector<int>nums2 = {1 };
    int m = 0, n = 1;
    s.merge(nums1, m, nums2, n);
    for (int i = 0; i < nums1.size(); i++)
    {
        cout << nums1[i];
    }
}
我的思想

使用vector新建一个数组,将nums1中的有效元素赋值到temp数组中.

共由三种情况:

  1. nums1和nums2都不为空.
    判断nums2和temp中的元素哪个小,将较小的数放到nums1中
  2. nums1为空
    那么最终的nums1等价于nums2
  3. nums2为空
    -那么最终的nums1还是原来的nums1
    在这里插入图片描述
官方题解:

官方题解没有C++版本,但是有三种思想:

  1. 两个数组合并后再排序

  2. 因为最终得到的结果为nums1原数组, 所以先将原来的数组复制一份.从头开始遍历(我用的就是这种思想)

  3. !!!(划重点啦)!!!

    从数组后面开始遍历,不用使用新的数组空间.不用担心从从后面赋值过来会将nums1的有效元素覆盖,因为nums1的长度至少是m+n的.
    在这里插入图片描述

我的代码优化:提交

//使用的官方题解三的思想
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int p1 = m - 1, p2 = n - 1, p = n + m - 1;

        while (p2 > -1)
        {
            
            if (p1 == -1) {
                while (p2>-1)
                {
                 nums1[p--] = nums2[p2--];
                }
                break;
            }
            if (nums2[p2] >= nums1[p1]) {
                nums1[p--] = nums2[p2--];
            }
            else
            {
                nums1[p--] = nums1[p1];
                nums1[p1] = -10000;
                p1--;
            }

        }
    }
};

我的代码优化:测试

#include<vector>
#include<iostream>
using namespace std;

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int p1 = m - 1, p2 = n - 1, p = n + m - 1;

        while (p2 > -1)
        {
            
            if (p1 == -1) {
                while (p2>-1)
                {
                 nums1[p--] = nums2[p2--];
                }
                break;
            }
            if (nums2[p2] >= nums1[p1]) {
                nums1[p--] = nums2[p2--];
            }
            else
            {
                nums1[p--] = nums1[p1];
                nums1[p1] = -10000;
                p1--;
            }

        }
    }
};

Solution s;

int main() {
    vector<int>nums1 = { 4,5,6,0,0,0 };
    vector<int>nums2 = { 1,2,3 };
    int m = 3, n = 3;
    s.merge(nums1, m, nums2, n);
    for (int i = 0; i < nums1.size(); i++)
    {
        cout << nums1[i];
    }
}

在这里插入图片描述

我的疑惑
我的题解三没有另外开数组空间复杂度为O(1),题解二另外开了一个数组temp空间复杂度为O(m),为什么题解三的内存消耗比内存二的内存消耗还大?求大佬解释解释,谢谢啦!

我学会了
1.边界处理的时候一定要小心小心再小心。注意数组越界
2.学会使用逆向思维,就比如此题的从后往前遍历就不用新开数组了,这样理论上就可以节省内存空间了.(实际运行结果求解求解求解)
3.C++使用vector数组简直不能再爽,这里推荐一篇文章:C++_vector操作

有不对或是可以改进的地方,有劳大佬指点指点!十分感谢呀

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页