二分搜索

怎么说呢,二分我之前就是太害怕它了,开始学的时候在知乎上到二分有64种写法,一下被吓着了,才一直搁到现在才学。

主要思想大家都明白,就是代码实现起来有问题。

个人认为,二分最后可以归结为三种问题(假设序列不下降,参数均为区间[l,r]):

1. 是否存在x。

如果A[mid]==x 即为找到,返回mid位置即可;

如果A[mid]>x说明当前位置大了,可以确定x在[l,mid-1]区间内,因此 执行r = mid-1即可;

如果A[mid]<x说明当前位置小了,可以确定x在[mid+1,r]区间内,因此执行l = mid+1即可;

int binary_sreach(int A[],int l,int r,int x){
    int mid;
    while (l<=r) {
        mid = (l+r)>>1;
        if(A[mid]==x)
            return mid;
        else if(A[mid]>x)
            r = mid-1;
        else
            l = mid+1;
    }
    return -1;
}


2. 找到第一个大于等于x的数。

 1.这里的二分结束判断的条件是l<r,也就是当l==r时,我们就确定了唯一一个位置,如果这个位置是x的话,那么他就是

  第一个大于等于x的值如果不是x的话,那么证明,序列中不存在x,而这时这个位置的意义是如果把x插入序列的话,

  它应该在的位置。

2.如果A[mid]>=x说明第一个大于等于x的位置一定在mid处或mid的左侧,因此应该去左边区间[l,mid]寻找,即,r = mid;


3.如果A[mid]<x说明第一个大于等于x的一定在mid的右侧,因此应该去右边区间[mid+1,r]寻找,即,l = mid+1;


4.因为二分结束的条件一定是l==r 所以返回l或r都可以;

int lower_search(int A[],int l,int r,int x){
    int mid;
    while(l<r){
        mid = (l+r)>>1;
        if(A[mid]>=x)
            r = mid;
        else
            l = mid+1;
    }
    return l;
}


3.找到第一个大于x的数。

 1.与上边类似,判断条二分结束的条件为l<r;如果x不存在序列中的话,则和第二种情况一样,返回的是x应该在的位置;

2.如果A[mid]>x说明第一个大于x的位置一定在mid处或mid的左侧。因此应该去左边区间[l,mid]寻找,,即,r = mid;


3.如果A[mid]<=x说明第一个大于x的位置一定在mid的右侧。因此应该去左边区间[mid+1,r]寻找,即 l = mid;


4.上同,返回l或r都行。

int upper_sreach(int A[],int l,int r,int x){
    int mid;
    while(l<r){
        mid = (l+r)>>1;
        if(A[mid]>x)
            r = mid;
        else
            l = mid+1;
    }
    return l;
}
注意代码2与代码3的区别,仅仅是判断条件不同,所以就可以存自己的二分模板了。

做题的时候经常遇见一些二分整个答案区间,直接找出符合条件的最小值或最大值。

题目举例:求sqrt(2)的值。


const double eps = 1e-5;
double f(double x){
    return x*x;
}
double calSqrt(){
    double l = 1,r = 2;
    double mid;
    while(r-l>eps){
        mid = (l+r)/2;
        if(f(mid)>2)
            r = mid;
        else
            l = mid;
    }
    return mid;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值