二分查找&&二分中位数
Posted qq2210446939
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找&&二分中位数相关的知识,希望对你有一定的参考价值。
普通二分查找
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
至此我们可以写出这样的代码,还缺了点边界情况和终止条件。
那么极端情况是什么呢,ab序列都只有一个的时候,最终答案自然是小的那个,
那么跑一遍样例,看看有没有错,发现了死循环:
当a序列为3 5 ,b序列为4 时,ma=3,mb=4,ma的左边和mb的右边删无可删了,所以这算一种边界情况。
推广,当总序列只有三个元素时,算一种边界情况,那么最终答案肯定是三个数中间那个数,我的做法:出现两序列不等长的时候,让小的那个序列左指针右移一就行,然后就会回到第一种终止条件!
代码:
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 9 if(la==ra) 10 return a[ma]<b[mb]?a[ma]:b[mb]; 11 12 if(a[ma]==b[mb]) 13 return a[ma]; 14 15 if(a[ma]<b[mb]) 16 la=ma; 17 rb=mb; 18 if(ra-la!=rb-lb) 19 ra-la > rb-lb ? la++ :lb++; 20 bs(la,ra,lb,rb); 21 22 else if(a[ma]>b[mb]) 23 lb=mb; 24 ra=ma; 25 if(ra-la!=rb-lb) 26 ra-la > rb-lb ? la++ :lb++; 27 bs(la,ra,lb,rb); 28 29 30 int main() 31 32 cin>>n; 33 for(int i=1;i<=n;i++) 34 cin>>a[i]; 35 for(int i=1;i<=n;i++) 36 cin>>b[i]; 37 cout<<bs(1,n,1,n); 38 return 0; 39
输入的复杂度为O(n),查找的复杂的为O(logn),总复杂度为O(logn) (手动滑稽)。
以上是关于二分查找&&二分中位数的主要内容,如果未能解决你的问题,请参考以下文章