
👨💻 关于作者:会编程的土豆
"不是因为看见希望才坚持,而是坚持了才看见希望。"
你好,我是会编程的土豆,一名热爱后端技术的Java学习者。
📚 正在更新中的专栏:
-
《数据结构与算法》😊😊😊
-
《leetcode hot 100》🥰🥰🥰🤩🤩🤩
-
《数据库mysql》
💕作者简介:后端学习者

原始写法:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n, m;
vector<int>arr;
int main()
{
cin >> n >> m;
arr.resize(n + 5);
for (int i = 1; i <= n; i++) cin >> arr[i];
while (m--)
{
int left = 1;
int right = n;
int tar; cin >> tar;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] >= tar)
{
right = mid - 1;
}
else left = mid + 1;
}
if (arr[left] == tar)
cout << left << " ";
else cout << "-1"<<" ";
}
return 0;
}
二分查找进阶:lower_bound 用法详解(附完整代码 + 易错点分析)
在算法题中,"查找一个数是否存在"是非常高频的需求。
而 lower_bound 是 C++ STL 中最常用、最强大的二分查找工具之一。
你这段代码就是一个典型模板写法,这篇文章带你彻底理解它。
一、问题描述
给定:
-
一个长度为 n 的数组
-
m 次查询
对于每个查询 x:
如果 x 存在,输出它在数组中的位置(从1开始)
如果不存在,输出 -1
二、代码展示
cpp
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<int> arr;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
arr.push_back(x);
}
while (m--)
{
int x;
cin >> x;
auto it = lower_bound(arr.begin(), arr.end(), x);
if (it == arr.end() || *it != x)
{
cout << "-1" << " ";
}
else
{
cout << it - arr.begin() + 1 << " ";
}
}
return 0;
}
三、核心函数:lower_bound
1. 作用
返回第一个 >= x 的位置
2. 举个例子
数组:1 3 5 7 9
| 查询 x | 返回位置 | 指向元素 |
|---|---|---|
| 5 | 2 | 5 |
| 6 | 3 | 7 |
| 10 | end | 越界 |
四、代码逻辑拆解
1. 查找位置
auto it = lower_bound(arr.begin(), arr.end(), x);
2. 判断是否存在
if (it == arr.end() || *it != x)
含义:
1. 到了末尾 → 不存在
2. 找到的不是 x → 不存在
3. 输出位置
it - arr.begin() + 1
说明:
迭代器转下标 + 转成1-based
五、一个非常重要的前提
数组必须是有序的(升序)
⚠️ 如果不排序会发生什么?
结果完全错误(但程序不会报错)
正确做法(建议加上)
sort(arr.begin(), arr.end());
六、时间复杂度分析
单次查询
O(log n)
总复杂度
O(n log n + m log n)
七、常见错误总结
1. 忘记排序
最常见错误:
lower_bound 默认要求有序
2. 少写判断
错误写法:
cout << it - arr.begin();
可能访问非法位置。
3. 忘记 +1
it - arr.begin() + 1
八、进阶理解(非常重要)
lower_bound vs upper_bound
| 函数 | 含义 |
|---|---|
| lower_bound | 第一个 ≥ x |
| upper_bound | 第一个 > x |
举例
数组:1 2 2 2 3
| x | lower_bound | upper_bound |
|---|---|---|
| 2 | 第一个2 | 第一个3 |
九、进阶应用(面试常考)
1. 统计某个数出现次数
int count = upper_bound(arr.begin(), arr.end(), x)
- lower_bound(arr.begin(), arr.end(), x);
2. 查找第一个 ≥ x 的位置
十、一句话总结
lower_bound = 找到"第一个不小于 x 的位置"