题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素。例如输入{1,2,3,4,5}的一个旋转为{3,4,5,1,2},该数组的最小值为1。
算法思路:因为数组是递增的,旋转后分为两部分,两部分都是有序的,可以利用二分查找的思想,记录最左边的元素left、中间元素mid和最右边的元素right,首先判断左边值是否大于或等于右边的如果成立判断right-left是否等于1,如果等于一说明最小的值位于right直接返回,如果不等于计算mid,判断a[left]和a[mid],如果小于或等于mid,说明最小值在mid之后让left的值等于mid,如果大于则继续向下执行判断a[right]和a[mid],如果mid小于或等于right,说明最小值位于right之前,将right设为mid向前开始查找,循环结束条件是right-left等于1。
特殊情况:如果左边的数和中间的数以及右边的数相等则按顺序查找.如{1,1,1,1,1}.
代码(C++):
#include <iostream>
using namespace std;
int minNumInRotateArray(int array[],int length);
int MinInOrder(int array[],int left,int right);
int mian()
{
int a1[]={3,4,5,1,2};
int a2[]={1,1,1,0,1};
int length=sizeof(a1)/sizeof(int);
int result=minNumInRotateArray(a1,length);
cout<<result<<endl;
return 0;
}
int minNumInRotateArray(int array[],int length)
{
if(array==NULL||length<0)
{
throw new exception("Invalid parameters");
}
int left=0;
int right=length-1;
int mid=0;
while(array[left]>=array[right])
{
if(right-left==1)
{
return array[right];
}
mid=(left+right)/2;
//如果左边的数和中间的数以及右边的数相等则按顺序查找
if(array[left]==array[right]&&array[mid]==array[left])
{
return MinInOrder(array,left,right);
}
//如果中间数大于最左边的数,说明最小值在中间数的右边
if(array[mid]>=array[left])
{
left=mid;
}
if(array[mid]<=array[right])
{
right=mid;
}
}
return array[mid];
}
/*按顺序从left到right查找找出最小的值返回*/
int MinInOrder(int array[],int left,int right)
{
int result=array[left];
for(int i=left;i<=right;i++)
{
if(result>array[i])
{
result=array[i];
}
}
return result;
}
代码(Java):
public static void main(String[] args) {
int array[]={1,1,1,1,1};
System.out.println(minNumInRotateArray(array,array.length));
}
public static int minNumInRotateArray(int array[],int length)
{
int left=0;
int right=length-1;
int mid=0;
while(array[left]>=array[right])
{
if(right-left==1)
{
return array[right];
}
mid=(left+right)/2;
//如果左边的数和中间的数以及右边的数相等则按顺序查找
if(array[left]==array[right]&&array[mid]==array[left])
{
return MinInOrder(array,left,right);
}
//如果中间数大于最左边的数,说明最小值在中间数的右边
if(array[mid]>=array[left])
{
left=mid;
}
if(array[mid]<=array[right])
{
right=mid;
}
}
return array[mid];
}
public static int MinInOrder(int array[],int left,int right)
{
int result=array[left];
for(int i=left;i<=right;i++)
{
if(result>array[i])
{
result=array[i];
}
}
return result;
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>