LeetCode 88. 合并两个有序数组

文章介绍了两种方法来合并两个已排序的数组,保持结果不递减。第一种方法使用双指针和额外数组,第二种方法则直接在nums1数组的末尾操作,避免了额外空间。两种方法的时间复杂度均为O(m+n),但空间复杂度不同。
摘要由CSDN通过智能技术生成

题目描述

题目:合并两个有序数组,使其保持不递减的顺序排列。

样例
nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3;

合并后的nums1数组为:[1,2,2,3,5,6]

算法1

(双指针)

题目让从两个不递减数组中挑选元素,使其合并成一个不递减的数组,可以考虑归并排序的模型,使用两个指针i,j分别指向两个数组开头,逐个比较指针所指元素的大小,小的那个挑选出来。新开辟一个数组nums其大小为 m + n m + n m+n用来保存满足条件的元素。最后再将nums数组里的元素拷贝到nums1中。

时间复杂度

O(m+n)

空间复杂度

开辟了一个数组nums用来中转元素,所以空间复杂度是O(m+n)

C++ 代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = 0, j = 0;
        vector<int>temp(m+n);
        while((i < m) && (j < n)){
            if(nums1[i] < nums2[j]){
                temp.push_back(nums1[i]);
                i++;
            }
            else{
                temp.push_back(nums2[j]);
                j++;
            }
        }
        while(i < m)    temp.push_back(nums1[i]),i++;
        while(j < n)    temp.push_back(nums2[j]),j++;
        // 这里有个坑,由于temp默认初始化为0,所以拷贝时要将前面的元素略过。
        for(int i = 0; i < m + n; i++)
            nums1[i] = temp[i + m + n];
    }
};

算法2

(倒着放)

注意到题目中已经将nums1的大小设置为m+n了,而正着放会覆盖掉nums1中的元素,所以上面的方法额外使用了一个数组存放选中的元素。可以发现:倒着放的情况下,由于nums1后面n个元素都是0,所以不会存在元素被覆盖掉的现象,这样直接在原数组中操作,节省了空间。

时间复杂度

O(m+n)

空间复杂度

O(1)

C++ 代码

先考虑思路再考虑细节。确实是一个好的方法hh

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = m - 1, j = n - 1;
        for(int k = m + n - 1; k >= 0; k--){
            if(j < 0 || (i >= 0 && nums1[i] >= nums2[j]))  nums1[k] = nums1[i--];
            else    nums1[k] = nums2[j--];
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值