小区疫情隔离解除还是遥遥无期,昨天小区里又有人新检测出了核酸阳性,十四天隔离期又要重新开始计数了。近几天每天都是两次抗原自测,加上下楼做一次核酸检测。今天看了些算法相关的内容,二叉树和二分查找。二叉树内容相对比较多,还没有完全看完消化掉,先整理一下二分查找这一部分的内容。
二分查找主要应用于从一个有序数组中找出对应于给定值的那个数字。基本的二分查找就是找到任意等于给定值的元素,如果有的话返回对应的数组下标,没有的话返回-1。除了基本的二分查找以外还有一些变形的二分查找,比如找到第一个等于给定值的元素;或是找到最后一个等于给定值的元素。
- 基本的二分查找
def binary_search(nums, target):
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
return -1
- 找到第一个等于给定值的元素
def bsearch_left(nums, target):
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
if left >= len(nums) or nums[left] != target:
return -1
return left
- 找到最后一个等于给定值的元素
def bsearch_right(nums, target):
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
if right < 0 or nums[right] != target:
return -1
return right
有一些值得注意的细节:
- 如果right初始设定为len(nums) - 1,那么while判断的条件就是<=,而且重置的left或者right的值就是mid加或者减1。
- 在变形的二分查找中,while循环之后要加一个判断,判断最后得到的值是否有效。无效的话返回-1表示没找到;有效的话将值最后返回。