二分模板

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

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

第一种:

当我们将区间[l,r][l, r][l,r]划分成[l,mid][l, mid][l,mid][mid+1,r][mid + 1, r][mid+1,r]时,其更新操作是r=midr = midr=mid或者l=mid+1l = mid + 1l=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,mid−1][l, mid - 1][l,mid1][mid,r][mid, r][mid,r]时,其更新操作是r=mid−1r = mid - 1r=mid1或者l=midl = midl=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、付费专栏及课程。

余额充值