✅ 二分查找或返回插入位置
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, target;
cin >> n >> target;
vector<int> nums(n);
for (int i = 0; i < n; ++i)
{
cin >> nums[i];
}
int left = 0;
int right = n; // 左闭右开区间 [left, right)
bool found = false;
while (left < right)
{
int mid = left + (right - left) / 2; // 防止溢出,推荐写法
if (nums[mid] == target)
{
cout << mid << endl;
found = true;
break; // 找到就立即退出
}
else if (nums[mid] > target)
{
right = mid; // 舍弃右半边(包含 mid)
}
else
{
left = mid + 1; // 舍弃左半边(不含 mid)
}
}
if (!found)
{
// 没找到,输出应该插入的位置
cout << left << endl;
}
return 0;
}
📝 二分查找模板关键笔记(适用于面试/刷题)
🔹 1. 区间定义一定要搞清楚:左闭右开 [left, right)
- 设定
right = n,而不是 n - 1,避免遗漏最后一个元素。
- 循环条件是
left < right,即还有搜索空间时继续。
🔹 2. mid 的计算必须写在循环体内!
🔹 3. 找到目标后要记得及时 break
- 若
nums[mid] == target,输出并立刻 break,避免进入多余循环。
- 避免写错逻辑导致死循环。
🔹 4. 没找到目标时返回插入位置(left)
- 此逻辑类似于 C++
lower_bound() 的行为。
left 最终会落在第一个大于等于 target 的位置。
📚 延伸提示(进阶):
- 若要查找最右侧的相等元素(upper bound),
left = mid + 1,right = n 的策略仍适用,但判断逻辑略有不同。
- 二分查找不仅用于查数字,还可以用于函数、浮点、字符串的“最小值最大值”搜索(如“最小化最大值”类题型)。