std::lower_bound最快最安全,返回首个≥目标的迭代器,未找到时等于end(),避免手写二分的越界风险与性能损耗。

用 std::lower_bound 最快也最安全
直接调标准库,比手写二分快、无越界风险、还支持自定义比较。它返回第一个 ≥ 目标值的迭代器,没找到就等于 end():
int arr[] = {1, 3, 5, 7, 9};
int n = 5;
int target = 5;
auto it = std::lower_bound(arr, arr + n, target);
if (it != arr + n && *it == target) {
std::cout << "found at index " << (it - arr) << "\n";
} else {
std::cout << "not found\n";
}注意:必须确保数组升序,否则行为未定义;std::lower_bound 是左闭右开区间语义([first, last)),别传错长度。
手写二分时边界条件怎么设才不漏不越界
核心是统一用 [left, right] 闭区间,while 条件用 left ,更新时 <code>right = mid - 1 和 left = mid + 1 —— 这样所有整数位置都能被覆盖,且不会死循环:
- 别用
[left, right)却忘了改 while 条件为left - 别在
arr[mid] == target后直接 return,除非你确定只要一个位置;想找第一个/最后一个,得继续收缩边界 -
mid计算用left + (right - left) / 2,防止left + right溢出(尤其指针差值大时)
找第一个/最后一个位置不能只靠 == 判断
重复元素存在时,普通二分可能停在中间任意一个位置。要找最左,就在 arr[mid] == target 时继续往左搜:right = mid - 1;找最右则往右搜:left = mid + 1。最后检查边界是否合法:
立即学习“C++免费学习笔记(深入)”;
// 找第一个位置
int left = 0, right = n - 1, ans = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
ans = mid; // 先记下
right = mid - 1; // 继续往左找更早的
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}返回 ans 前务必确认它不是 -1,且 arr[ans] == target —— 有些实现会把 ans 初始化成 left 或 right,容易误判。
用 std::binary_search 只判断存不存在
如果只需要布尔结果(有/没有),用它最轻量。它不返回位置,内部也是调 lower_bound,但少一次解引用:
bool exists = std::binary_search(arr, arr + n, target);
别指望它返回索引;也不要对降序数组用它——它默认按 比较,降序得传 <code>std::greater<int>()</int>。
边界检查和数组有序性是所有方法共通的前提,漏掉这个,再对的逻辑也会崩。


















