左闭右开区间下lower_bound风格二分写法为:while(left
左闭右开区间怎么写
lower_bound风格的二分左闭右开(
[left, right))是 STL 里lower_bound、upper_bound的默认区间约定,边界处理更统一,不容易越界。核心是:循环条件用left ,更新时 <code>right = mid(不是mid - 1),因为mid可能是答案,但右边界不包含它。常见错误是把
right初始化成nums.size()却在循环里写right = mid - 1,导致漏查或死循环。
left初始为0,right初始为nums.size()- 每次
mid = left + (right - left) / 2,不加1- 查目标值存在性:循环结束后检查
left- 找第一个 ≥ target 的位置(即
lower_bound):直接返回left,无需额外调整左闭右闭区间怎么避免
mid计算溢出和死循环左闭右闭(
[left, right])更符合直觉,但容易在left == right时陷入死循环——尤其当mid更新后没跳过当前值。关键点是:循环条件必须是left ,且每次更新必须让区间严格缩小。典型坑是
mid = (left + right) / 2在大数组下整数溢出;还有left = mid或right = mid没加减 1,导致left和right卡住不动。
C++ Code Review Master下载组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用
mid = left + (right - left) / 2替代(left + right) / 2- 查
target存在时,if (nums[mid] == target)可直接返回mid- 找左边界(第一个 ≥ target):命中时设
right = mid - 1,否则left = mid + 1- 循环结束时,
left是第一个 ≥ target 的索引(类似lower_bound),但需校验是否越界两种区间下
lower_bound和upper_bound的返回值差异左闭右开区间返回的索引可直接用于
vector::insert或erase,语义干净;左闭右闭则需要手动转换——比如upper_bound在左闭右闭中返回的是最后一个 ≤ target 的位置,而左闭右开返回的是第一个 > target 的位置,两者差 1。混用两种逻辑拼接代码时,极易把一个区间的
right直接传给另一个区间的right,结果错位。例如把左闭右闭的right(含)当成左闭右开的right(不含)用,会少查一个元素。
lower_bound在两种区间都返回第一个 ≥ target 的索引,但左闭右闭的返回值范围是[0, nums.size()-1],左闭右开是[0, nums.size()]upper_bound在左闭右开返回第一个 > target 的位置(可能等于nums.size()),左闭右闭若按标准实现,应返回最后一个 ≤ target 的位置,需额外处理才能对齐- STL 所有算法默认左闭右开,自定义二分若要兼容,优先选该风格
什么时候该坚持左闭右开,什么时候用左闭右闭
工程中只要涉及与 STL 容器交互(比如在
vector中插入、删除、配合std::distance),一律用左闭右开;纯算法题或教学演示中,左闭右闭更易理解边界含义,但得全程保持一致。真正容易被忽略的是:同一个项目里不同模块用了不同约定,却没有文档说明。比如封装了一个
binary_search_left函数,参数是(arr, l, r, target),但没注明r是开还是闭,调用方靠猜,一出错就难定位。
- 函数接口设计时,在参数名里体现约定,如用
end而非right表示开区间终点- 注释第一行就写清楚:“区间为
[begin, end)”- 测试用例至少覆盖空数组、单元素、全相同、target 不存在于两端等边界
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!












