【二分总结】

二分的关键在于如何正确的划分区间,那么问题就来了:

一般都是将区间划分成两个部分,如[l, mid], [mid + 1, r] or [l, mid - 1], [mid, r] 两者区别在于mid到底放在哪一个集合里面

我们就用二分经典的问题lower_bound来理清代码思路。

首先这里的lower_bound的定义是: 第一个 >= target的值的索引

第一种写法

// [0, n) 寻找 target lower_bound
 // [idx, n) >= target 
int lower_bound(int * arr, int n, int target) { 
    if (arr[n-1] < target) return -1;
    int l = 0, r = n - 1;
    while (l < r) {
        int mid = l + r >> 1;
        
        if (arr[mid] >= target) 
            r = mid;  // 请仔细理解这里 *
        else
            l = mid + 1;
    }
    //如果 target < arr[0],则为 0
    //如果 arr[n-1] < target, 则为-1 或者 n
    // * 如果target < arr[mid],则 target 在左边,所以选择左区间,同时arr[mid]本身也可能是答案,则 r = mid;
    
    //同时如果不好想,就考虑 target = arr[mid]的情况,这里找下边界,答案肯定在[l, mid]中
    // 这里是关键,试想如果找上边界,则答案应该在[mid, r]中找,请仔细体会,
    // arr[mid] < target 和 arr[mid] > target 两种情况下写法都不变,请仔细体会。
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值