二分查找与二分答案
在有序 / 单调的范围里找答案,每次砍掉一半,O(log n) 极快。
一、核心前提:单调性
二分能用的关键:数据有序,或答案满足单调性(越大越满足,或越大越不满足)。没有单调性就不能二分。
生活类比:猜数字。1~100 猜一个数,每次猜中间,根据"大了 / 小了"砍掉一半,最多 7 次必中。
二、互动演示:猜数字(1~100,目标 73)
蓝色是还没排除的范围,橙线是当前 mid,绿线是答案。点“下一步”看范围如何对半收缩。
lo1
hi100
mid—
第几次0
点击“下一步”开始二分。
三、二分答案模板
// 答案难直接求、但好验证且单调时,二分答案 + check()
int lo = 最小答案, hi = 最大答案;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (check(mid)) hi = mid; // mid 可行,试更优
else lo = mid + 1; // mid 不行,往大走
}
cout << lo; // lo 即最优答案
难点只有一个:想清楚 check(mid) 为真时答案该更大还是更小,据此调 lo / hi。