AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

二分查找初学

作者: 作者的头像   acwing_22766 ,  2024-11-21 16:46:26 ,  所有人可见 ,  阅读 2


0


bool check(int x) {/* ... */} // 检查x是否满足某种性质

// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
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;
}

下面我们来详细解释两个函数


bsearch_1: 用于区间 [l, mid] 和 [mid + 1, r] 的划分
示例:寻找数组中第一个大于等于某值的元素位置

int bsearch_1(int l, int r) {
    while (l < r) {                // 只要区间有多个点,就继续二分
        int mid = l + r >> 1;      // 计算中点,向下取整
        if (check(mid))            // 判断 mid 是否满足条件
            r = mid;               // 如果满足条件,右边界缩小到 mid
        else
            l = mid + 1;           // 如果不满足条件,左边界缩小到 mid + 1
    }
    return l;                      // 返回第一个满足条件的位置
}

执行过程

假设数组是 arr = {1, 3, 5, 7, 9}

初始:l = 0, r = 4
    mid = (0 + 4) / 2 = 2
    arr[2] = 5 < 6,check(2) = false
    更新:l = mid + 1 = 3

第一步:l = 3, r = 4
    mid = (3 + 4) / 2 = 3
    arr[3] = 7 >= 6,check(3) = true
    更新:r = mid = 3

停止:l = r = 3

结果:第一个大于等于 6 的元素位置是 3,即 arr[3] = 7。


bsearch_2 是另一种二分查找方法,适用于查找满足某种条件的最后一个位置。它的逻辑与 bsearch_1 相似,但区间的划分方式不同。

int bsearch_2(int l, int r) {
    while (l < r) {               // 循环条件:区间没有缩小到一个点
        int mid = l + r + 1 >> 1; // 计算中点(上取整),向右靠
        if (check(mid))           // 如果 mid 满足条件
            l = mid;              // 更新左边界为 mid
        else
            r = mid - 1;          // 如果 mid 不满足条件,更新右边界为 mid - 1
    }
    return l;                     // 返回最终位置
}

执行过程

初始:l = 0, r = 4
第一次计算:
    mid = (0 + 4 + 1) / 2 = 2
    check(2) 返回 true(arr[2] = 5 <= 6),更新 l = mid = 2
第二次计算:
    mid = (2 + 4 + 1) / 2 = 3
    check(3) 返回 false(arr[3] = 7 > 6),更新 r = mid - 1 = 2
停止条件:l == r == 2

结果:最后一个小于等于 6 的元素位置是 2。

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息