对于有序数组的查找经常会使用到二分法。在实际问题中我们遇到的数组中常常含有相同的元素。C++标准模板库STL中有lower_bound( )和upper_bound( )可以实现利用二分查找找到元素第一次出现的位置和最后一次出现的位置。但是java中的binarySearch()则无法实现之一要求。故需自己加以完善。
思路是使用Arrays.binarySearch(arr, num)找到num在arr中的下标时判断该位置前或后的数是否与num相同,若相同则继续二分查找。
public static int lowerBinarySearch(int a[], int num){
int index = Arrays.binarySearch(a, num);
while(index>0 && a[index-1] == a[index]){ //下标为0或者前面没有相同的数时退出查找
index = Arrays.binarySearch(a, 0, index, num);
}
return index;
}
public static int upperBinarySearch(int[] a, int num){
int index = Arrays.binarySearch(a, num);
int len = a.length;
while(index>0 && index<len-1 && a[index] == a[index+1]){ //下标为0或者后面没有相同的数时退出查找
index = Arrays.binarySearch(a, index+1, len, num);
}
return index;
}
需要注意的是方法 binarySearch(Object[], int fromIndex, int toIndex, Object key)区间是左闭右开的,即包含了fromIndex但不包含toIndex。