题解
- 题中说输入的是一个上升序列的旋转序列 ,就是比如一个上升序列是 1 2 3 4 5
题中就可以输入4 5 1 2 3,然后让你找最小的。 (序列中会有重复的数字)
- 我们以横坐标表示序列的下标,纵坐标表示序列值的大小
就会得出这样的图(前面的一段区间是在后边一段的上边的,旋转得到)我们发现除了最后水平的一段(黑色水平那段)之外,其余部分满足二分性质:竖直虚线左边的数满足 nums[i]≥nums[0];而竖直虚线右边的数不满足这个条件。分界点就是整个数组的最小值。
- 所以我们先将最后水平的一段删除即可。另外,不要忘记处理数组完全单调的特殊情况:当我们删除最后水平的一段之后,如果剩下的最后一个数大于等于第一个数,则说明数组完全单调。
- 二分的时间复杂度是 O(logn),删除最后水平一段的时间复杂度最坏是 O(n),所以总时间复杂度是 O(n)。
代码
class Solution {
public:
int findMin(vector<int>& nums) {
int n=nums.size()-1;
if(n<=0) return -1;
while(n>0 && nums[n]==nums[0]) n--;
if(nums[n]>=nums[0]) return nums[0];
int l=0,r=n;
while(l<r){
int mid=(l+r)>>1;
if(nums[mid]<nums[0]) r=mid;
else l=mid+1;
}
return nums[l];
}
};