1. 有序数组中不存在重复元素,用二分查找值等于给定值的数据。
Python代码实现:
from typing import List
def bsearch(a: List[int], target: int) -> int:
low = 0
high = len(a) - 1
while low <= high:
mid = low + (high - low) // 2
if a[mid] == target:
return mid
elif a[mid] > target:
high = mid -1
else:
low = mid + 1
return None
三个易错点:
(1). 循环退出条件:
low<=high,而不是low<high
(2). mid的取值:
mid = (low + high) // 2 这种写法可能造成溢出
mid = low + (high - low) // 2 正确写法
mid = low + ((high - low) >> 1 位运算性能更优
(3). low和high的更新:
low = mid + 1
high = mid - 1
2. 查找第一个值等于给定值的元素。
Python代码实现:
def bsearch_left(a: List[int], target: int) -> int:
low = 0
high = len(a) - 1
while low <= high:
mid = low + (high - low) // 2
if a[mid] > target:
high = mid -1
elif a[mid] < target:
low = mid + 1
else:
if mid == 0 or a[mid-1] != target:
return mid
else:
high = mid - 1
return None
3. 查找最后一个值等于给定值的元素。
Python代码实现:
def bsearch_right(a: List[int], target: int) -> int:
low = 0
high = len(a) - 1
while low <= high:
mid = low + (high - low) // 2
if a[mid] > target:
high = mid -1
elif a[mid] < target:
low = mid + 1
else:
if mid == len(a)-1 or a[mid+1] != target:
return mid
else:
low = mid + 1
return None
4. 查找第一个大于等于给定值的元素。
Python代码实现:
def bsearch_left_not_less(a: List[int], target: int) -> int:
low = 0
high = len(a) - 1
while low <= high:
mid = low + (high - low) // 2
if a[mid] < target:
low = mid + 1
else:
if mid == 0 or a[mid-1] < target:
return mid
else:
high = mid - 1
return None
5. 查找最后一个小于等于给定值的元素。
Python代码实现:
def bsearch_right_not_greater(a: List[int], target: int) -> int:
low = 0
high = len(a) - 1
while low <= high:
mid = low + (high - low) // 2
if a[mid] > target:
high = mid -1
else:
if mid == len(a)-1 or a[mid+1] > target:
return mid
else:
low = mid + 1
return None