二分查找

9/9/2022 二分查找

本专题是对 力扣Letbook二分查找 (opens new window) 的总结和思考。

本系列文章:

# 算法说明

书籍资料上对二分查找的描述,基本上是对有序数组进行二分查找,即前置条件是有序。但是有序其实只是二分法的特殊形式,二分法的前置条件是二段性。如果查找的条件满足二段性,就可以考虑使用二分法

二段性也叫排他性,即 数据一分为二,形成 确定(满足或不满足)条件/可能(满足或不满足)条件。即二段中的一段,一定要能够确定满足或确定不满足条件,对另外一段不做强制性。数组有序只是二段性的特殊形式。

二段性有很多表现形式,比如经典的数组有序,对一个有序数组,找到一个分割点数值,一边一定小于该数值,另一边一定大于该数值。

# 三个模板

二分查找的时间复杂度为对数 级别,是一种时间复杂度非常好的的算法。力扣Letbook为二分查找总结了三个模板,这三个模板很好的覆盖了二分查找的几乎全部内容,其中比较常用的为模板一和模板二,最为强大的是模板二。

# 使用场景

  • 模板一,用于寻找一个特定的数据,比如在一个有序数组中寻找一个特定值
  • 模板二,应用范围更广,应用于夹逼寻找满足条件的一个值,比如在一个有序数组中,寻找一个满足某条件(比如大于数组中的某一个值)的值,或在一个无重复数的数组中寻找到一个峰值(可能有多个峰值)
  • 模板三,是模板二的特殊形式,当第一个元素和最后一个元素无法直接访问时,考虑使用

一般来说,模板一为二分法的基础版;模板二最为强大,覆盖的场景更多,功能更强,堪称二分法中的瑞士军刀;模板三使用场景较少,一般都可以用模板二来代替。

# 代码

二分查找代码一般由三个主要部分组成:

  • 预处理 —— 如果集合未排序,则进行排序,即集合需要满足二段性

  • 二分查找 —— 使用循环或递归在每次比较后将查找空间划分为两半。

  • 后处理 —— 在剩余空间中确定可行的候选者,即在满足循环条件退出时的情况处理

# 对应区间

  • 模板一,[left, right],左闭右闭区间
  • 模板二,[left, right),左闭右开区间
  • 模板三,**(left, right),左开右开区间**

# 关于区间

之前对三个模板的理解是对应三个区间,经过多次的学习深入的思考,其实并不是。模板跟区间并没有绝对的对应的关系,核心取决与mid是否属于下一个符合题意的区间

  • 模板一,代码为 left = mid + 1; right = mid - 1 ,此时mid 已经判断过,不符合要求,因此不会再在左区间或右区间里
  • 模板二,代码为 left = mid + 1;right = mid; left = mid; right = mid - 1;,一般来说是解决 一定不是答案/可能是答案的问题,即mid存在可能是答案的情况
    • left = mid + 1;,此时mid已经不符合答案要求,因此需要将 mid 移除区间
    • right = mid;,此时mid还符合答案要求,可能是答案,因此需要 mid 留在区间内
    • 注意:这里不可能是 left = mid; right = mid-1;,由于mid为向下去中,考虑[0,1]区间,mid = 0,如果此时 nums[mid] < target,mid会一直停留在left。即对于两个数的区间,mid == left,此时如果left不变化,则会陷入无限循环中

# 折线图

二分法的题目尽量画折线图辅助理解。

Last Updated: 9/19/2022, 2:18:22 PM