二分
二分查找比较基础,这里我就讲的简略一点。
算法思想
对于有序的数组,查找一个元素如果还是线性查找,实在是太浪费了。
假设数组
取查找范围的中间值
- 如果
,说明 会在 范围 - 否则
会在 。
如此反复。
cpp
while (l < r) {
int mid = (l + r) / 2;
if (aa[mid] >= x)
r = mid;
else
l = mid + 1;
}
return l;
while (l < r) {
int mid = (l + r) / 2;
if (aa[mid] >= x)
r = mid;
else
l = mid + 1;
}
return l;
确切的说,上述代码实现的是:在单增数组中查找
类似的,还有:在单减数组中查找
cpp
while (l < r) {
int mid = (l + r + 1) / 2;
if (aa[mid] >= x)
l = mid;
else
r = mid - 1;
}
return l;
while (l < r) {
int mid = (l + r + 1) / 2;
if (aa[mid] >= x)
l = mid;
else
r = mid - 1;
}
return l;
如果感觉较为抽象,可以查看 可视化。
应用
对于单调的函数,也可以通过二分查找查找其符合条件的值。
有时需要转换思考角度,比如 P1873 砍树。
给定森林中每棵树的高度,伐木工将砍伐所有的树比
高的部分,要求锯下的木材的总长至少为 ,并且尽量小,求 。
直接计算一个值可能不太容易,但我们可以较容易的判断某个值是否符合条件。
同时,答案是单调的,换句话说,随着
我们可以设计函数