学习目标:
- [ 1 ] 掌握二分查找
- [ 2 ] 掌握变形及应用场景
学习内容:
- 基础二分查找
- 二分查找变形-最左最右
- 力扣相关练习
二分查找-基础版:
查找数组中的元素target
,如果找到就返回下标,找不到则返回-1
public class BinarySearch {
public int binarySearchBasic(int[] arr, int target) {
int low = 0, high = arr.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1; //注意这个地方经常错写成>>>2
if (arr[mid] > target) {
high = mid - 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
二分查找-最左版-Type1:
查找元素target
并且返回最左边一个target
的下表
public class BinarySearch {
public int binarySearchLeft(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int candidate = -1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (arr[mid] > target) {
high = mid - 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
candidate = mid;
high = mid - 1; //继续向左找
}
}
return candidate;
}
}
测试一下,在{1,2,2,2,2,4,5,6}
中查找2
:
@Test
public void testBinary(){
BinarySearch bs = new BinarySearch();
int[] arr = {1,2,2,2,2,4,5,6};
int ans = bs.binarySearchLeft(arr,2);
System.out.println(ans);
}
正确返回索引结果1
二分查找-最左版-Type2:
在Type1中,如果要查找的target
不存在,则返回-1
。我们可以进一步改进代码,使得target
不存在时,返回≥target
的最靠左索引。
public class BinarySearch {
public int binarySearchLeft2(int[] arr, int target) {
int low = 0, high = arr.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return low;
}
}
测试一下,在{1,2,2,2,2,4,5,6}
中查找3
:
@Test
public void testBinary(){
BinarySearch bs = new BinarySearch();
int[] arr = {1,2,2,2,2,4,5,6};
int ans = bs.binarySearchLeft2(arr,2);
System.out.println(ans);
}
正确返回索引结果5
二分查找-最右版:
返回≤target
的最右索引
public class BinarySearch {
public int binarySearchRight(int[] arr, int target) {
int low = 0, high = arr.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (arr[mid] > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low - 1;
}
}
low在右移过程中会越过最后一个
target
元素,所以索引为low-1
测试一下,在{1,2,2,2,2,4,5,6}
中查找2
:
@Test
public void testBinary(){
BinarySearch bs = new BinarySearch();
int[] arr = {1,2,2,2,2,4,5,6};
int ans = bs.binarySearchRight(arr,2);
System.out.println(ans);
}
正确返回索引结果4
二分查找-最左最右应用:
以下最左查找/最右查找表示对应查找范围的索引
1.求排名:最左查找 + 1
2.求前任元素:最左查找 -1
3.求后任元素:最右查找 +1
4.查找target1
~target2
范围内的元素:最左查找(target1
) ~ 最右查找(target2
)
二分查找相关题目:
https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/
当然啦,Java中数组自带 binarySearch(Object[], Object key)