LeetCode 153-Find Minimum in Rotated Sorted Array
题干:
给定一个元素各不相同的升序数组 n u m s nums nums,现将 n u m s nums nums从 k k k位置( k k k未知)旋转(即将从 k k k开始到末尾的部分移到最前面),要求在 l o g ( n ) log(n) log(n)时间内在 n u m s nums nums中寻找到最小的元素并返回元素值。
Input: nums = [3,4,5,1,2]
Output: 1
解:
![58](https://i-blog.csdnimg.cn/blog_migrate/dbaab5cc8b30f240ab8b35b9d273e0b4.jpeg)
画图可以看到,数组满足二段性:有一个分界点 m m m,在 m m m左侧的数都大于 m m m右侧的数,即存在一个数 S S S(要么是 n u m s [ 0 ] nums[0] nums[0]要么是 n u m s [ n − 1 ] nums[n-1] nums[n−1]),使得在 m m m左侧的数 n u m s [ i ] nums[i] nums[i]都 ≥ S \ge S ≥S,在 m m m右侧的数 n u m s [ i ] nums[i] nums[i]都 < S < S <S,在这个条件下,可认为整个数组是有序的(一侧为true,一侧为false)。
因为题目要求的是最小值,不论是旋转了还是没旋转一定有 n u m s [ a n s ] ≤ n u m s [ n − 1 ] nums[ans]\le nums[n-1] nums[ans]≤nums[n−1],所以不妨设 S = n u m s [ n − 1 ] S=nums[n-1] S=nums[n−1],那么在 m m m右侧的数都 ≤ n u m s [ n − 1 ] \le nums[n-1] ≤nums[n−1](设为true),在 m m m左侧的数 n u m s [ i ] nums[i] nums[i]都 > n u m s [ n − 1 ] > nums[n-1] >nums[n−1](false),求 m m m的最小值(即二分搜索寻找 f ( x ) = = t r u e f(x)==true f(x)==true的左边界)
int findMin(vector<int> &nums){
int left = 0, right = nums.size()-1;
int ans = 0, target = nums[right];
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] <= target){
ans = mid;
right = mid - 1;
}
else left = mid + 1;
}
return nums[ans];
}