题目
给定一个升序数组,它在某个点发生旋转,要求找出其中的最小值。
题目分析
这题非常适合用来理解“二分不是只用来找某个 target”。
你真正要找的不是某个明确值,而是满足某种结构特征的位置:最小值所在的那一侧。
方法一:直觉解法
直接线性扫描当然能做,但这会浪费数组原本的有序结构。
方法二:优化思路
关键判断是:
- 如果
nums[mid] > nums[right],说明最小值一定在右半边 - 否则最小值在左半边或者就是
mid
所以每次都能排除一半区间。
Go 实现
1func findMin(nums []int) int {
2 left, right := 0, len(nums)-1
3 for left < right {
4 mid := left + (right-left)/2
5 if nums[mid] > nums[right] {
6 left = mid + 1
7 } else {
8 right = mid
9 }
10 }
11 return nums[left]
12}
复杂度分析
- 时间复杂度:
O(log n) - 空间复杂度:
O(1)
易错点
right = mid不能写成mid - 1,因为mid本身可能就是最小值- while 条件通常是
left < right,不是<=
我的复盘
这题让我进一步确认:二分查找最本质的能力,是利用结构性质持续排除不可能区间,而不是只盯着某个目标值比较大小。