题目描述
思路解析动画文字版
挨个比当然能找到最小,可那是 O(n),白白浪费了「旋转前本来有序」。题目把有序明牌摆这了,得用二分把它砍到 O(log n)。
转折:最小值就是旋转点。怎么二分定位它? 拿 nums[mid] 和右端点 nums[r] 比——这是 不变量:若 nums[mid] > nums[r],说明从 mid 到 r 中间有断崖, 最小值在 mid 右边(l=mid+1);若 nums[mid] < nums[r],说明 mid 到 r 已经是连续升序, 最小值在 mid 或它左边(r=mid,别丢 mid)。为什么不和 nums[l] 比?因为左半整段可能都比最小值大,比左端判不出方向。
准备 · 闭区间 [0,6]:搜索范围是整个数组,l=0、r=6。比较的「锚」永远是当前的右端 nums[r]。
第 1 轮 · 取 mid:中点 mid=3,nums[3] = 7。和右端点 nums[6]=2 比。
第 1 轮 · 判断(负例分支):7 > 2,说明从 mid 走到 r 中间一定 掉过崖(旋转点在右半),最小值在 mid 右边,且 mid 本身肯定不是最小。
第 1 轮 · 收缩:l 跳到 mid+1=4,左半 [4,5,6,7](灰)整段丢掉——这半里没有最小值。范围缩到 [4, 6]。
第 2 轮 · 取 mid:范围 [4,6],新中点 mid=5,nums[5] = 1。继续和右端 nums[6]=2 比。
第 2 轮 · 判断:1 < 2,说明从 mid 到 r 是 连续升序(没掉崖),那这段最小的就在 mid 这头。最小值在 mid 或它左边,mid 可能就是答案。
第 2 轮 · 收缩:r 收到 mid=5( 不是 mid−1,因为 mid 自己可能就是最小)。下标 6 丢掉,范围 [4, 5]。
第 3 轮 · 取 mid:范围 [4,5],mid=4,nums[4] = 0。和右端 nums[5]=1 比。
第 3 轮 · 收缩 → l==r:0 < 1,最小值在 mid 或其左,r 收到 4。现在 l == r == 4,区间只剩一个,循环结束。
答案:l 和 r 撞在下标 4,nums[4] = 0 就是最小值。每轮砍一半,O(log n) 搞定。
旋转找最小,记死一句:和右端点比。大于则断崖(最小值)在右,否则在左含 mid。和 nums[l] 比会判错,因为左半可能整段偏大。
边界三连:三种边界先想清楚。
面试官常追问:三个高频追问,答法记牢。
参考代码
class Solution: def findMin(self, nums): l, r = 0, len(nums) - 1 while l < r: mid = (l + r) // 2 if nums[mid] > nums[r]: # 断崖在右 → 最小在 mid 右 l = mid + 1 else: # 最小在 mid 或其左 r = mid return nums[l]复杂度
- 时间复杂度:O(log n),每轮把区间砍掉一半
- 空间复杂度:O(1),只用 l、r、mid 三个变量
可套用的代码模板
骨架记牢:while l < r、和 nums[r] 比、大于则 l=mid+1 否则 r=mid。LC154(含重复)、LC33(旋转找 target)都是它的近亲。
Python
l, r = 0, len(nums) - 1while l < r: mid = l + (r - l) // 2 if nums[mid] > nums[r]: l = mid + 1 # 最小在右 else: r = mid # 最小在左(含 mid)return nums[l]易错点
面试追问把动画讲成自己的话
追问核心思路是什么?
追问和找目标值的二分有何不同?
追问有重复元素(LC154)怎么办?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
搜索旋转排序数组
LeetCode 33 · 中等 · 沿着 二分查找 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题