常见二分法及其变形整理
二分法适用于有序数组,可以将时间复杂度由O(m)降低为O(logm)
(1)数组有序且不重复,确定value在数组A中的位置
思路:利用双指针动态查找value在数组A中的位置,迭代停止的条件是当low > high的时候,表明已经遍历完全
//当数组 有序 且 不重复的时候,确定 value 在 数组 A 中的位置
public static int binarySearch(int[] A, int value) {
//数组长度 以及两个指针
int length = A.length;
int low = 0;
int high = length - 1;
//迭代停止的条件是 low > high
while (low <= high) {
//设置中值
int mid = low + ((high - low) >> 1);
//判断一下 value 的位置
if (value < A[mid]) {
high = mid - 1;
} else if (value > A[mid]) {
low = mid + 1;
} else
return mid;
}
return -1;
}
(2)数组有序且重复,查找数组A中第一个等于value的位置
//数组有序且存在重复 查找在数组A中第一个等于value的位置 第一种方法
public static int binarySearchFirstOne(int[] A, int value) {
int length = A.length;
int low = 0;
int high = length - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (value < A[mid])
high = mid - 1;
else if (value > A[mid])
low = mid + 1;
else {
//相等的话 判断一下当前的位置
// 如果当前位置已经到达 索引 0 那么不需要再判断 直接返回 mid 即可
//如果当前位置不是 索引 0 那么它一定比 1 大,故 mid >= 1
// 此时判断一下A[mid-1]的值,一定不会越界(比如说A[-1])
//满足if 条件直接返回,
// 如果不满足,说明在 low 和 mid 中间一定还有 value
//更改high 为 mid-1即可
if (mid == 0 || A[mid - 1] != value)
return mid;
else
high = mid - 1;
}
}
return -1;
}
** (3)数组有序且存在重复,查找数组A中最后一个等于value的位置**
//数组有序 且存在重复 查找最后一个 等于 value的数组 的方法一
public static int binarySearchLastOne(int[] A, int value) {
int length = A.length;
int low = 0;
int high = length - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (value < A[mid])
high = mid - 1;
else if (value > A[mid])
low = mid + 1;
else {
if (mid == length - 1 || A[mid + 1] != value)
return mid;
else
low = mid + 1;
}
}
return -1;
}
(4)数组有序且存在重复,在数组A中查找第一个大于等于value的值的位置
//数组有序 且存在重复 查找第一个大于等于给定元素value的位置
public static int binarySearchFirstGreatOrEqual(int[] A, int value) {
int length = A.length;
int low = 0;
int high = length - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (value > A[mid])
low = mid + 1;
else {
if (mid == 0 || A[mid - 1] < value)
return mid;
else
high = mid - 1;
}
}
return -1;
}
(5)数组有序且存在重复,在数组A中查找最后一个小于等于value的位置
//数组有序 且存在重复 查找最后一个小于等于给定值 value 的 位置
public static int binarySearchLastLessOrEqual(int[] A, int value) {
int length = A.length;
int low = 0;
int high = length - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (value < A[mid])
high = mid - 1;
else {
if (mid == length - 1 || A[mid + 1] > value)
return mid;
else
low = mid + 1;
}
}
return -1;
}