# 二分查找
- 设置一个起点索引和重点索引(length -1)
- 使用右移计算中间值
- 判断中间值向左移动还是向右
public class BinarySearch {
/**
* @param a 待查找升序数组
* @param target 查找目标值
* @return 查找目标索引,未找到返回-1
*/
public static int binarySearchBasic(int[] a, int target) {
int i = 0, j = a.length - 1;
//循环内存在值
//注意:一定是 <=,因为在最后一次的判断中当前位置也有可能是要查找的数值
while (i <= j) {
//中间索引
//这里 /2 会有一个问题当target使用int最大数字的时候,第二次相加也就是m + 1的时候,
//由于java会把高位当作无符号所以会出现负数,所以会出现问题
//使用右移低位舍弃高位补0,运算结果不会产生印象
//int m = (i + j) / 2;
int m = (i + j) >>> 1;
if (target < a[m]) {
//向左边移动
j = m - 1;
} else if (a[m] < target) {
//向右边移动
i = m + 1;
} else {
//当前就是
return m;
}
}
return -1;
}
public static void main(String[] args) {
int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 15, 20};
System.out.println(binarySearchBasic(a, 123));
}
}
# 查找最左/右索引
引用场景,求排名
/**
* @param a 待查找升序数组
* @param target 查找目标值
* @return 查找目标索引,未找到返回-1
*/
public static int findLeftBinarySearchBasic(int[] a, int target) {
int i = 0, j = a.length - 1;
//候选者索引
int candidate = -1;
while (i <= j) {
int m = (i + j) >>> 1;
if (target < a[m]) {
j = m - 1;
} else if (a[m] < target) {
i = m + 1;
} else {
candidate = m;
//向左
j = m - 1;
//向右
// i = m + 1;
}
}
return candidate;
}