二分法
这里我们对二分法的初始值,循环条件,条件语句进行讨论。
初始值
对于左右两个端点的初始值,在一个长度为 的数组上,左经常用到的有两种情况:
- 左闭右闭,即
- 左闭右开,即
上述两种初始化对应的中间值计算方式均为
循环条件
对于循环条件我们经常见到的也有两种情况:
- ,对应着退出循环
- ,对应着退出循环
上面两种循环条件各自对应着以下两种更新方式
- ,
- ,
也不难理解,因为为开区间,在第二种更新中并没有取。(个人更喜欢第一种循环和更新。)
第一种更新需要注意的特殊场景是,返回的或者可能是超出范围的。例如当target
大于所有元素时,判断条件是是,最终返回的是。
条件语句
在各种类似“第一个大于k的坐标”,“小于等于k的最小坐标”等等题目中,if-else
判断条件起着重要的作用,例如下面的代码中返回的 是大于 target
的最小值的坐标。
def f(nums, l, r)
while l <= r:
mid = (r - l) // 2 + l
if nums[mid] <= target:
l = mid + 1 # 确保更新后左侧的区域,( ,l), 一定小于等于target
else:
r = mid -1 # 确保更新后右侧的区域, (r, ), 一定是大于target
return l
例题
对二分法本质更深的理解
二分法的本质是通过判断中间值是否满足一定条件,来舍弃掉一半的搜索范围,实现 的复杂度。