153. 寻找旋转排序数组中的最小值
已知一个长度为
n
的数组,预先按照升序排列,经由1
到n
次 旋转 后,得到输入数组。例如,原数组nums = [0,1,2,4,5,6,7]
在变化后可能得到:
- 若旋转
4
次,则可以得到[4,5,6,7,0,1,2]
- 若旋转
7
次,则可以得到[0,1,2,4,5,6,7]
注意,数组
[a[0], a[1], a[2], ..., a[n-1]]
旋转一次 的结果为数组[a[n-1], a[0], a[1], a[2], ..., a[n-2]]
。给你一个元素值 互不相同 的数组
nums
,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。你必须设计一个时间复杂度为
O(log n)
的算法解决此问题
由于原升序数组在某点进行了旋转,将旋转后的数组分成A(绿色部分)和B(蓝色部分)两个部分,A中的任意元素大于B中的任意元素,在A
和B
部分内部也是升序的。设left=0,right=n-1
对于二分取到的值x=nums[mid]
,如果x<nums[n-1]
,那么可以说明mid
落在数组B
部分,因为在A
部分不可能有值大于nums[n-1]
,nums[n-1]
位于B
部分末尾,那么就要将搜索区间右侧向左缩小。如果x>nums[n-1]
,说明mid
落在数组A
部分,因为在B
部分不可能有值大于nums[n-1]
,nums[n-1]
是B
部分的最大值,那么要将搜索区间左侧向右缩小。通过这样的操作,搜索区间会向B
部分的第一个元素逼近,也就是要找的最小值。
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
while(left<right){
int mid=left+(right-left)/2;
if(nums[mid]<nums[nums.size()-1]){
right=mid;
}else{
left=mid+1;
}
}
return nums[left];
}