普通二分查找

 1 int bs(int L,int R,int x)
 2 {//在l到r区间上查找x,找不到就返回-1
 3     int l=L,r=R;
 4     while(l<=r){
 5         int m=l+r>>1;
 6         if(a[m]==x){
 7             return m;
 8         }
 9         else if(a[m]>x){
10             r=m-1;
11         }
12         else{
13             l=m+1;
14         }
15     }
16     return -1;
17 }

普通版很简单就不详细总结了

二分查找中位数

题意:给定长度为n的两个有序序列,求两个序列合并后的中位数

直接归并法,找到第(2n+1)/2数时停止并输出答案,复杂度为O(n)

但题目要求logn,我们就得换个思路了;

 

题目给的是两个有序序列,所以两个序列的中位数都可以O(1)求得,那么最终答案的中位数和这两个序列的中位数有什么关系呢?假设第一个序列叫a,中位数为ma,第二个是b,中位数为mb,他们的并集是c,最终答案为ans。

 

如果ma==mb,也就是说,ma的两端和mb的两端分别在ans的两端,ans也就是ma+mb>>1,也就是随便一个了

 

如果ma<mb,也就是说,a的中位数比b的要小,所以a的左边和b的右边可以不用考虑了,ans一定在ma与mb中间

 

如果ma>mb,情况同上,把b视作a,a视作b即可

 

那么每一次都可以删掉c的一半,直到达到终止条件(假装知到),复杂度就是O(logn)了!

 1 #include<iostream>
 2 using namespace std;
 3 int a[100010],b[100010];
 4 int n;
 5 int bs(int la,int ra,int lb,int rb){
 6     int ma=la+ra>>1;
 7     int mb=lb+rb>>1;
 8     if(a[ma]==b[mb]){
 9         return a[ma];
10     }
11     if(a[ma]<b[mb]){
12         bs(la,ra,lb,rb);
13     }
14     else if(a[ma]>b[mb]){
15         bs(la,ra,lb,rb);
16     }
17 }
18 int main()
19 {
20     cin>>n;
21     for(int i=1;i<=n;i++)
22         cin>>a[i];
23     for(int i=1;i<=n;i++)
24         cin>>b[i];
25     cout<<bs(1,n,1,n);
26 }
View Code

相关文章:

  • 2021-06-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-28
  • 2022-01-20
  • 2022-01-14
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-02
  • 2021-07-20
  • 2021-09-19
相关资源
相似解决方案