LeetCode HOT100 寻找两个正序数组的中位数

该博客探讨了一种改进的算法,用于在两个已排序的整数数组中找到中位数。算法首先尝试通过比较中间元素来优化查找过程,然后通过合并和排序两个数组的剩余部分来解决边界情况。这种方法适用于处理不同长度数组的中位数问题,尤其关注效率和准确性。
摘要由CSDN通过智能技术生成

在王道数据结构的课后算法题基础上改进的,感觉解法还是有点暴力=-=思路在注释里写清楚了

 

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
    if(nums1Size>nums2Size){//统一代码,保证数组1长度<=数组2长度
        int* p=nums1;nums1=nums2,nums2=p;
        int tmp=nums1Size;nums1Size=nums2Size,nums2Size=tmp;
    }
    int l1=0,r1=nums1Size-1,l2=0,r2=nums2Size-1,mid1,mid2;
    while(r1-l1>=2){//若短的数组只剩下两个,中位数可能为其平均值,故此处跳出循环,再用常规方式处理
        mid1=(l1+r1)/2,mid2=(l2+r2)/2;
        if(nums1[mid1]==nums2[mid2]){
        //如果待比较数组均为奇数长度,则中位数为两个中值的均值,此处两均值相等,可返回任意一个
        //如果两组数为一奇一偶,则奇数长度的mid对应的位置刚好是中位数
            if((nums1Size%2)||(nums2Size%2))
            return (double)nums2[mid2];
            else{
                //如果两组均为偶数长度,则对应的mid右侧比左侧元素多一个,需要比较两个mid右侧相邻元素的大小
                //最终取两个相邻元素的较小值与下标为mid的值取平均数,得到中位数
                int tmp= nums1[mid1+1]<nums2[mid2+1]?nums1[mid1+1]:nums2[mid2+1];
                return (1.0*tmp+1.0*nums1[mid1])/2;
            }
        } 
        if(nums1[mid1]<nums2[mid2]){
            //如果两组数据均为偶数长度,先各减去一个不影响结果的元素,讲其处理为奇数长度
            if((!(nums1Size%2))&&(!(nums2Size%2))){
                nums1Size-=1,nums2Size-=1,r2-=1,l1+=1;
            }else{
                //保证数组两侧裁去的长度相同,以短的(num1数组)为基准
                r2=r2-(mid1-l1);
                nums1Size-=(mid1-l1);
                nums2Size-=(mid1-l1);
                l1=mid1;
            }
        }else{
            //同上
            if((!(nums1Size%2))&&(!(nums2Size%2))){
                 nums1Size-=1,nums2Size-=1,r1-=1,l2+=1;
            }else{
                nums1Size-=(r1-mid1);
                nums2Size-=(r1-mid1);
                l2=l2+(r1-mid1);
                r1=mid1;
            }
        }
    }
    //上述算法剪枝能力有限,如未在循环中得到中位数,达到边界条件跳出循环后,需要通过常规算法求解
    int* f=(int*)malloc(sizeof(int)*(nums1Size+nums2Size));
    int i=0;
    while((l1<=r1)&&(l2<=r2)){
        if(nums1[l1]<nums2[l2])f[i++]=nums1[l1++];
        else f[i++]=nums2[l2++];
    }
    while(l1<=r1){
        f[i++]=nums1[l1++];
    }
    while(l2<=r2){
        f[i++]=nums2[l2++];
    }
    //依旧分奇数/偶数两种情况处理
    if((nums1Size+nums2Size)%2)return (double)f[(nums1Size+nums2Size)/2];
    else return (double)(f[(nums1Size+nums2Size)/2]*1.0+f[(nums1Size+nums2Size)/2-1]*1.0)/2;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值