复习leetcode第四题:寻找两个正序数组的中位数(C语言)

我的代码思路是先创建一个新整型数组arr,然后将nums1和nums2中的数存入arr中。(存入后代码是无序的,例如leetcode给出的第一种情况,arr数组中应该是{1,3,2})

易错点:但在使用循环存入时注意,arr的元素个数应该是nums1Size+nums2Size,因此存入时要小心,不要出现数组某一地址重新赋值的状况。

本题的难点在于排序判断中位数算法,分为了偶数个数字与奇数个数字两种中位数算法,但只需将这两个功能实现,本题便迎刃而解了。

        一.排序方法:

        本题笔者能立即想到的排序方法共有两种:选择法排序、冒泡法排序。

笔者在本文中会将两种排序方式一一讲述,读者可以选择最适合自己的排序方法。

        1.选择法排序

该方法简而言之,从数组第一个数字开始,与第一个数字以后的各数一一比较大小,找到数组所有数中的最小数,并移至数组的第一位;然后数组第二个数字重复上述操作,但无需再和第一个数字比较大小(由于第一次判断时,就已经判断出第一个数是最小数了,那么根据正序排序的需求,第一个数位置已确定,无需再次判断),诸如这样,判断到数组倒数第二个数字(由于最后一个数肯定是最大值,所以无需判断)。

for(int i=0;i<flag-1;i++)
    {
       int min=i;
        for(int h=i+1;h<=flag-1;h++)
        {
            if(arr[min]>arr[h])
            min=h;
        }
        int index=arr[i];
        arr[i]=arr[min];
        arr[min]=index;
    }

tips:如果需要实现倒序排放(最大值在首位),就将if语句中的‘>’变成‘<’即可,当然为了代码的可读性,最好将“min”换成“max”(故意让别人看不懂的情况除外)。

排序完,使用中间的那(一个/两个)数,进行中位数计算即可。

        2.冒泡法排序

该方法是从第一个数字开始,比较左右两数间的大小,小的数字在右就和左边那个大的数字交换位置,然后遍历至倒数第二个数字(原因与选择法排序相似);然后再次遍历,直至数组中的各数字是正序排序。

请读者自行尝试该方法,笔者在此偷个懒。(doge)

        二.判断中位数算法

判断中位数算法即是在判断数组中元素究竟是奇数个还是偶数个,那么可以创建一个整型变量flag,并flag=nums1Size+nums2Size。若flag%2==0即为偶数个算法,flag%2!=0即为奇数个算法。

int flag=nums1Size + nums2Size;
    if(flag%2==0)
    {
    //偶数个数字算法
    }
    else
    {
    //奇数个数字算法
    }

偶数个算法:

return((arr[flag/2-1]+arr[flag/2])/2.0);

奇数个算法:

return((double)arr[flag/2]);

因为arr是整型数组,所以要强制类型转换成double型

——————————————————分割线——————————————————————

上述方法时间复杂度较高,是暴力解题方式。通过参考csdn的各种文章,笔者学习了各种时间复杂度更低的解题方法,笔者将择其一讲解。

为方便讲解,给定nums1数组有三个元素,nums2数组有三个元素。并如下赋值,

nums1[0] = 1 , nums1[1] = 3 , nums1[2] = 5;

nums2[0] = 2 , nums2[1] = 4 , nums2[2] = 6;

创建一个整型数组nums3[nums1Size+nums2Size],以及给三个数组分别使用一个计数器,方便后续存入。笔者这边是定义了count1,count2,count3三个数组相对应的计数器(计数器即为定义一个整型变量count,然后赋初值为0)。

然后通过循环,将题目给的数组中的各元素放入;同时在放入时,使用if语句,判断两数组存入元素的大小,如果nums1存入的元素大,那么就先放入nums1中的元素,这时nums3已经存入一个元素,count3++,count1++;反之则count3++,count2++。

具体如下:

1.因为nums1[0] < nums2[0],所以nums3[0] = nums1[0] = 1,nums1下次判断用第二个元素,nums3下次赋值用第二个位置。

2.因为nums1[1] > nums2[0],所以nums3[1] = nums2[0] = 2,nums2下次判断用第一个元素,nums3下次赋值用第三个位置。

3.重复上述操作

……

n.直至全部赋值完,那么nums3 = {1,2,3,4,5,6}

于此同时,由于此法需要使用循环语句,同时nums1Size与nums2Size是题目给出的自变量,nums3中的元素个数是因变量,因此可能会出现(nums1/nums2)之一的数已经全部赋完了,所以循环退出条件可以是(count1>nums1Size或count2>nums2Size),接下来就把未赋完的那个数组中的各元素存入即可。

int count1 = 0;
    int count2 = 0;
    int count3 = 0;
    while(count1<nums1Size&&count2<nums2Size)
    {
        if(nums1[count1]<nums2[count2])
        {
            nums3[count3] = nums1[count1];
            count1++;
            count3++;
        }
        else
        {
            nums3[count3] = nums2[count2];
            count2++;
            count3++;
        }
    }
    while(count1<nums1Size)  
    {
        nums3[count3] = nums1[count1];
        count3++;
        count1++;
    }
    while(count2<nums2Size)
    {
        nums3[count3] = nums2[count2];
        count3++;
        count2++;
    }
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/weixin_45224842/article/details/119603535

最后的中位数算法已在上文中提过,此处省略

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值