当前位置: 首页 > news >正文

详细介绍:二分查找边界模板:第一个 > target / 第一个 < target(找不到就返回边界)

详细介绍:二分查找边界模板:第一个 > target / 第一个 < target(找不到就返回边界)

二分查找边界模板:第一个 > target / 第一个 < target(找不到就返回边界)

写二分最容易错的不是“能不能找到”,而是 边界怎么收、mid 怎么取、以及找不到时返回什么。这篇把两个常用的“边界型二分”整理成可直接套用的模板。

本文假设数组 a 在区间 [l, r]单调非降(升序可重复)


1)第一个 > target 的下标(upper_bound)

语义

a[l..r] 中找 最左 的下标 idx 满足:

  • a[idx] > target

如果不存在(也就是全都 <= target),返回边界 r(夹到右边界)。

说明:经典 upper_bound 不存在时返回 r+1,但你要求“查不到就返回边界”,这里做了“夹边界”处理。

模板(Java)

// 第一个 > target;如果不存在,返回 r(右边界)
static int firstGreaterOrRight(int[] a, int l, int r, int target) {
int lo = l, hi = r + 1; // 搜索落点允许到 r+1(虚拟位置,不访问数组)
while (lo < hi) {
int mid = lo + ((hi - lo) >>> 1);
if (a[mid] > target) hi = mid;
else lo = mid + 1;
}
// lo 是“第一个 > target”的位置,可能是 r+1
return (lo == r + 1) ? r : lo;
}

关键点

  • hi = r+1 是“虚拟位置”,不会访问 a[r+1],因为 mid < hi,所以 mid 最大只会到 r
  • 最后 lo 可能为 r+1,表示不存在,于是按需求返回 r

2)第一个 < target 的下标(最左的“小于”)

语义

a[l..r] 中找 最左 的下标 idx 满足:

  • a[idx] < target

如果不存在(也就是全都 >= target),返回边界 l(夹到左边界)。

注意:这不是“最后一个 < target”,而是“第一个 < target”(最左的小于)。

模板(Java)

思路:
“第一个 < target” 等价于在单调数组中找 第一个 >= target 的位置 lb(lower_bound),那么答案就是:

但这推导对“最左”很尴尬:只要存在 < target,最左一定是 l
所以更有用、也更符合你想表达“边界二分”的,通常写的是:

第一个 >= target(lower_bound)
或 ✅ 最后一个 < target

你这里写“第一个小于target”很可能是口误,实际想要的是“最后一个小于 target”。我直接给你三者都放上,博客更完整,也不坑你。


2A)第一个 >= target(lower_bound,强烈推荐你用这个)

语义

找最左 idx 满足 a[idx] >= target
不存在时返回 r(夹到右边界)

// 第一个 >= target;如果不存在,返回 r
static int firstGeOrRight(int[] a, int l, int r, int target) {
int lo = l, hi = r + 1;
while (lo < hi) {
int mid = lo + ((hi - lo) >>> 1);
if (a[mid] >= target) hi = mid;
else lo = mid + 1;
}
return (lo == r + 1) ? r : lo;
}

2B)最后一个 < target(更常用,且和“第一个 >”对偶)

语义

找最右 idx 满足 a[idx] < target
不存在时返回 l(夹到左边界)

// 最后一个 < target;如果不存在,返回 l
static int lastLessOrLeft(int[] a, int l, int r, int target) {
int lo = l - 1, hi = r;   // lo 允许落到 l-1(虚拟位置,不访问数组)
while (lo < hi) {
int mid = lo + ((hi - lo + 1) >>> 1); // 上中位数,避免死循环
if (a[mid] < target) lo = mid;
else hi = mid - 1;
}
// lo 可能是 l-1 表示不存在
return (lo == l - 1) ? l : lo;
}

3)为什么“虚拟边界”不会越界?

  • hi = r+1 的模板里,mid 永远满足 mid < hi,因此 mid <= r,不会访问 a[r+1]
  • lo = l-1 的模板里,我们用 上中位数,保证 mid >= lo+1 >= l,不会访问 a[l-1]

