题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路
- 特点:数组包括两段非递减序列,且前段序列比后段序列都大
- 目标:我们总要找包含最小元素的那半段
二分查找
mid=(low+high)/2
一般有两种情况:
- rotateArray[mid]属于前段序列,如4567123,那么我们要取“7123”这半段。| rotateArray[high]-rotateArray[mid] | > | rotateArray[low]-rotateArray[mid] |,所以选择差值较大的这半段
- rotateArray[mid]属于后段序列,如6712345,那么我们要取“6712”这半段。| rotateArray[high]-rotateArray[mid] | < | rotateArray[low]-rotateArray[mid] |,也是选择差值较大的这半段
ch
会出现rotateArray[high]==rotateArray[low]的情况,直接跳过这两个端点,即low++;high–;
边界值处理
上述过程处理到最后会剩下‘(最大元素)(最小元素)’这两个值,所以最后返回rotateArray[high]。
代码
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0)
return 0;
int low=0,high=rotateArray.size()-1,mid;
while(low+1<high){
if(rotateArray[low]==rotateArray[high]){
low++;
high--;
}
else{
mid=(low+high)/2;
if(abs(rotateArray[low]-rotateArray[mid])>abs(rotateArray[high]-rotateArray[mid]))
high=mid;
else
low=mid;
}
}
return rotateArray[high];
}
};