寻找两个有序数组的中位数 C语言 就怕你不会

反正作为菜鸡的我 这道题是真真正正难住了我,找了无数题解 看了n遍代码 才真正搞懂 所以我决定要好好把这道题撕一撕。
先把解析资料放这

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
是不是资料看得头大 让我通俗的讲一讲:

  • 第一点
    对于合并后的数组,其前一半的数组是不是肯定有前n个A数组中的数和前m
    个B数组中的数组成,我要是能确定n和m是不是肯定能得出答案 ps:m+n是定值是Asize+Bsize的一半
    所以肯定是有限个组合 所以只要n从1到Asize+Bsize的一半,就可以全部找出这些组合
  • 第二点 如何确定某一个组合不合适
    在这里插入图片描述

ai 和bj都要小于等于 ai+1 和bj+1这样才是合适的 否则不是合适的?想想为什么 从合并的角度出发

这是代码和注释

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
     if(nums1Size>nums2Size)//确保二分查找的次数最少
     {
         return findMedianSortedArrays(nums2,nums2Size,nums1,nums1Size);
     }
     int high = nums1Size;//一共这么多的插入点,比数据多一
     int low  = 0;
     int m = (nums1Size+nums2Size+1)/2;//这个点要学习,可以在偶数时找到一半奇数时找到一办加1
     while(low<=high)
     {
         int i =(high+low)/2;//这个是找到分割点哦,注意第i个分割点前面有i个数据
         int j = m-i;//j是第二个序列取的数 注意:是第几个 所以引用时要【j-1】
        if (j != 0 && i != nums1Size&& nums2[j-1] > nums1[i]){ // i 需要增大
                low = i + 1; 
            }
            else if (i != 0 && j != nums2Size&& nums1[i-1] > nums2[j]) { // i 需要减小
                high = i - 1; 
            }
           else//到达这一步就有两种可能,要不就是找到了,要不就是特殊情况
           {
               //接下来就是分情况讨论1,特殊情况 2,一般情况   然后每种情况分奇偶两种情况
               //但后来发现可以合并  
               //注意:以下代码是精简过的 把情况给合并了,因为总数奇数时中位数只看左边,所以只要担心左边的元素会不会越界小于零,偶数时要看右边,所以要考虑是否越界
             double   leftmax = 0;
            
               if(i == 0)//
               {
                    leftmax = nums2[j-1] ; //此处建议用个图画一画 别太相信自己的想象力
               }
               else if(j == 0)
               {
                   leftmax = nums1[i-1];
               }
               else{
                   leftmax = nums2[j-1]>nums1[i-1]?nums2[j-1]:nums1[i-1];
                   //大的数字排的更靠近中位数 不懂的话想想如果把他们归并排序是不是这样
               }


               if((nums1Size+nums2Size)%2==1) 
               return leftmax;//中位数要么是最左边的(当总数是奇数)要么是左边最大和右边最小  肯定先判断奇数
               double rightmin = 0;

               if(i == nums1Size)
               {
                   rightmin = nums2[j];
               }
               else if(j == nums2Size)
               {
                   rightmin=nums1[i];
               }
               else{
                   rightmin = nums1[i]<nums2[j]?nums1[i]:nums2[j];
               }
               return (rightmin+leftmax)/2.0;
           }
         
     }
return 0.0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值