二分查找框架
套路纲查找与排序什么时候想到它(适用信号)
- 数组有序,或"答案具有单调性"(判断条件把区间分成是/否两段)
- 要定位某个目标值,或"第一个满足条件的位置"
- 线性扫描太慢(数据规模大、或者要求 O(log n))
一句话核心
每一步取区间中点比较,把不可能的一半确定性地排除——关键不是"猜得准",而是"排除得多"。
通用模板(先背骨架)
js1function binarySearch(nums, target) {
2 let lo = 0, hi = nums.length - 1; // 闭区间 [lo, hi]
3 while (lo <= hi) { // 闭区间配 <=
4 const mid = Math.floor((lo + hi) / 2); // 向下取整,mid 偏左
5 if (nums[mid] === target) {
6 return mid;
7 } else if (nums[mid] < target) {
8 lo = mid + 1; // mid 已排除,用 +1
9 } else {
10 hi = mid - 1; // 同理
11 }
12 }
13 return -1;
14}
关键问题清单(做题时按顺序回答,把模板套进去)
- 区间定义是什么——闭区间 [lo, hi] 还是左闭右开?这决定循环条件写 <= 还是 <
- 收缩用 mid ± 1 还是 mid?mid 自己已经比较过了,必须排除它,否则死循环
- mid 的取整方向(向下取整偏左)和收缩方向是否配套?
- 要找的是"存在性"还是"边界"(第一个/最后一个满足条件的)?边界问题在相等时要继续收缩,而不是直接返回
常见坑
- 循环条件和收缩方式混搭(<= 配 mid、或 < 配 mid ± 1)是死循环的头号来源——两处要配套记
- 向下取整 + hi = mid 会卡死(mid 可能等于 lo);需要这种收缩时改用 (lo + hi + 1) // 2 向上取整