1.算法要求
1.把一个排序好的数组,将数组中的前n个数字搬到数组的后面,从而实现旋转数组,并从中找到最小的数字
2.例如原数组是:{1,2,3,4,5},旋转之后的数组,可能是{3,4,5,1,2},那么就需要在旋转后的数组中,找到数字最小的值也就是1
2.算法的实现思路
- 其实,这一个算法题,最简单的实现方式,就是遍历数组,将最小的值找出来就行了。但是优秀的我们,肯定不会这么low的
- 旋转后的数组,也就是相当于两个有序的数组的集合{3,4,5}和{1,2}。那么我们是不是可以使用二分查找法,答案当然是可行的。
- 假设旋转后的数组为int[] arr= new int[]{3,4,5,1,2}。min = 0,max = arr.length
- mid = (min + max) >> 1; if(arr[mid] >=arr[min] && arr[mid] >=arr[max]),表明的就是,
最小值是
在mid所对应的数组的值
的后面
那么此时 min = mid;反之,也就是说明最小值
在mid所对应的数组的值
的前面,max = mid;
特殊情况1:如果数组为空,需要做好边界值得判断
特殊情况2:如果数组不为空,但是形如{1,1,1,1,1,1,1,2,0,1}这样的形式的话,只能通过遍历数组,从而找到数组中的最小值
判断的条件,在于arr[min] == arr[max]的时候。
3.算法的实现
public class FindMidNum {
public static int findMidNum(int[] arr) {
if (arr == null) {
// 表示不存在
return -1;
}
if(arr[0]== arr[arr.length-1]){
for(int i=0;i < arr.length;i++){
if(arr[i+1]< arr[i]){
return arr[i+1];
}
}
}
// 1.0 使用二分查找法
return searchMid(arr,0,arr.length-1);
}
private static int searchMid(int[] arr, int min, int max) {
if(min+1==max){
return arr[max];
}
int mid = (min + max) >> 1;
if(arr[mid] >= arr[min] && arr[mid] > arr[max]){
return searchMid(arr, mid, max);
}else {
return searchMid(arr, min, mid);
}
}
public static void main(String[] args) {
// int[] arr = new int[]{3,4,5,1,2};
// int[] arr = new int[]{8,9,10,2,3,4,5,6,7};
// 如果旋转数组的前后的值一样的情况下,只能遍历数组。特殊情况(不适合使用二分查找的方法)
int[] arr = new int[]{1,1,1,1,1,1,1,1,1,2,0};
int minNum = findMidNum(arr);
System.out.println(minNum);
}
}