【算法学习】二分查找开区间写法总结

根据灵神教学中的二分查找开区间写法进行如下总结:

我们需要注意的是,lowerBound 模板求解的是 >= target 的最小下标

 private int lowerBound(int[] nums, int target) {
        int left = -1;
        int right = nums.length; // 开区间 (left, right)
        while (left + 1 < right) { // 区间不为空
            // 循环不变量:
            // nums[left] < target
            // nums[right] >= target
            int mid = left + ((right - left) > 1);// 避免溢出的同时位运算加快运算速度
            if (nums[mid] < target) {
                left = mid; // 范围缩小到 (left, mid)
            } else {
                right = mid; // 范围缩小到 (mid, right)
            }
        }
        // 循环结束后 left+1 = right
        // 此时 nums[left] < target 而 nums[right] >= target
        // 所以 right 就是第一个 >= target 的元素下标
        return right;
    }

那么如果我们要求的是 > / < / <= 这三类的该怎么处理呢?

在整型的条件下,其实是同一类问题,都转化成 >= 模板就可以了,

  • > x 等价于 >= x+1
  • < x 等价于 >= x 的左边一个
  • <= x 等价于 > x 或 >= x + 1的左边一个
// > 情况
// nums[right] >= target + 1
if (nums[mid] < target + 1)

// < 情况
// nums[right] >= target
if (nums[mid] < target)		
...
return right - 1

// <= 情况
// nums[right] >= target + 1
if (nums[mid] < target + 1)
...
return rigth - 1

如果没有找到会有哪些情况?

  1. right == nums.length ,target > 数组中的所有元素
  2. nums[right] != target , 数组中不存在target
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值