案例一:局部值最小值位置
虽然是个无序数组,但是由于任意两个相邻元素的值不重复的性质决定了可以使用二分搜索算法。
思路:
1.数组为空或长度为0,返回-1,表示局部值不存在
2.数组长度为1,返回位置0
3.数组长度大于1时:考虑三种情况
考虑最左边和最右边的元素:如果arr[0]<arr[1] return0; arr[N-1]<arr[N-2] returnN-1;
考虑最中间元素,如果中间元素大于它左边的元素,那么局部最小值就应该在数组的左半部分
如果中间元素小于大于它右边的元素,那么局部最小值就应该在数组的右半部分
中间元素既小于它左边的值又小于它右边的值,那么它就是局部最小
总结:该题表明二分搜索算法不一定只能在有序数组中进行,只要你在查找的时候发现能否淘汰数组的一半,留下另一半,那么都是可以用二分搜索的。
public class LocalMinimum {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr1={1};
int[] arr2={1,2};
int[] arr3={3,2,6,5};
int[] arr4={5,4,6,8,1,3,2,9};
System.out.println(getLessIndex(arr1));
System.out.println(getLessIndex(arr2));
System.out.println(getLessIndex(arr3));
System.out.println(getLessIndex(arr4));
}
public static int getLessIndex(int[] arr){
if(arr==null||arr.length==0)
return -1;
if(arr.length==1)
return 0;
//先考虑最左边和最右边元素的情况
if (arr[0] < arr[1])
return 0;
if (arr[arr.length - 1] < arr[arr.length - 2])
return arr.length - 1;
int left=1;
int right=arr.length-2;
int mid =0;
while(left<right){
mid=left + (right - left) / 2; //注意:这行不要放到while循环外了,mid是随left和right变化的
if (arr[mid] > arr[mid - 1])
right=mid-1;
else if (arr[mid] > arr[mid + 1])
left=mid+1;
else
return mid;
}
return left;
}
}