力扣数据结构入门题目:合并两个有序的数组

力扣第88题

思路:头双指针、尾双指针

头双指针

对比于队列,队列是先进先出,由于我们遇到的是两个有序数组。所以,对于两个数组,我们只需要依次分别判断两个数组的头指针位置所指的元素大小,将小的元素先放入数组中。由于题目要求将新的数组放在nums1中,所以,使用头指针直接将元素放入到nums1中,会把nums1中的元素覆盖。解决方法:新开辟一个地址空间,大小为nums1的大小,用于暂时存储排序后的数组,最后for循环赋值。
对于思路很好理解,具体的实现方法,到自己手上又等了很久才想到。主要是逐步运算过程中出现的一些情况处理;普通的情况就是,nums1[i]与nums2[j]大小对比;哪个小,那个就放进数组中;但是在运算过程中,总会出现一个数组的值全部处理完之后的结果。所以需要加入判断条件:if(i == m),if(j == n);这时候的一个情况处理
具体看代码:

//正向双指针解法
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
//nums1Size和nums2Size是不需要用到的,迷惑我们的
//我刚开始用了nums1Size,一直报错
    int i = 0, j = 0, a=0;  //a是新数组的下标值
    //新开辟的地址空间用于存储处理后的数组
    int sorted[m+n];
    while(i < m || j < n){
    //首先要判断nums1和nums2数组是否已经全部遍历
        if(i == m){
            sorted[a++] = nums2[j++];
        }else if(j == n){
            sorted[a++] = nums1[i++];
            //这里是原本的双指针处理方法
        }else if(nums1[i] < nums2[j] ){
            sorted[a++] = nums1[i++];
        }else{
            sorted[a++] = nums2[j++];
        }
        //sorted[i+j-1] = a;
    }
    //for循环给nums1进行赋值
    for(i = 0; i != m+n; ++i){
        nums1[i] = sorted[i];
    }
}

尾双指针

从头指针可以发现对nums1来说,需要重新开辟一个新的地址空间。尾双指针可以解决这个问题。因为nums1后m个位置为空,所以,可以利用nums1尾部没有利用到的空间进行,那这里使用尾双指针。

思路

跟头双指针的思路基本一致,仍然需要对一个数组已经遍历完的情况进行处理。
**注意点:**对于nums1下标值的处理,刚开始我是直接使用的nums1[i+j-1];后来发现一直报错,缓存溢出,找了很久没找到错误,跟正确答案对比了之后,发现自己的下标值其实是错的,因为 i 和 j 都已经减了1,再去用nums1的尾指针指向值不是最后一个,所以要修改一下

具体看代码:

//逆向双指针解法
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int i = m-1, j = n-1, a;
    int tail = n + m -1;
    while(i >= 0 || j >= 0){
        if(i == -1){
            a = nums2[j--];
        }else if(j == -1){
            a = nums1[i--];
        }else if(nums1[i] < nums2[j] ){
            a = nums2[j--];
        }else{
            a = nums1[i--];
        }
        //注意不能用首位双指针的方法进行i+j-1
        //前面,i, j 都已经减1,然后运行过程中又减了一个1,所以需要+2
        //或者是nums1[tail--] = a;
        nums1[i+j+2] = a;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值