前言
二分查找很简单,但是由于限定条件多种多样,不止是返回任一等于
目标值的坐标,还有第一个等于
、最后一个等于
、第一个大于等于
、最后一个小于等于
等等情况,导致二分查找很复杂,我们经常不知道应该返回左指针还是右指针
我总结了一句话,概括了所有情况:返回当反条件时需要移动的指针
,下面进行详细解释
先写一个第一个大于等于
代码
两个示例
第一个大于等于
大于等于
的反条件是小于
,当nums[mid]<target
时,需要移动left
,所以当反条件时需要移动的指针
就是left
指针,结果就返回left
可以这样简单理解下:在循环时,left
指针一直不满足条件,因为它是反条件需要移动的指针。循环退出,恰恰是因为left
开始满足条件了。所以left
就是第一次满足条件的指针
最后,作为下标,还要判断是否在[0, n-1]
里面,如果不在,说明没有满足条件的数据
def first_ge_binary_search(nums, target):
n = len(nums)
left = 0
right = n - 1
while left <= right:
middle = (left + right) // 2
if nums[middle] >= target:
right = middle - 1
else:
# 反条件时需要移动left
left = middle + 1
# 在循环时left一直不满足条件,循环退出的,恰恰是因为left开始满足条件了,所以他是第一个
if left < n:
return left
下面再来个最后一个等于
最后一个等于
最后一个相当于最后一个小于等于,反条件是大于,当nums[mid]>target
时,需要移动right
,所以结果就是right
最后还要判断一下是否相等,不相等说明不存在等于的
def last_binary_search(nums, target):
n = len(nums)
left = 0
right = n - 1
while left <= right:
middle = (left + right) // 2
if nums[middle] <= target:
left = middle + 1
else:
# 反条件时移动right
right = middle - 1
# 在循环体内right一直不满足条件,循环退出的,恰恰是因为right开始满足条件了,所以他是第一个
if right>=0 and nums[right] == target:
return right
后记
去leetcode练手
二分查找题库