题目:把一个最开始的若干元素搬到数组的末尾,我们称为数组的旋转。输入一个递增排序数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}是{1,2,3,4,5}的一个旋转,该数组的最小值为1。
思路:采用二分查找,两个指针index、indexe2分别指向数组的第一个元素和最后一个元素;
(1) 如果数组已经有序时array[index1]<array[index2],最小元素就是array[index1];
(2)数组不有序时,array[index1]>=array[index2],找到中间元素mid,此时数组以最小元素为分割,有两个递增序列(例题中分为3,4,5和1,2)
1. 如果mid在前面的递增序列,array[mid]>=array[index1],那么最小元素在mid后面;把第一个元素指向中间元素缩小范围;
2.如果mid在后面的递增序列,array[mid]<=array[index2],那么最小元素在mid前面;把第二个元素指向中间元素缩小范围;
3.当array[index1]、array[index2]、array[mid]三个相等时,无法判定中间元素属于前一个递增序列还是后一个,只能顺序查找最小元素。
实现:
public int minNumberInRotateArray(int[] array) {
if(array==null||array.length==0) { //数组为空
return 0;
}
int index1=0;
int index2=array.length -1;
int mid=0;
while(array[index1]>=array[index2]) {
if(index2-index1==1) {//index1和index2相邻时,循环结束
mid=index2;
break;
}
mid=(index1+index2)/2;
//array[index1]、array[index2]、array[mid]三个相等时,只能顺序查找最小元素
if(array[mid]==array[index1]&&array[mid]==array[index2]) {
return minInOrder(array,index1,index2);
}
if(array[mid]>=array[index1]) {//mid在前面的递增序列,最小元素在mid后面
index1=mid;
}
else if(array[mid]<=array[index1]) {//mid在后面的递增序列,最小元素在mid前面
index2=mid;
}
}
return array[mid];
}
public int minInOrder(int []array,int index1,int index2) {
int result=array[index1];
for(int i=index1+1;i<=index2;i++) {
if(array[i]<result)
result=array[i];
}
return result;
}