在旋转排序数组中找最小值,本质是利用二分查找淘汰一半搜索空间,关键在于根据nums[mid]与nums[right]大小关系判断最小值所在区间:若nums[mid]>nums[right],最小值在右半段;若nums[mid]

在旋转排序数组中找最小值,本质是利用二分查找“淘汰一半搜索空间”的思想,但需根据旋转特性调整判断逻辑——关键不在于找某个target,而在于识别哪半边必然包含最小值。
理解旋转数组的结构特征
一个升序数组向右旋转后,会形成“高段|低段”两段有序区间,最小值一定位于低段开头。整个数组虽不完全有序,但任意中点将数组分为两部分,其中至少有一侧是严格递增的。
- 若 nums[mid] > nums[right]:说明左半段(含mid)整体大于右端,最小值一定在右半段(mid+1 到 right)
- 若 nums[mid] :说明右半段(从 mid 到 right)是递增的,最小值一定在左半段(left 到 mid)
- 若 nums[mid] == nums[right]:无法确定最小值在哪边(如 [1,1,1,0,1]),安全做法是 right-- 缩小范围
二分边界收缩策略
使用闭区间 [left, right] 模板更直观。每次比较 nums[mid] 和 nums[right],而非 nums[left],因为右端能稳定反映低段位置(最小值总在“断崖”右侧)。
- 不取等号判断 left:避免因 nums[left] == nums[mid] 时误判(如 [3,3,1,3])
- 当 nums[mid] right = mid(因为 mid 可能就是最小值)
- 当 nums[mid] > nums[right] 时,left = mid + 1(mid 肯定不是最小值)
- 循环结束时 left == right,即为最小值下标
处理重复元素的鲁棒性
当 nums[mid] == nums[right] 时,无法通过一次比较排除任一半,但可以安全地缩小右边界——因为即使 nums[right] 是最小值,它也和 nums[mid] 相等,保留 nums[mid] 仍能覆盖解空间。
- 直接执行 right--,避免死循环
- 最坏情况下退化为 O(n),但平均仍保持 O(log n)
- 切忌用 left++ 替代,可能跳过最小值(如 [3,1,3,3,3] 中最小值在 left 位置)
代码核心逻辑示意
以下为关键片段(非完整函数):
while (left int mid = left + (right - left) / 2;if (nums[mid] > nums[right]) left = mid + 1;
else if (nums[mid] else right--;
}
return nums[left];











