1、二分法模板
-
模板1 (left <= right):
查找条件可以在不与元素的两侧进行比较的情况下确定(或使用它周围的特定元素)。不需要后处理,因为每一步中,你都在检查是否找到了元素。如果到达末尾,则知道未找到该元素。 -
模板 2 (left < right):
查找条件需要访问元素的直接右邻居。使用元素的右邻居来确定是否满足条件,并决定是向左还是向右。保证查找空间在每一步中至少有 2 个元素。需要进行后处理。 当你剩下 1 个元素时,循环 / 递归结束。 需要评估剩余元素是否符合条件。 -
模板3 (left + 1 < right):
搜索条件需要访问元素的直接左右邻居。使用元素的邻居来确定它是向右还是向左。保证查找空间在每个步骤中至少有 3 个元素。需要进行后处理。 当剩下 2 个元素时,循环 / 递归结束。 需要评估其余元素是否符合条件。
temp1
left<=right
存在相等情况
所以:left=mid+1\right=mid-1
temp2:
left<right
由于(left+right)/2:
偶数偏向左边
奇数偏向中间
终止条件left==right,所以left=mid+1
temp3:
left+1<right
最后剩下两个单独数需要单独判断
left+1=right
1.1 二分法—排序数组查找
public static int findSortedArray(int[] arr, int target) {
if (arr == null || arr.length < 1) {
return -1;
}
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (right + left) / 2;
if (arr[mid] == target){
return mid;
}else if (arr[mid] > target){
right = mid-1;
}else {
left = mid+1;
}
}
return -1;
}
1.2 有序数组连续重复数字的边界
public static int[] searchRange(int[] arr, int target) {
int[] result = {
-1, -1};
if (arr == null || arr.length < 1) {
return result;
}
int left = 0;
int right = arr.length - 1;
// 找左侧的
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) {
right = mid - 1;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
if (arr[left] == target) {
result[0] = left;
} else if (arr[right] == target)