1. 二分算法基础与核心思想
二分查找(Binary Search)作为计算机科学中最经典的算法之一,其核心思想是"分而治之"。我第一次接触二分是在大学数据结构课上,当时教授用"猜数字游戏"的类比让我们理解:假设你需要在1-100之间猜一个预设的数字,每次猜测后会被提示"大了"或"小了",最优策略就是从中间值50开始猜,这样每次都能排除一半的可能性。
在实际编码中,二分算法通常应用于有序数据集合的查找场景。它的时间复杂度是O(log n),相比线性查找的O(n)有质的飞跃。举个例子,在一个包含100万个元素的有序数组中查找特定值,线性查找最坏需要100万次比较,而二分查找最多只需20次(因为2^20 ≈ 100万)。
关键理解:二分法的本质是通过每次迭代将问题规模减半,这种指数级的缩减速度是其高效的核心原因。
1.1 标准二分查找实现
让我们用Python实现最基础的二分查找:
python复制def binary_search(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2 # 避免溢出
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
这段代码有几个关键点需要注意:
- 循环条件是
left <= right而不是<,这决定了搜索区间是闭区间[left, right] mid = left + (right - left) // 2的写法是为了防止大数相加导致的整数溢出- 每次比较后,我们都能排除掉一半的搜索空间
1.2 二分法的变体与应用场景
在实际问题中,纯粹的二分查找可能需要进行各种变体调整。常见的变体包括:
- 查找第一个/最后一个等于目标值的位置
- 查找第一个大于/小于目标值的位置
- 在旋转有序数组中查找目标值
- 在无限数据流中查找目标值
每种变体都需要对标准二分进行微调。例如,查找第一个等于目标值的位置时,当nums[mid] == target时不能直接返回,而需要继续向左搜索:
python复制def first_occurrence(nums, target):
left, right = 0, len(nums) - 1
res = -1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] >= target:
right = mid - 1
if nums[mid] == target:
res = mid
else:
left = mid + 1
return res
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
