二分查找核心模板
二分查找的本质是在一个有序的搜索区间内,通过不断将区间一分为二,快速缩小查找范围,最终定位到目标值。其时间复杂度为 O(log n),效率极高。
1.1 基本框架(两端都闭写法)
我们将使用两端都闭的搜索区间 [left, right],这是最直观、最不容易出错的写法。
#include <vector>
using namespace std;
// 基本二分搜索:查找 target 在有序数组 nums 中的任意一个索引,不存在返回 -1
int binarySearch(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1; // 注意:右边界是最后一个元素的索引
while (left <= right) { // 当搜索区间不为空时继续
int mid = left + (right - left) / 2; // 防止溢出的写法
if (nums[mid] == target) {
return mid; // 找到目标,直接返回
} else if (nums[mid] < target) {
left = mid + 1; // target 在右半部分,收缩左边界
} else if (nums[mid] > target) {
right = mid - 1; // target 在左半部分,收缩右边界
}
}
return -1; // 循环结束未找到
}
关键点:
- 循环条件
left <= right:当left == right + 1时,搜索区间[right+1, right]为空,循环终止,不会漏掉元素。 - 边界更新
left = mid + 1和right = mid - 1:因为mid已经检查过,需要将其从搜索区间中排除。