二分搜索模板

翻了一下自己的博客。记录了花花酱的二分搜索模板王争的二分搜索模板
花花酱的文章中提到:不要试图去找一个正确答案。试图去找一个分割点m,使得x>=m,g(x)>0为true。这个始终get不到。
王争的二分模板思路是比较简单的,就是时间长了,忘记了。考虑边界值的时候,是在代码逻辑中考虑,容易理解。

接下来记录一下labuladong的二分搜索模板

1 查找目标值

简单二分,查找目标值。

int binarySearch(int[] nums, int target) {
    int left = 0; 
    int right = nums.length - 1; // 注意

    while(left <= right) {
        int mid = left + (right - left) / 2;
        if(nums[mid] == target)
            return mid; 
        else if (nums[mid] < target)
            left = mid + 1; // 注意
        else if (nums[mid] > target)
            right = mid - 1; // 注意
    }
    return -1;
}

2 查找目标值的左边界

查找目标值的左边界,也就是第一个等于目标值的位置。

int left_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    // 搜索区间为 [left, right]
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            // 搜索区间变为 [mid+1, right]
            left = mid + 1;
        } else if (nums[mid] > target) {
            // 搜索区间变为 [left, mid-1]
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 收缩右侧边界
            right = mid - 1;
        }
    }
    // 检查出界情况,因为退出条件是left=right+1
    if (left >= nums.length || nums[left] != target)
        return -1;
    return left;
}

在这里插入图片描述

左侧边界的含义是:数组中<target的数有多少个,取值区间是[0,nums.length]

如果target<nums中的任何元素,那么在整个搜索过程中right会不断变小,left=0,所以此时退出条件是right<=-1。因为该方法中返回的是left,所以不需要检查边界。
如果target>nums中的任何元素,那么在个搜索过程中left会不断变大,所以此时的退出条件是left>=nums.length。因为该方法中返回的是left,这个时候left会越界,所以需要检查。

3 查找目标值的右边界

查找目标值的右边界,也就是最后一个等于目标值的位置。

int right_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 这里改成收缩左侧边界即可
            left = mid + 1;
        }
    }
    // 这里改为检查 right 越界的情况,见下图
    if (right < 0 || nums[right] != target)
        return -1;
    return right;
}

在这里插入图片描述

因为当nums[mid] == target的时候,修改的是left,那退出循环的时候left指向的可能nums[left]不等于target,所以检测right。
那这个时候right一定指向nums[right]=target吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值