LeetCode 88. 合并两个有序数组

目录

1.原题链接:

2.排序:

3.双指针:

4.代码实现:

①.C语言版:

②.C++版:

 5.逆向双指针:

6.代码实现:

①.C语言版:

②.C++版:

7.提交结果:

8.读书分享:


1.原题链接:

88. 合并两个有序数组

2.排序:

可以把数组 nums2 里面的所有元素放到 nums1 里面,然后再对 nums1 进行排序就可以了,这里可以使用快排( 时间复杂度为O(NlogN) )。因为 nums1 有 m+n 个元素,所以总的时间复杂度为O( (m+n)log(m+n) )

3.双指针:

如果要从左向右合并数组,为了防止存在值的覆盖,需要拷贝一个nums1数组,我们这里将其命名为copy,然后分别遍历三个数组,通过比较copy数组与nums2数组当前遍历到的元素,把更小的值放入nums1,直至nums1被遍历完。

但是,在遍历copy数组与nums数组时,可能存在一个数组已经遍历完,另一个数组还没有遍历完的情况。

这时,nums1数组还没有遍历完,后面还存在错误数据,所以需要把没有遍历的元素全部放到nums1尾部(因为没有遍历的数肯定>=已经遍历了的数)。时间复杂度为O(m+n)空间复杂度为O(m+n)


4.代码实现:

①.C语言版:

int min(int x,int y)
{
    return x<y?x:y;
}
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int n1=0,n2=0,tmp=0;
    int copy[m+n];
    for(int i=0;i<m+n;i++)//拷贝nums1数组里面的元素到copy数组里面
    {
        copy[i]=nums1[i];
    }
    while(n1<m+n && tmp<m && n2<n)
    {
        nums1[n1]=min(nums2[n2],copy[tmp]);
        if(nums1[n1]==copy[tmp])
            tmp++;
        else
            n2++;
        n1++;
    }
    //当一个数组遍历完,可能存在另一个数组没有遍历完的情况
    while(n2<n)//当num2数组没有遍历完
    {
        nums1[n1]=nums2[n2];
        n1++;
        n2++;
    }
    while(tmp<m)//当copy数组没有遍历完
    {
        nums1[n1]=copy[tmp];
        n1++;
        tmp++;
    }
}

②.C++版:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int n1=0,n2=0,tmp=0;
        vector<int> copy=nums1;
        while(n1<m+n && tmp<m && n2<n)
        {
            nums1[n1]=min(nums2[n2],copy[tmp]);
            if(nums1[n1]==copy[tmp])
                tmp++;
            else
                n2++;
            n1++;
        }
        //当一个数组遍历完,可能存在另一个数组没有遍历完的情况
        while(n2<n)//当num2数组没有遍历完
        {
            nums1[n1]=nums2[n2];
            n1++;
            n2++;
        }
        while(tmp<m)//当copy数组没有遍历完
        {
            nums1[n1]=copy[tmp];
            n1++;
            tmp++;
        }
    }
};

 5.逆向双指针:

对于合并这两个非递减排列的数组,最终的结果不就是值小的在前面,值大的在后面吗,那我从左往右遍历,把值小的放前面都可以,那我试试从右向左,把值大的放后面看看可不可以。时间复杂度为O(m+n)

6.代码实现:

①.C语言版:

int max(int x,int y)
{
    return x>y?x:y;
}
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    if(n==0)//当nums2没有要合并的数时
        return;
    if(m==0)//当nums1没有要合并的数时
    {
        for(int i=0;i<n;i++)
        {
            nums1[i]=nums2[i];
        }
        return;
    }
    int n1=m-1,n2=n-1,tail=(m+n)-1;
    while(n1>=0 && n2>=0)
    {
        //选择更大的值放入tail所指位置
        if(max(nums1[n1],nums2[n2]) == nums1[n1])
        {
            nums1[tail]=nums1[n1];
            n1--;
        }
        else
        {
            nums1[tail]=nums2[n2];
            n2--;
        }
        tail--;
    }
    while(n2>=0)
    {
        nums1[n2]=nums2[n2];
        n2--;
    }
    //不用判断n1是否大于等于0,因为直接在nums1上面操作的
}

②.C++版:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        if(n==0)//当nums2没有要合并的数时
            return;
        if(m==0)//当nums1没有要合并的数时
        {
            nums1=nums2;
            return;
        }
        int n1=m-1,n2=n-1,tail=(m+n)-1;
        while(n1>=0 && n2>=0)
        {
            //选择更大的值放入tail所指位置
            if(max(nums1[n1],nums2[n2]) == nums1[n1])
            {
                nums1[tail]=nums1[n1];
                n1--;
            }
            else
            {
                nums1[tail]=nums2[n2];
                n2--;
            }
            tail--;
        }
        while(n2>=0)
        {
            nums1[n2]=nums2[n2];
            n2--;
        }
        //不用判断n1是否大于等于0,因为直接在nums1上面操作的
    }
};

7.提交结果:

8.读书分享:

道德经·第三十三章》:

知人者智,自知者明。胜人者有力,自胜者强。

知足者富,强行者有志。不失其所者久,死而不亡者寿。 

解释:善于了解别人的人是明智,善于了解自己的人才最聪明。

           能够克服别人的人是有力量,能够克制自己的人才最强大。

           知道满足的人才能富有,努力不懈的人才最有志向。

           不丧失根基的人才能长久,身死而不朽的人才最长寿。

道德经·第三十四章》:

以其终不自为大,故能成其大。

由于它不自以为伟大,所以才能成就它的伟大。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值