704. 二分查找
算法逻辑分析
-
初始化边界
left设为0,right设为len(nums),表示左闭右开区间[left, right)。- 这意味着搜索区间包含下标
left,但不包含下标right。
-
循环条件
while left < right:,只要left小于right,就一直循环。- 终止时,
left == right,搜索区间为空。
-
中点计算
mid = (left + right)//2,取当前区间的中间位置。
-
比较并缩小区间
if nums[mid] < target:- 目标值在
mid右侧,left = mid + 1。 - 新区间为
[mid+1, right)。
- 目标值在
elif nums[mid] > target:- 目标值在
mid左侧,right = mid。 - 新区间为
[left, mid)。
- 目标值在
else:- 找到了目标值,返回
mid。
- 找到了目标值,返回
-
未找到目标值
- 如果循环结束还没找到,返回
-1。
- 如果循环结束还没找到,返回
核心点
- 左闭右开区间
[left, right):这是这段代码的核心思想。每次区间调整都严格遵循这个规则,保证循环不变量(即任何时候区间外都不是目标)。 - 区间调整方式:
- 小于目标时,
left = mid + 1,排除mid。 - 大于目标时,
right = mid,排除mid右侧。
- 小于目标时,
- 循环不变量保证:
- 循环内始终有:
nums[left-1] < target,nums[right] >= target(伪注释)。
- 循环内始终有:
- 终止条件:区间为空,说明不存在目标元素。
# 左闭右开
class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums)while left < right:# 循环不变量:# nums[left-1] < target# nums[right] >= targetmid = (left + right)//2if nums[mid] < target:left = mid + 1elif nums[mid] > target:right = midelse:return midreturn -1
复杂度分析
时间复杂度
- 每次循环将区间减半,最坏情况下要查找
log2(n)次。 - 因此,时间复杂度为 O(log n)。
空间复杂度
- 只用常数级别的辅助变量(
left,right,mid等)。 - 空间复杂度为 O(1)