一、定义: 把一个数组的最开始的若干元素搬到末尾称为数组的旋转。输入一个递增排序数组的旋转,输出旋转数组的最小元素。例如:{1,2,3,4}是一个递增数组,将1,2搬到数组的末尾得到一个旋转数组为{3,4,1,2}。
二、解法:很显然旋转数组最小元素为1。 1的位置有2个特点:1、1把数组分成两个递增数组1:{3,4}和2:{1,2},2、其中前面一个数组的元素均大于等于后面一个数组的元素。利用特点2可以求取一个中间元素,中间元素的值大于等于数组2的值,说明中间元素的位置在数组1,则最小元素在中间元素的后面。若中间元素的值小于等于数组2的值,说明中间元素位置在数组2中,则最小元素在中间元素之前。怎样判断中间元素与数组1、2元素大小呢?选两个指针分别指向旋转数组的开始begin和结尾end,显然begin指针指向的元素位于数组1,end指向元素位于数组2,显然begin指向的元素大于等于end指向的元素。只需要将中间元素指针mid指向的值与begin和end指向的值比较就知道mid位于哪个数组了。在重复一遍,若arrey[begin]<=arrey[mid],则mid位于数组1,更新begin = mid;若arrey[end]>=arrey[mid];则mid位于数组2,更新end=mid;不断迭代,begin逐渐逼近end,知道他们相邻时,此时最小值minvalue=arrey[end]。总的时间复杂度为logN。
三、代码:
#include<iostream>
using namespace std;
int GetMinElement(int a[],int n){
int begin = 0; //头指针
int end = n-1; //尾指针
int mid = begin + (end - begin) / 2;//中间指针
int min ;
if(a[mid] == a[begin] && a[mid] == a[end]){
min =a[mid];
return min;
} // 如果输入数组元素全部相等
//当数组元素不等时
while(begin < end){
if (begin +1 == end && a[begin] >= a[end]){ // 头尾指针相邻时找到了最小值
min = a[end];
break;
}
mid = begin + (end - begin) / 2;
if(a[mid] >= a[begin]) //判断中间指针位置,并更新头指针
begin = mid;
else
{ //更新尾指针
if(a[mid] <= a[end])
end = mid;
}
}
return min;
}
int main(){
int a[] = {3,4,1,2};
cout<<GetMinElement(a,4)<<endl;
return 0;
}