二分模板

据说,只有 10 % 10\% 10%的程序员能把二分写对

算法思路:假设目标值在闭区间 [ l , r ] [l, r] [l,r]中, 每次将区间长度缩小一半,当 l = r l = r l=r时,我们就找到了目标值。

第一种:

当我们将区间 [ l , r ] [l, r] [l,r]划分成 [ l , m i d ] [l, mid] [l,mid] [ m i d + 1 , r ] [mid + 1, r] [mid+1,r]时,其更新操作是 r = m i d r = mid r=mid或者 l = m i d + 1 l = mid + 1 l=mid+1;,计算mid时不需要加1。

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

第二种

当我们将区间 [ l , r ] [l, r] [l,r]划分成 [ l , m i d − 1 ] [l, mid - 1] [l,mid1] [ m i d , r ] [mid, r] [mid,r]时,其更新操作是 r = m i d − 1 r = mid - 1 r=mid1或者 l = m i d l = mid l=mid;,此时为了防止死循环,计算mid时需要加1。

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

第三种

白书上的,也是我最常用的,对于整数域,先将范围统一往左右各扩大一位,然后对应的二分即可。

int bsearch_2(int l, int r)
{
	l--,r++;
    while (l+1 < r)
    {
        int mid = l + r  >> 1;
        if (check(mid)) l = mid;
        else r = mid ;
    }
    return l;
}

对于实数域上的二分

int bsearch_2(double l, double r)
{
	double eps=1e(-k-2);
    while (r-l > eps)
    {
        double mid = l + r  >> 1;
        if (check(mid)) l = mid;
        else r = mid ;
    }
    return l;
}

int bsearch_2(double l, double r)
{
    for(int i=0;i<100;i++)
    {
        double mid = l + r  >> 1;
        if (check(mid)) l = mid;
        else r = mid ;
    }
    return l;
}

总结

具体还得实际来,没有万能的模板。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值