核心原理与模板
二分查找不仅仅是针对有序数组,其本质是利用数据的二段性。只要存在一个分界点能将数据分为满足条件和不满足条件两部分,就可以使用二分。
关键细节
-
循环终止条件 通常使用
left <= right。当left == right时仍需比较一次,确认该位置是否为目标值。若使用left < right,则需根据具体场景调整边界更新逻辑。 -
中点计算防溢出
(left + right) / 2在大多数情况下安全,但当两数之和超过整型最大值时会溢出。推荐写法:int mid = left + (right - left) / 2;这利用了起始值加偏移量的思路,既避免了溢出又保证了结果正确。
-
奇偶数处理 当区间长度为偶数时,中间有两个数。不加 1 取左中点,加 1 取右中点。选择哪种取决于更新逻辑(
mid+1还是mid),目的是避免死循环。
经典例题实战
1. 基础查找 (LeetCode 704)
这是最朴素的二分模板。适用于严格单调递增序列。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) left = mid + 1;
else if (nums[mid] > target) right = mid - 1;
else return mid;
}
return -1;
}
};
2. 查找元素的第一个和最后一个位置 (LeetCode 34)
此题需要分别查找左边界和右边界。由于目标值可能重复,找到相等值不能立即返回,需继续收缩区间。
查找左端点


