题目:在一个无序数组中,相邻的数肯定不相等。求任意一个局部最小数。
局部最小:3,1,2。1就是局部最小。比左右两边都要小。
题解主要就是利用这个数据的特殊性。无非就是这几种情况:
1、数组的首位如果比第二位要小,说明第一个元素就是一个局部最小数。
2、如果末尾的数比倒数第二个数要小,说明末尾的也是一个局部最小数。
3、如果前面两个没有满足,说明肯定是 3 (2...1) 4 。这种结构。括号中的肯定比两边要小。再来看括号中的元素。利用二分法,找到中间的那个数n,如果这个数比n-1位置上的数要大,又回到了之前的那种结构,0~n的结构和3 (2..1) 4这种结构一样。同样的,如果中间数n比n+1的数要大,说明n~数组末尾的结构也是这种数据样式。如果及不满足n>n-1和n>n+1。说明 n<n-1&&n<n+1。那么此时中间数n就是一个局部最小值。
Java代码如下
public static int findLocalMinimum(int[] arr){
if (arr == null || arr.length<2){
return 0;
}
//第一个元素如果比第二个要小,因为左边没有数,所以第一个元素就是一个局部最小数。
if (arr[0] < arr[1]){
return arr[0];
}
//数组最后一个元素如果比倒数第二个元素值要小,说明最后一个元素也是一个局部最小数。
if (arr[arr.length-1] < arr[arr.length-2]){
return arr[arr.length-1];
}
//中间进行二分。利用数据特性。如果前面两个条件都不满足。说明第一个元素要比第二个元素要大,最后一个元素比倒数第二个要大。说明在第一个
// 和倒数第一个中间一定存在局部最小值。
int begin = 1;
int end = arr.length-2;
int mid = (begin + end)/2;
while (begin < end){
if (arr[mid] > arr[mid-1]){
end = mid-1;
}else if (arr[mid] > arr[mid+1]){
begin=mid+1;
}else {
return mid;
}
mid = (begin +end)/2;
}
return begin;
}