每日一题---OJ题2: 合并两个有序数组

嗨,小伙伴们,我们又见面啦!一起来看看今天的题目吧!准备好了吗? 我们开始咯!

emmm,文字不难理解,我们一起来画图吧!

数组num1有3个元素,分别为1,2,3,数组num1可存放元素的个数为6; 数组num2有3个元素

思路1: 将nums2中的数据直接保存到num1中,通过排序算法对nums1中所有的数据统一进行排序。

首先,定义两个变量i和j,初始的时候,i为nums1数组的末位置(下标为m),j指向nums2数组的首元素,(下标为0)。

将nums2数组中的元素拷贝到nums1数组中去,每拷贝完一次,i自增一次,j自增一次。
第一次:

第二次:

第三次:

当i超过nums1数组的长度,当j超过nums2数组的长度,循环结束。

部分代码如下:

 int i = m;
      int j = 0;
      while(j != nums2Size){
        nums1[i] = nums2[j];
        i++;
        j++;
      }
将nums2数组里面的元素全部拷贝到nums1数组中后,我们就可以开始排序啦,我采用冒泡排序。
所以,这道题的解法之一:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
      int i = m;
      int j = 0;
      while(j != nums2Size){
        nums1[i] = nums2[j];
        i++;
        j++;
      }

      for(int k = 1; k<=m+n-1; k++){
        for(int h = 0; h<= m+n-k-1; h++){
            if(nums1[h] > nums1[h+1]){
                int temp = nums1[h];
                nums1[h] = nums1[h+1];
                nums1[h+1] = temp;
            }
        }
      }
    }
那有没有另外一种思路呢? 答案是: 当然有!我们可以让两个数组合并的同时就让其排序!

思路二: 定义3个变量,分别为l1,l2,l3。其中,l1指向num1数组的最后一个有效元素,l2指向nums2数组的最后一个有效元素,l3指向num1数组的总长度。

从两个数组的最后一个有效数据开始从后往前进行比较,找较大的数,谁大就从nums1数组的最后一个位置从后往前放元素。
第一次比较: nums1[l1] < nums2[l2] , 因此将nums2[l2]的数据拷贝到num1数组的最后一个位置(nums1[l3])。拷贝完成后,l2自减一次,l3自减一次(l2--,l3--)。

第二次比较: nums1[l1] < nums2[l2], 那么把nums2[l2]的数据拷贝到nums1[l3]里面, l2自减一次,l3自减一次(l2--,l3--)。

第三次比较: nums1[l1] > nums2[l2], 那么把nums1[l1]的数据拷贝到nums1[l3]中,l1自减一次,l3自减一次(l1--,l3--)。

第四次比较: nums1[l1] < nums2[l2] ,(写成 nums1[l1] > nums2[l2] 也可以),因此,将nums2[l2] 的数据拷贝到nums1[l3]位置中,l2自减一次,l3自减一次(l2--,l3--)。

我们此时不难发现,nums2数组中的元素已经全部拷贝到nums1数组中,此时,nums1数组刚好有序。
诶诶诶,我还没看过瘾呢,再举一个例子呗!可以!满足你!
我们仍然定义3个变量,分别为l1,l2,l3。其中,l1指向num1数组的最后一个有效元素,l2指向nums2数组的最后一个有效元素,l3指向num1数组的总长度。

方法同上,这里不再赘述。
第一次比较:nums1[l1] > nums2[l2] , 将nums1[l1]的数据拷贝到nums1[l3]中, l1--,l3--

第二次比较: nums1[l1] > nums2[l2] , 将num1[l1] 的数据拷贝到nums1[l3] 中, l1--, l3--

第三次比较: nums1[l1] < nums2[l2] , 将 nums2[l2] 的数据拷贝到 nums1[l3] 中, l2--, l3--

第四次比较: nums1[l1] > nums2[l2] , 将 nums1[l1] 的数据拷贝到 nums1[l3] 中, l1--, l3--

此时,我们可以看到,指向nums1数组的l1已经走完了整个数组,而l2还没有走完,此时我们用while循环遍历nums2数组的元素,将其放入nums1数组中。
第五次:

第六次:

好啦,我们可以看到,当  l1>=0 &&  l2>=0 时, 会进入循环,当 l2先不满足条件时, 此时nums1数组已经完全有序, 当 l1 先不满足条件时, 说明 l2 还没有遍历完 nums2数组, 用 while循环 将nums2剩余的元素都拷贝到 nums1数组中。
整体代码如下:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
        int l1 = m-1;
        int l2 = n-1;
        int l3 = m+n-1;

        while(l1 >=0 && l2 >=0){
            if(nums1[l1] > nums2[l2]){
                nums1[l3] = nums1[l1];
                l3--;
                l1--;
            }else{
                nums1[l3] = nums2[l2];
                l3--;
                l2--;
            }
        }

        while(l2 >= 0){
            nums1[l3] = nums2[l2];
            l3--;
            l2--;
        }
}
好啦,今天就到这里啦,我们下期再见!
  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值