23. 寻找旋转排序数组中的最小值
题目描述
给定一个升序排列的数组,该数组在某个未知的下标处进行了旋转。例如 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2]。请找出其中最小的元素。
解题思路
这道题的关键在于利用数组的局部有序性。虽然整体不单调,但旋转点将数组分成了两个递增的子序列。我们可以通过比较中间元素 mid 与边界元素的关系,判断最小值位于哪一侧。
方案一:以末尾元素为基准
我们将 nums[n-1] 作为参照物。如果 nums[mid] > nums[n-1],说明 mid 落在第一个递增区间(较大的那部分),最小值一定在右侧;反之,最小值可能在左侧或就是 mid 本身。
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[nums.size() - 1]) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left];
}
};
方案二:以开头元素为基准
另一种思路是拿 nums[0] 做对比。如果 nums[mid] >= nums[0],说明 mid 还在前半段(较大值区域),需要向右收缩;否则向左收缩。注意处理数组未旋转的特殊情况。
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0;
right = nums.() - ;
(left < right) {
mid = left + (right - left + ) / ;
(nums[mid] >= nums[]) {
left = mid;
} {
right = mid - ;
}
}
(left == nums.() - ) {
nums[];
}
nums[left + ];
}
};


