前言
二分查找很常用,属于 “一看就会,一写就错” 的类型。在网上看了很多博客视频,记录一下心得。(大雪菜tql)
一、什么时候用到二分查找?
不是有序性 ,而是二段性
二段性是指存在一个分界点,能把代求解区域分成两段
二、怎么使用二分查找?
1.测试代码
代码如下(示例):
public static void binarySearch(int[] data, int k) {
System.out.println("加*代表常用,剩余的作为对比。");
int l = 0, r = data.length - 1;
while (l < r) {
int mid = (l + r) / 2;
if (data[mid] >= k)
r = mid;
else
l = mid + 1;
}
System.out.println("*大于等于:" + k + " 下标:" + l + " 值:" + data[l]);
l = 0;
r = data.length - 1;
while (l < r) {
int mid = (l + r + 1) / 2;
if (data[mid] >= k)
r = mid - 1;
else
l = mid;
}
System.out.println(" 小于:" + k + " 下标:" + l + " 值:" + data[l]);
l = 0;
r = data.length - 1;
while (l < r) {
int mid = (l + r + 1) / 2;
if (data[mid] <= k)
l = mid;
else
r = mid - 1;
}
System.out.println("*小于等于:" + k + " 下标:" + l + " 值:" + data[l]);
l = 0;
r = data.length - 1;
while (l < r) {
int mid = (l + r) / 2;
if (data[mid] <= k)
l = mid + 1;
else
r = mid;
}
System.out.println(" 大于:" + k + " 下标:" + l + " 值:" + data[l]);
}
public static void main(String[] args) {
int[] data = {2, 5, 8, 13, 15, 15, 15, 15, 15, 15, 20};
binarySearch(data, 15);
}
2.思考&结论
可以看到,主要的不同点有三处
r = mid; l = mid + 1;
--------------------
l = mid; r = mid - 1;
--------------------
mid = (l + r) / 2; mid = (l + r + 1) / 2;
其中mid的不同,在于选择向下还是向上取整。
取整不同的原因是:避免进入死循环。
如果向下取整,
l
=
m
i
d
;
r
=
m
i
d
−
1
;
l = mid; r = mid - 1;
l=mid;r=mid−1; 在边界上会进入死循环,所以针对这种选择,使用向上取整
l 和 r 的移动,有着不同的含义,可参考代码理解。有两种加*的表示常用的写法,可做为模板使用。
while (l < r) {
int mid = (l + r + 1) / 2;
if (data[mid] <= k)
l = mid;
else
r = mid - 1;
}//左部分的右边界
while (l < r) {
int mid = (l + r) / 2;
if (data[mid] >= k)
r = mid;
else
l = mid + 1;
}//右部分的左边界
总结
推荐几道力扣题
找左边的右边界: 33、34、69、74、275、5751
找右边的左边界: 33、34、35、74、153、278、1482