二分查找是高效的搜索算法。
有序数组 随机访问
每次折半 逐步缩小范围 直到找到目标
def binary_search(arr, target, left, right): if left > right: return -1 mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: return binary_search(arr, target, mid + 1, right) else: return binary_search(arr, target, left, mid - 1)
def binary_search(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return -1
最好:O(1) - 直接找到 最坏:O(log n) - 一直折半 平均:O(log n)
递归:O(log n) - 调用栈 迭代:O(1) - 常数空间
def find_first(arr, target): left, right = 0, len(arr) - 1 result = -1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: result = mid right = mid - 1 # 继续向左找 elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return result
def find_last(arr, target): left, right = 0, len(arr) - 1 result = -1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: result = mid left = mid + 1 # 继续向右找 elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return result
def find_first_ge(arr, target): left, right = 0, len(arr) while left < right: mid = (left + right) // 2 if arr[mid] < target: left = mid + 1 else: right = mid return left if left < len(arr) else -1
问题:最小的最大值 方法:在答案上二分 验证:检查是否可行
def search_rotated(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid # 判断哪边有序 if arr[left] <= arr[mid]: if arr[left] <= target < arr[mid]: right = mid - 1 else: left = mid + 1 else: if arr[mid] < target <= arr[right]: left = mid + 1 else: right = mid - 1 return -1
二分查找虽然简单,但细节容易出错。