23. 寻找旋转排序数组中的最小值
题目描述
假设按照升序排序的数组在预先未知的某个点上进行了旋转。例如,[0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2]。请找出其中最小的元素。
解题核心
这道题的关键在于利用数组的'二段性'。虽然整体不是有序的,但我们可以观察到:
- 如果我们将数组分为两部分,一部分是严格递增的,另一部分也是严格递增的(只是数值较小)。
- 最小值一定位于那个'断点'处。
- 通过比较中间值
mid和右端点right的值,我们可以判断mid落在哪一段。
具体逻辑:
- 若
nums[mid] > nums[right],说明最小值在mid右侧(因为mid处于较大的前半段),此时left = mid + 1。 - 若
nums[mid] <= nums[right],说明最小值在mid左侧或就是mid本身(mid处于较小的后半段),此时right = 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 {
right = mid;
}
}
return nums[left];
}
};
注意:这里选择
nums[right]作为参照物比nums[0]更稳健,避免了处理数组完全有序时的特殊分支判断,代码更简洁。


