二分模板(整数和浮点数)

整数:

同时注意右移运算>>1与整除/2不同。右移运算是向下取整,整数除法是向零取整:

  • -5 / 2 = -25 / 2 = 2。    这表明除二是向零取整
  • -5 >> 1 = -35 >> 1 = 2。这表明右移一位是向下取整

右移一位和除二的区别_FlushHip-CSDN博客_右移一位

模板一:

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, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

l+r >> 1向下取整,若l=mid,mid可能刚好为 l.5,mid取整刚好为l就陷入死循环了。

为什么此时l+r不加1,因为l的执行条件是l=mid+1。即使l=1,r=2,mid=1。l会在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;
}

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

为什么此时l+r要加1,因为l执行的条件是l=mid。当l=1,r=2时,如果mid=(l+r)>>1,那么mid=1,此时l=mid仍要循环就死循环了。所以要向上加1。

浮点数

double bsearch(double l, double r) {
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求, 一般比所求精度高2位
    while (r - l > eps) {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

确定好精度eps,以l+eps<r为循环条件。若保留k位小数,则eps=10的(-k+2)次方

力扣模板题: 

704. 二分查找

注意:右边界应该从nums.length开始 

class Solution {
    public int search(int[] nums, int target) {
        int l=0;
        int r=nums.length;
        while(l<r){
            int m=l+r>>1;
            if(nums[m]<target) l=m+1;
            else if(nums[m]>target) r=m;
            else return m;
        }
        return -1;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值