Leetcode笔记-二分查找

183 阅读2分钟

二分查找

有三种写法:闭区间、半开半闭区间、开区间,本质相同。

以闭区间为例:

  • 初始条件:0,n-1
  • 循环条件:区间不为空,即left <= right
  • 更新逻辑:mid已判断,更新后越过mid
  • 返回值:循环内部相等则返回mid,出循环说明没找到,返回-1

搜索插入位置

注意读题:无重复元素。

  • 如果找到了目标值,即返回索引,与【二分查找】相同。
  • 如果没有找到,返回应该被插入的位置,即大于target的第一个数对应的index,可能大于n-1。
    • 考虑跳出循环的前一步,left和right一定重合。
    • 此时,left左边都小于目标值,right右边都大于目标值。
    • 如果mid小于目标值,left后移,target应该插入在left;反之,right前移,target仍然应该插入left。
    • 因此,返回left即可。

在排序数组中查找元素的第一个和最后一个位置

基于【搜索插入位置】,搜索target - 0.5和target + 0.5对应的插入位置即可。

注意:

  • target+0.5对应位置需要-1。
  • 先搜索一边,如果符合条件(==target),才继续搜索,否则直接返回-1。
  • 注意搜索时可能超出边界。
  • 始终记住先判断边界条件:nums是否为空。

搜索旋转排序数组

首先,理解二分搜索的判断,虽然简化为了mid和target的比较,但本质上是mid的左区间和右区间,分别与target比较。(因此,其实存在提前终止的优化空间。)

因此,在本题中,问题变为,每次迭代如何确定target在哪个区间?

  • 只有有序数组可以直接计算区间范围。 因此,需要先判断左右区间哪一个有序。
  • 旋转后,左右区间其一必然有序。
  • 如何判断?首末元素比较大小,注意不需要严格大于,因为可能只有一个元素。 接下来,target和有序区间比较,如果不在此区间,则在另一区间。