二分查找
二分查找及其变体问题
无重复元素查找
/**
* 二分查找
*
* @param arr 无重复元素的有序数组(升序)
* @param value 待查找目标值
* @return 符合条件的元素下标,否则返回-1
*/
public static int binarySearch(int[] arr, int value) {
if (arr == null || arr.length == 0) {
return -1;
}
int start = 0;
int end = arr.length - 1;
while (start <= end) {
// 如果使用 (start+end)/2 在start 和 end 较大时有溢出风险
int middle = start + ((end - start) >> 1);
if (arr[middle] == value) {
return middle;
} else if (arr[middle] > value) {
end = middle - 1;
} else {
start = middle + 1;
}
}
return -1;
}
寻找第一个等于指定值的元素
/**
* 寻找第一个等于给定值的元素
*
* @param arr 有重复元素的有序数组(升序)
* @param value 待查找目标值
* @return 符合条件的元素下标,否则返回-1
*/
public static int binarySearchFirst(int[] arr, int value) {
if (arr == null || arr.length == 0) {
return -1;
}
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int middle = start + ((end - start) >> 1);
if (arr[middle] > value) {
end = middle - 1;
} else if (arr[middle] < value) {
start = middle + 1;
} else {
if (middle == 0 || arr[middle - 1] != value) {
return middle;
}
end = middle - 1;
}
}
return -1;
}
寻找最后一个等于指定值的元素
/**
* 寻找最后一个等于指定值的元素
* @param arr 有重复元素的有序数组
* @param value 待查找目标值
* @return 符合条件的元素下标,否则返回-1
*/
public static int binarySearchLast(int[] arr, int value) {
if (arr == null || arr.length == 0) {
return -1;
}
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int middle = start + ((end - start) >> 1);
if (arr[middle] > value) {
end = middle - 1;
} else if (arr[middle] < value) {
start = middle + 1;
} else {
if (middle == arr.length - 1 || arr[middle + 1] != value) {
return middle;
}
start = middle + 1;
}
}
return -1;
}
第一个大于等于指定值的元素
针对升序数组。
/**
* 寻找第一个大于等于指定值的元素
*
* @param arr 有序数组
* @param value 指定值
* @return 符合条件的元素下标,否则返回-1
*/
public static int binarySeartchFirstNotLess(int[] arr, int value) {
if (arr == null || arr.length == 0) {
return -1;
}
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int middle = start + ((end - start) >> 1);
if (arr[middle] >= value) {
if (middle == 0 || arr[middle - 1] < value) {
return middle;
}
end = middle - 1;
} else {
start = middle + 1;
}
}
return -1;
}
最后一个小于等于指定值的元素
针对升序数组。
/**
* 寻找最后一个小于等于指定值的元素
* @param arr 有序数组(升序)
* @param value 指定值
* @return 符合条件的元素下标,否则返回-1
*/
public static int binarySearchLastNotLarger(int[] arr, int value) {
if (arr == null || arr.length == 0) {
return -1;
}
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int middle = start + ((end - start) >> 1);
if (arr[middle] <= value) {
if (middle == arr.length - 1 || arr[middle + 1] > value) {
return middle;
}
start = middle + 1;
} else {
end = middle - 1;
}
}
return -1;
}
最后更新于
这有帮助吗?