4)一眼记住的对偶关系

需求典型模板可能的“找不到”落点按本文“夹边界”返回
第一个 > targethi = r+1,mid 下取r+1r
第一个 >= targethi = r+1,mid 下取r+1r
最后一个 < targetlo = l-1,mid 上取l-1l

5)小结:推荐你真正常用的两个

如果你在做区间、前缀和、离线查询、重复元素统计,最常用就是这俩:

  • lower_bound:第一个 >= target
  • upper_bound:第一个 > target

有了它们:

  • count(target) = upper_bound(target) - lower_bound(target)
  • “最后一个 <= target” = upper_bound(target) - 1
  • “最后一个 < target” = lower_bound(target) - 1
http://www.jsqmd.com/news/381697/

相关文章:

  • 西安哪些线下情人节礼物店铺靠谱,情人节礼物送老婆实用清单在此 - 工业品网
  • 聊聊拉链袋包装制造厂哪家好,性价比高的厂家全解析 - mypinpai
  • 详细介绍:全面股市知识普及:从概念到实践
  • 揭秘颜语堂考研英语写作提升效果,性价比高吗? - 工业设备
  • 2026初学者古筝推荐,实用款排行盘点,瑶鸾古筝Y103系列(星辰)/瑶鸾古筝Y106系列,古筝源头厂家有哪些 - 品牌推荐师
  • 2026年口碑好的交互设计培训机构分析,移动端交互设计培训课程解析 - 工业品网
  • 2026更新版!8个AI论文网站测评:自考毕业论文写作+格式规范全攻略
  • 全网最全 9个AI论文软件测评:专科生毕业论文+开题报告写作神器推荐
  • IoT 安全态势感知:利用网络空间测绘发现暴露的 IoT Web 资产
  • 【工具变量】企业固定资产加速折旧DID数据集(2008-2025年)
  • Jetson AGX 系列平台及其在人形机器人中的应用进展、比较优势与不足、应用前景和发展趋势(2)
  • 实用指南:同态加密搞定医疗数据安全共享
  • GTK4 布局管理入门
  • 2026年长沙性价比高的网页端交互设计培训课程排名 - 工业品网
  • 【优化求解】基于灰狼算法优化正交设计实验附Matlab代码
  • 跨平台WANGEDITOR网页编辑器如何优化PPT图文混排导入?
  • 细聊2026年浙江自建房建设品牌公司,哪家性价比高 - myqiye
  • 【预测模型】基于麻雀优化算法改进LSTM的锂电池寿命预测(SSA-LSTM)附Matlab代码
  • 【预测模型】改进的回溯搜索算法优化LSSVM预测研究(多输入)附Matlab代码
  • 详细介绍:计算机视觉(CV)期刊(按 CCF 推荐目录 A/B/C + 交叉方向整理
  • 2026年全国建设工程纠纷律师推荐,建设工程纠纷律师哪家好 - 工业品牌热点
  • 2026年口碑好的红外热像仪专业厂家推荐,上海热像科技实力解析 - 工业推荐榜
  • GitHub 热榜项目 - 日榜(2026-01-21):从0到1避坑指南(附完整代码)
  • 国企项目PHP如何通过分片上传解决视频文件超时问题?
  • 2026年浙江实力强的企业认证公司分析,选哪家比较好? - 工业品牌热点
  • 2026年污水处理项目企业盘点,河北景达表现亮眼 - mypinpai
  • PHP如何利用插件机制扩展视频分片上传的兼容格式?
  • 农业信息化项目用WANGEDITOR导入Excel表格时图片会失真吗?
  • 探讨安费诺FPC连接器,温升控制、医疗设备适配技术揭秘 - 工业设备
  • 2026年建设工程纠纷律师靠谱推荐,建设工程纠纷律师哪家好 - 工业设备