2个有序数组,查询第k个,二分

2、如果A+B的数组大小大于k

二分法,考虑A的前一半m/2和B的前一半n/2,

假设A[mid]<B[mid]:

如果m/2+n/2大于k,则表明第k大存在于A和B的前一半中;否则,只需在A的m/2之后的数和B中找第k-m/2大的数;

假设A[mid]>B[mid]:

如果m/2+n/2大于k,则表明k存在于A和B的前一半中;否则,只需在B的n/2之后的数和A中找第k-n/2大的数;

递归实现即可;

代码:

复制代码

 


#include<iostream>

using namespace std;

// if length of A && length of B >=k
// k is power of 2 
int FindKthElem_1(int A[],int aLeft,int aRight,int B[],int bLeft,int bRight,int k){
    /*
    if(aLeft>aRight)
        return B[bLeft+k-1];
    if(bLeft>bRight)
        return A[aLeft+k-1];
    */
    if(k==1){
        if(A[aLeft]>B[bLeft])
            return B[bLeft];
        else
            return A[aLeft];
    }

    int aKth=aLeft+(k>>1)-1;
    int bKth=bLeft+(k>>1)-1;

    if(A[aKth]<B[bKth])
        return FindKthElem_1(A,aKth+1,aRight,B,bLeft,bRight,(k>>1));
    else
        return FindKthElem_1(A,aLeft,aRight,B,bKth+1,bRight,(k>>1));
}

// if length of A + length of B >=k
int FindKthElem_2(int A[],int aLeft,int aRight,int B[],int bLeft,int bRight,int k){
    if(aLeft>aRight)
        return B[bLeft+k-1];
    if(bLeft>bRight)
        return A[aLeft+k-1];

    int aMid=aLeft+((aRight-aLeft)>>1);
    int bMid=bLeft+((bRight-bLeft)>>1);

    int halfLen=aMid-aLeft+bMid-bLeft+2;  // 个数k

    if(A[aMid]<B[bMid]){
        if(halfLen>k){   // 说明前一半中>k   必然存在于 A 和 B 的前一半中
            return FindKthElem_2(A,aLeft,aRight,B,bLeft,bMid-1,k);  // k 值是变化的
        }
        else{
            return FindKthElem_2(A,aMid+1,aRight,B,bLeft,bRight,k-(aMid-aLeft+1)); //数组A的前面的个数
        }
    }
    else{
        if(halfLen>k){
            return FindKthElem_2(A,aLeft,aMid-1,B,bLeft,bRight,k);
        }
        else{
            return FindKthElem_2(A,aLeft,aRight,B,bMid+1,bRight,k-(bMid-bLeft+1));
        }
    }
}

int main(){
    int A[]={1,2,3,7,8,9};
    int B[]={4,5,6,10,11,12};

    int aLen=sizeof(A)/sizeof(A[0]);
    int bLen=sizeof(B)/sizeof(B[0]);

    int k;
    while(true){
        cout<<"Please Input k:"<<endl;
        cin>>k;
        cout<< FindKthElem_1(A,0,aLen-1,B,0,bLen-1,k) <<endl;
        cout<< FindKthElem_2(A,0,aLen-1,B,0,bLen-1,k) <<endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值