1.题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
2.思路
可把旋转后的数组看做两个有序数组,以最小值为分界,前面的数大于最小值,后面的数小于最小值,左边的数大于右边的数
利用二分法查找,定义两个指针,一个指向开始,一个指向结束,计算出中间值,
- 将中间的数与指向开始的指针指向的数进行比较,如果比中间数大,则最小值在右半部分。
- 将中间的数与指向结束的指针指向的数进行比较,如果比中间数小,则最小值在右、左半部分。
特殊情况:
- 数组为1个元素,直接返回
- 递增排序数组的本身是自己的旋转,则最小数字是第一个数字,直接返回
- 中间数字与首尾数字大小相等,如{1,0,1,1,1,1}和{1,1,1,1,0,1},无法采用二分法,只能顺序查找。
3.代码实现
public class Solution {
public static int minNumberInRotateArray(int [] array) {
if(array==null||array.length==0) {
try {
throw new Exception("无效的参数");
} catch (Exception e) {
e.printStackTrace();
}
}
int begin=0;
int end= array.length-1;
int mid=begin;
//数组翻转了0次,则仍为有序递增数组,直接返回
if(array[begin]<array[end]){
return array[begin];
}
while(begin<end){
if(end-begin==1){
return array[end];
}
mid=(begin+end)/2;
if(array[mid]>=array[begin]){
begin=mid;
}else{
end=mid;
}
//特殊情况处理,遍历输出
if(array[mid]==array[begin]&&array[begin]==array[end]){
return getMin(array);
}
}
return array[mid];
}
public static int getMin(int[] array){
int min=array[0];
for(int i=0;i<array.length;i++){
if(array[i]<min){
min=array[i];
}
}
return min;
}
public static void main(String[] args) {
int[] array={1};
int min= minNumberInRotateArray(array);
System.out.println(min);
}
}