详解二分算法

                                                                                                                 详解二分算法

                                                                                                 Powered by WSY in SSF

                                                           2019-11-02  14:23:05

【1】定义

二分算法,顾名思义,就是把一个数列或数组分一下,分成两段。那么究竟什么情况下比较适合使用二分算法,二分算法能用于哪些领域呢?

先来举一个例子:

(奥数)你有10枚古罗马硬币,但是有一枚被一个小偷给掉包了(假硬币要更轻一些),于是你把这些硬币送到当地的警察局(局长超级Lazy),他们只是告诉你那枚假硬币上面有小偷的指纹,而且你只有一个天平,那么你最少需要称几次,才能找出那枚假硬币的呢?

解:4次

相信通过这道奥数题大家已经无形中运用到了二分的算法。但是值得注意的是,二分查找只能用于有序数列

二分查找流程

【2】比较次数

计算公式:
 
当顺序表有n个关键字时:
查找失败时,至少比较a次关键字;查找成功时,最多比较关键字次数是b。
注意:a,b,n均为正整数。
 
二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x.
时间复杂度无非就是while循环的次数!
总共有n个元素,
渐渐跟下去就是n,n/2,n/4,....n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数
由于你n/2^k取整后>=1
即令n/2^k=1
可得k=log2n,(是以2为底,n的对数)
所以时间复杂度可以表示O(h)=O(log2n)
折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。它的基本思想是:(这里假设数组元素呈升序排列)将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止;如 果x<a[n/2],则我们只要在 数组a的左半部继续搜索x;如果x>a[n/2],则我们只要在数组a的右 半部继续搜索x。
 
C++代码模板:
int r=0;//右边的变量 
int l=n-1;//左边的变量 
while(r<l)//满足条件时进入循环 
{
    int mid=(r+l)/2;//二分查找的精华所在:mid变量用来得到每次二分后的位置 
    if (a[mid]==ans) return mid;//如果成功就结束了 
    else if(a[mid]>ans) r--;//否则调整 
    else l++; 
}

例题:

农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi<= 1,000,000,000). 但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?

源码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+3;
int n,m,x[N];
inline bool check(int d)
{
    int cow=1;
    int rgt=x[1]+d; for(int i=2;i<=n;++i) { if(x[i]<rgt) continue; ++cow; rgt=x[i]+d; } return cow>=m; } int main() { cin>>n>>m; for(int i=1;i<=n;++i) cin>>x[i]; std::sort(x+1,x+n+1); int l=0,r=x[n]-x[1]; while(l<=r) { int mid=l+r>>1; if(check(mid)) l=mid+1; else r=mid-1; } cout<<r<<endl; return 0; }

本文结束,望大家多多支持!

猜你喜欢

转载自www.cnblogs.com/Monach/p/11782284.html