3.二分

二分

二分的关键并不是单调性,而是存在某个性质能使队列一分为二

模板

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

// 找左边界或左边界值
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;
}

// 找右边界或右边界值
int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;//!!!需要加1
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

如何选择

主要根据区间进行选择
1. 首先写出check函数
2. 然后根据check函数确定是l = mid还是r = mid;
3. 根据第二步分析结果选择模板

QA

1、为什么第二个需要加1

因为l+r>>1是向下取整,所以l+r>>1可能会等于l,此时数组边界就会被再次变为[l,r],区间无法更新,陷入死循环

比如l=3,r=4 ,mid = 3 + 4 >> 1 = 3
[l,r] = [3,4],之后无限循环
若+1,则 l = mid = 3 + 4 + 1 >> 1 = 4;
[l,r]被更新为[4,4],跳出死循环

相关题目

数的范围

posted @ 2021-01-06 23:10  INnoVation-V2  阅读(96)  评论(0编辑  收藏  举报