遍历数组的时间复杂度是O(n)。
考虑旋转数组的特性(可以将旋转后的数组分成两个子数组,前面的子数组的元素都大于后面子数组的元素,最小的元素刚好是这两个子数组的分界线),在排序的数组中可以用二分查找法实现O(logn)的查找。
但是对于一些特例,例如{1,0,1,1,1}和{1,1,1,0,1} 第一个数字、最后一个数字和中间的数字都是1,难以确定中间的数字数以第一递增子数组还是第二递增子数组,因此这种情况使用顺序遍历查找的方法。
package codingquestions;
public class MinNumberInRotatedArray {
public static int minnum(int[] numbers) {
if(numbers==null||numbers.length<=0) {
throw new RuntimeException("null");
}
int index1=0;
int index2=numbers.length-1;
int indexmid = index1;
while(numbers[index1]>=numbers[index2]) {
if (index2-index1==1) {
indexmid=index2;
break;
}
indexmid=(index1+index2)/2;
if(numbers[indexmid]>numbers[index1])
index1=indexmid;
else if (numbers[indexmid]<numbers[index2])
index2=indexmid;
else if (numbers[indexmid]==numbers[index1])//当index1,index2,indexmid 对应的数字都相等时,采用顺序遍历找最小值
return MinInOrder(numbers,index1,index2);
}
return numbers[indexmid];
}
public static int MinInOrder(int[]numbers,int index1,int index2) {
int result =numbers[index1];
for (int i =index1+1;i<=index2;i++) {
if (result>numbers[i])
result=numbers[i];
}
return result;
}
public static void main(String[] args) {
int[] numbers1= {1,0,1,1,1,1};
int[] numbers2= {5,6,1,2,3,4};
System.out.println(minnum(numbers1));
System.out.println(minnum(numbers2));
}
}