二分(通俗易懂)

二分查找

整数二分

先决条件:数据一定有序
下面是模版,只需要记住,然后套用即可

// 查找左边界 SearchLeft 简写SL
int SL(int l, int r)
{
    while (l < r)
    {
        int mid = (l + r) >> 1;
        if (check(mid)) r = mid; 
        else l = mid + 1; 
    }   
    return l;
}
// 查找右边界 SearchRight 简写SR 
int SR(int l, int r) 
{
    while (l < r)
    {                   
        int mid = l + r + 1 >> 1; // 需要+1 防止死循环
        if (check(mid)) l = mid;
        else r = mid - 1; 
    }
    return r; 
}
  • 记忆方面: 有加必有减

    int mid = l + r + 1 >> 1; 	// 加
    if (check(mid)) l = mid;
    else r = mid - 1;			// 减
    
  • 最后return的时候lr都是可以的,因为最后一定r == l(二分终止条件)

  • 对于查找特定的数

    • 存在

      • SL返回第一次出现的位置(下标较小)
      • SR返回最后一次出现的位置
    • 不存在

      • SL返回第一个比它小的数的位置

      • SR返回第一个比它大的数的位置

      • 示例:

        int arr[] = [1 2 4 5]; // 查找3
        // SL 返回2的下标 check(arr[mid] <= 3) 
        // SR 返回4的下标 check(arr[mid] >= 3)
        

左右边界通过下标区分

image-20240817093922691

浮点数二分

double bsearch_3(double l, double r)
{
    // 保留4为小数 则 1e-6
    // 保留6位小数 则 1e-8 加二即可 
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;//精度限制 因此不用+1
        else l = mid;
    }
    return l;
}
posted @ 2024-08-17 09:47  YOLO_01  阅读(124)  评论(0)    收藏  举报