23. 寻找旋转排序数组中的最小值
题目描述
假设按照升序排序的数组在预先未知的某个点上进行了旋转。例如,[0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2]。请找出其中最小的元素。
算法思路
这类问题看似无序,实则隐藏着单调性。旋转后的数组可以看作两段递增序列,且前一段的所有元素都大于后一段的元素(除非没有旋转)。
二分的核心在于找到一个判断标准,将查找区间一分为二。观察图像可知,若以右端点 nums[right] 为参照物:
- 当
mid落在左半段(较大值区域)时,nums[mid] > nums[right],最小值一定在mid右侧; - 当
mid落在右半段(较小值区域)时,nums[mid] <= nums[right],最小值可能是mid或在mid左侧。
通过不断收缩区间,最终 left 和 right 会收敛到最小值的位置。

C++ 代码实现(以右端点为参照)
这种写法逻辑最直观,直接比较中点与末尾元素。
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
// 如果中间值大于右端值,说明最小值在右侧
if (nums[mid] > nums[right]) {
left = mid + 1;
} else {
// 否则最小值在左侧或就是 mid
right = mid;
}
}
return nums[left];
}
};
C++ 代码实现(以左端点为参照)
有些场景下我们习惯拿左端点做基准,但要注意处理数组未旋转的特殊情况。






