
7.1 左边界(第一个满足)
java
int lower(int l, int r) { while (l < r) { int mid = l + (r - l) / 2; // 不要 +1;防溢出写法 if (check(mid)) { r = mid; // 含 mid,向左收 } else { l = mid + 1; } } return l; // l == r}
mid不加 1,向左收敛。结束时l == r指向第一个满足 check 的位置。
7.2 右边界(最后一个满足)
java
int upper(int l, int r) { while (l < r) { int mid = l + (r - l + 1) / 2; // 必须 +1,防死循环 if (check(mid)) { l = mid; // 含 mid,向右收 } else { r = mid - 1; } } return l;}
mid必须 +1!否则(l, l+1)区间会死循环——不加 1 时 mid 永远等于 l,l = mid不改变 l。
7.3 二分答案
"最大值最小化"/"最小值最大化" → 二分。值域大用 long,防 (l+r)/2 溢出。
java
boolean check(long x) { /* 给定答案 x,是否可行 */ return true; } // 求最小可行答案 → 模板一(左边界)// 求最大可行答案 → 模板二(右边界)LC34 排序数组第一个和最后一个位置 | LC704 二分查找 | LC875 爱吃香蕉的珂珂
本文由 AgentPlanFlow 生成