通过数组中间位置数值的大小,来缩小查找范围(二分查找的变种)
1 递归
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length == 0)
return 0;
if(array.length == 1)
return array[0];
//数组递增时
if(array[0] < array[array.length - 1])
return array[0];
return invideFind( array, 0, array.length-1);
}
private int invideFind(int [] arr,int start,int end){
//最后只剩下2个元素
//start指向前面递增数组的最后一个元素
//end指向后面递增数组的第一个元素,即最小值
int len = (start + end ) / 2;
if(start+1 == end)
return arr[end];
else if(arr[start] == arr[len] && arr[len] == arr[end])
//{1,0,1,1,1,1,1}只能顺序遍历
return minInOrder(arr,start,end);
else if(arr[start] <= arr[len])
//中间元素位于前面的递增数组
return invideFind( arr, len, end);
else
//中间元素位于后面的递增数组
return invideFind( arr, start,len);
}
}
private int minInOrder(int[] arr,int start,int end){
int tmp = arr[start];
for (int i = start; i < end; i++) {
if(tmp > arr[i]){
tmp = arr[i];
}
}
return tmp;
}
2非递归
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length == 0)
return 0;
if(array.length == 1)
return array[0];
int start = 0,
end = array.length - 1,
mid = start;
//排除递增序列
while(array[start] >= array[end]){
if(start + 1 == end)
return array[end];
mid = (start + end ) / 2;
if(array[start]==array[mid] && array[mid]==array[end])
return minInOrder(array,start,end);
if(array[start] <= array[mid])
start = mid;
else if(array[mid] <= array[end])
end = mid;
}
return array[start];
}
private int minInOrder(int[] arr,int start,int end){
int tmp = arr[start];
for (int i = start; i < end; i++) {
if(tmp > arr[i]){
tmp = arr[i];
}
}
return tmp;
}
}