题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
分析
题目给出了输入的数组为非递减数组的一个旋转,那么旋转数组在一定程度上是有序的。因此盖提可以使用二分查找来加快搜索速度,而非使用遍历数组寻找最小值。思路如下:
- 指定 l o w low low和 h i g h high high两个指针,分别指向数组 a r r a y array array的第一个元素和最后一个元素。 m i d = ( l o w + h i g h ) / 2 mid = (low+high)/2 mid=(low+high)/2;
- 若 a r r a y [ m i d ] ⩾ a r r a y [ l o w ] array[mid] \geqslant array[low] array[mid]⩾array[low],则最小值在 m i d mid mid与 h i g h high high之间,赋值 l o w = m i d low=mid low=mid;
- 反之若 a r r a y [ m i d ] ⩽ a r r a y [ h i g h ] array[mid] \leqslant array[high] array[mid]⩽array[high],则最小值在 l o w low low和 m i d mid mid之间,赋值 h i g h = m i d high=mid high=mid,若 h i g h − l o w = = 1 high-low==1 high−low==1则返回 a r r a y [ l o w ] array[low] array[low]和 a r r a y [ h i g h ] array[high] array[high]之间的最小值;
- 但是还需注意到 a r r a y [ h i g h ] = = a r r a y [ l o w ] = = a r r a y [ m i d ] array[high] == array[low] == array[mid] array[high]==array[low]==array[mid]的这种情况,这种情况下无法判断二分查找下一步该怎么走,那么只能使用遍历 l o w low low到 h i g h high high的所有元素查找最小值并将其返回即可。
github链接如下:JZ06-旋转数组的最小数字
C++代码
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.size() == 0){
return 0;
}
int low = 0;
int high = rotateArray.size() - 1;
int mid = (low + high) / 2;
while(rotateArray[low] >= rotateArray[high]){
if(high - low ==1){
mid = high;
break;
}
mid = (low + high) / 2;
if (rotateArray[low] == rotateArray[high] && rotateArray[low] == rotateArray[mid]){
return this->findMin(rotateArray,low,high);
}
if (rotateArray[mid] >= rotateArray[low]){
low = mid;
}else if(rotateArray[mid] <= rotateArray[high]){
high = mid;
}
}
return rotateArray[mid];
}
int findMin(vector<int> rotateArray,int low,int high){
int min = rotateArray[low];
for(int i = low + 1; i < high ; i++){
if(rotateArray[i] < min){
min = rotateArray[i];
}
}
return min;
}
};
int main(){
int size;
cin >> size;
vector<int> array(size);
for(int i = 0 ; i < size ; i++){
cin>>array[i];
}
Solution s;
cout<<s.minNumberInRotateArray(array);
return 0;
}