Arithmetic problem | 求两个排序数组的中位数

题目如下:

两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n))。

样例

给出数组A = [1,2,3,4,5,6] B = [2,3,4,5],中位数3.5

给出数组A = [1,2,3] B = [4,5],中位数 3


解题思路:

注意,下述所说的中位数是思维上面的中位数位置,并不是真正的数组中位数。两个数组都是独立的并且不可重复元素已排序,在两个数组间寻找中位数一般需要知道总个数,但由于两个数组间可能存在相同元素,因此遍历出总个数后复杂度已经上升到O(m+n)的高度了,不符题意。从题意给出的O(log(m+n))可以推断出,此复杂度解法可以使用分治法,但在不知道总个数的情况下使用分治法对某个数组进行操作也是困难的,因此采用了动态规划。由于两个数组间存在并集关系,所以两个数组间的中位数可看做整体数组中位数的范围,如果数组a的中位数p1小于数组b的中位数p2,那么他们并集的中位数肯定在于[p1-a(n-1)]-[b(0)-p2]之间,可舍去a[0]-p1区间,可能有人会疑问,那么p2-b(n-1)能否舍去,当然是不能的,因为我们操作的是整个总数组,而不是并集数组,并不能判断中位数不在此区间。反之相反规律,如此反复取舍,每次将会舍去不必要的区间,并且p1与p2会无限接近并集数组中位数。】


思路实现代码如下:

void Method(int *s,int slen,int *e,int elen)
{
    int m=slen+elen,t,i=0,p=m&1?1:2;
    int u=0,q=0;
    int q1,q2,l1,l2;
    int *a,*b;
    slen>elen?Method(e,elen,s,slen),p=0:0;
    for(i=0; i<p; ++i)
    {
        t=m/2+1,l1=slen,l2=elen,
        a=s,b=e;
        i==1?q=u,--t:0;
        while(t)
        {
            l1==0?u=b[t-1],t=0:0;
            t==1?u=min(a[0],b[0]),t=0:0;
            t!=0?q1 = min(t / 2, l1),
                 q2 = t - q1,a[q1-1]>b[q2-1]?
                      b+=q2,l2-=q2,t-=q2:
                                      a[q1-1]<b[q2-1]?
                                      (a+=q1,l1-=q1,t-=q1):
                                      (u=a[q1-1],t=0):0;
        }
    }
    printf("%f\n",m&1?(double)u:(double)(u+q)/2);
}


  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值