旋转数组的最小数字
剑指Offer
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
按上述题意描述一般情况输入的数组可以分为两个递增序列(相等也算),如果使用直接查找遍历 那么时间复杂度是 O(N),这样虽然可以但是题目就没意思了。数组中的第一个元素大于或等于最后一个元素,使用二分法,一个指标指向数组的头 start,一个指向数组的末端 end,middle=(start+end)/2,若 middle 下标对应的值大于等于 start 下标对应的值,middle 属于第一个序列 start = middle ,若 middle 下标对应的值小于 end 则属于第二个序列,end = middle。 到最后 end 与 middle 相差为1时 最小值在 end下标上。
特殊情况:1,0,1,1,1,1,1 当 start = middle = end 相等时,就无法使用二分查找,只能遍历所有。
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length==0)
return 0;
//数组长度为 1
if(array.length==1){
return array[0];
}
//数组有序
if(array[0] < array[array.length-1]){
return array[0];
}
int start=0,end=array.length-1;
int middle=start;
while(true){
if(end-middle==1){
break;
}
middle=(start+end)/2;
//遍历所有
if(array[start]==array[middle] && array[middle]==array[end]){
return findMin(array,start,end);
}
if(array[start]<=array[middle]){
start=middle;
}else if(array[middle]<=array[end]){
end=middle;
}
}
return array[end];
}
public int findMin(int [] array,int start,int end){
int min=array[start];
for(int i=start+1;i<=end;i++){
if(array[i]<min){
min=array[i];
}
}
return min;
}
}
才学疏浅,有什么问题请大家指出来。十分感谢!