【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置

本节博客主要是通过“在排序数组中查找元素的第一个和最后一个位置”总结关于二分算法的左右界代码模板,有需要借鉴即可。

1.题目

题目链接:LINK
在这里插入图片描述

这个题要求我们求这个排序数组的一个元素的开始位置与结束位置。

可以用暴力求解的方法,把第一次出现的数字下标记录一下,最后一次记录一下,返回结果,除了复杂度差之外没什么不好的。

当然我们这里说一下二分算法的思想。之所以可以使用二分算法,这是因为该数组是有序的,可以利用二分算法的“二段性”将其分割。


用两次二分算法:

  • 一方面,我们可以将整个数组分为大于等于t和小于t来找left点

  • 另一方面,我们可以将整个数组分为大于t和小于等于t来找right点

但是这里有一些代码细节值得注意!!!

2.二分边界算法

2.1查找区间左端点

在这里插入图片描述

思考:我们在寻找左端点时候为什么要对数组按照小于t和大于等于t进行划分?
答:关键是因为我们要找左端点,左端点一定不可能在小于t的区间里。
在这里插入图片描述

通过上面的图片可知,我们要想找到一个数的左端点,那么这个左端点(我们要寻找的点)一定不再大于t这个区域,所以我们可知

  • mid < ret时,left = mid + 1
  • mid >= ret时,right = mid

2.1.1循环条件

while(left < right)//... √
while(left <= right)//... ×

循环条件选:left < right

这里为什么不是left <= right 呢?

  • left==right的情况下,即是最后结果,无需进行重复判断。
  • 可能有些情况下会出现死循环问题
    下面是对上面两个理由进行论证:
    在所有可能情况中,无非存在三种情况,
  • ①left与right中间存在要找的ret点
    在这里插入图片描述
    此时,mid = ret,mid == right,那么left = mid,会不断进入循环,陷入死循环
  • ②left与right中间所有点全部大于我们要找的右端点
    在这里插入图片描述
    到了最后,mid > ret, mid = right,right = mid,会存在死循环问题
  • ③left与right中间所有点全部小于我们要找的右端点
    在这里插入图片描述
    mid < ret,left = mid + 1,不会出现死循环问题。

2.1.2求中点的操作

我们求中点无非两种求法

①mid = left + (right - left) / 2; √
②mid = left + (right - left + 1) / 2; ×

这俩主要区别就是在数字个数是偶数情况下,①式取靠左的中点;②式取靠右的中点。

然后对于查找区间右端点而言,必须选用①式。
为什么,下面来进行解释?
如果选用②式,会存在下面情况:比如,mid指向right,然后mid所在的值>=ret值,就会不断死循环
注:if mid >= ret,right = mid;

在这里插入图片描述

2.1.3总结

在求目标值

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值