1. 二分查找算法精解与LeetCode实战
二分查找(Binary Search)是计算机科学中最基础且高效的查找算法之一,它能在O(log n)的时间复杂度内完成有序数组的查找操作。这个看似简单的算法在实际应用中却有着丰富的变体和陷阱,这也是为什么LeetCode会将其作为经典题目反复考察。
1.1 标准二分查找实现(LeetCode 704)
标准二分查找问题(LeetCode 704)要求在一个升序排列的整数数组nums中查找目标值target,如果存在则返回其索引,否则返回-1。看似简单的需求,却隐藏着几个关键细节:
python复制def 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,确保能处理到只剩一个元素的情况- 中间值计算采用
left + (right - left) // 2而非(left + right) // 2,避免大数相加导致的整数溢出- 边界更新必须
mid ± 1,否则可能在特定情况下陷入死循环
1.2 二分查找的变体与边界问题
实际工程中,我们更多遇到的是二分查找的变体问题,比如LeetCode 34题"在排序数组中查找元素的第一个和最后一个位置"。这类问题要求我们不仅找到目标值,还要确定其在数组中的左右边界。
python复制def searchRange(nums, target):
def find_left():
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] >= target:
right = mid - 1
else:
left = mid + 1
return left
def find_right():
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] <= target:
left = mid + 1
else:
right = mid - 1
return right
left_idx = find_left()
right_idx = find_right()
return [left_idx, right_idx] if left_idx <= right_idx
