#33
Medium
二分搜索
Search in Rotated Sorted Array
在旋转有序数组中查找目标值。
在旋转有序数组中用 O(log n) 查找目标值。关键在于每次二分后,总有一半区间仍然保持有序。
ArrayBinary Search
题目定位
每一步总有一半仍然保持有序,因此关键是判断哪一半有序,以及目标值是否落在那一半里。
关键观察
不是随便比较 target 和某个数,而是利用“哪一半有序”的结构来安全淘汰半边区间。
目标复杂度
O(log n) / O(1)
这题的解法思路怎么拆
1
先正常二分,但第一步不是直接比较大小,而是先判断哪一半有序。
2
如果左半边有序,就判断 target 是否落在这个有序区间内。
3
否则右半边一定有序,再判断 target 是否属于右半边。
4
淘汰不可能包含答案的那一半,继续二分。
拿一个例子顺一遍
1
例如 nums = [4,5,6,7,0,1,2], target = 0。
2
mid 指到 7,此时左半边 [4,5,6,7] 有序。
3
target 0 不在左半边,所以收缩到右半边。
4
再做一次同样判断,就能定位到下标 4。
参考实现
Pythondef search(nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
常见坑点
warning
没先判断哪一半有序就移动边界。
warning
直接套普通二分分支,忽略旋转结构。
高频追问
如果数组里允许重复值,写法要怎么变?
每次更新边界后,什么不变式依然成立?
继续刷相关题
先把 二分搜索 这个模式刷成体系,再去做更难变体。