题目:
输入一个按递增排序数组的一个旋转,输出该数组的最小数字。
输入:
12345的旋转可以是34512,所以我们输入34512.
输出:
1
解题思路:
较为直观的方法是每一个数据都扫描一遍,找到最小的元素,这样的时间复杂度为0(N),但是可以 利用2分法,用两个指针分别指向数组的第一个元素和最后一个元素,接着我们找到指针之间的中间元素,通过判断中间元素是大于第一个指针来判断是在第一个数组之中,还是在第二个数组之中,然后不断的缩小范围,当两个指针相差为1时,第二个指针,恰好指向最小元素。当然也有例外情况,比如(1,0,1,1,1)是(0,1,1,1,1,1)的旋转,他们的中间元素和第一个指针与第二个指针都相同,这样我们很难判断他是第一个数组还是第二个数组,这种情况下,我们只能采用顺序查找。
Java代码实现:
/**
* @param args
*/
public static void main(String[] args) {
int[] arr={3,4,5,1,2};
// TODO Auto-generated method stub
System.out.println(min(arr));
}
//输出旋转数组的最小元素
public static int min(int arr[]){
int index1=0;
int index2=arr.length-1;
int mid=index1;
if(arr==null && arr.length<=0){
return 0;
}
while(arr[index1]>=arr[index2]){
if(arr[index1]==arr[index2] && arr[mid]==arr[index1])
{
int min=arr[index1];
for(int i=index1+1;i<=index2;i++){
if(arr[i]<min){
min=arr[i];
}
return min;
}
}
if(index2-index1==1){
mid=index2;
break;
}
//用位运算代替除法,可以节省效率
mid=(index1+index2)>>1;
if(arr[mid]>=arr[index1]){
index1=mid;
}else if(arr[mid]<=arr[index2]){
index2=mid;
}
}
return arr[mid];
}