跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

二分算法实战:查找元素首尾位置与区间查询

二分算法核心在于利用数据的二段性快速定位答案。通过两个典型例题,演示如何在有序数组中查找目标值的起止位置及区间长度。重点解析左右端点二分的模板写法,包括 mid 取整策略防止死循环、边界条件合法性校验,以及 STL 库函数的应用场景。结合 C++ 代码实例,帮助读者掌握二分查找的底层逻辑与工程实践细节。

萤火微光发布于 2026/3/23更新于 2026/8/1742 浏览
二分算法实战:查找元素首尾位置与区间查询

题目示意图

前言

当解题思路具备'二段性'特征时,二分算法往往是首选。核心逻辑在于根据待查找区间的中点位置,判断答案落在哪一侧,随即舍弃一半区间,在剩余部分继续二分。该策略能将时间复杂度优化至 O(logN)。

在 C++ STL 中,lower_bound 返回大于等于 x 的最小元素迭代器,upper_bound 返回大于 x 的最小元素迭代器,两者均支持 O(log N) 的查找效率。理解其底层原理有助于我们在面试或竞赛中灵活手写实现。

题目一:在排序数组中查找元素的第一个和最后一个位置

题目描述

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值,返回 [-1, -1]。

题目详情

思路分析

这道题是典型的二分查找变体,需要分别寻找左边界和右边界。

  1. 寻找左端点:使用二分查找找到第一个大于等于 target 的位置。若该位置的值不等于 target,说明数组中不存在目标值。
  2. 寻找右端点:同理,找到最后一个小于等于 target 的位置。

关键点提示:

  • 区间缩小的终止条件通常是 left < right。
  • 计算中点时需注意防止死循环:找左边界用 mid = (left + right) / 2,找右边界用 mid = (left + right + 1) / 2。
  • 每次判断后需更新指针,确保区间不断缩小。

参考代码

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if (nums.empty()) return {-1, -1};

        // 二分查找左端点
        int left = 0, right = nums.size() - ;
         (left < right) {
             mid = (left + right) / ;
             (nums[mid] >= target) right = mid;
             left = mid + ;
        }
        
         (nums[left] != target)  {, };
         retLeft = left;

        
        left = ; right = nums.() - ;
         (left < right) {
             mid = (left + right + ) / ;
             (nums[mid] <= target) left = mid;
             right = mid - ;
        }
        
         {retLeft, right};
    }
};
1
while
int
2
if
else
1
if
return
-1
-1
int
// 二分查找右端点
0
size
1
while
int
1
2
if
else
1
return

题目二:牛可乐和魔法封印

题目描述

给定一个长度为 n 的有序数组 a,以及 q 次查询。每次查询给出一个区间 [x, y],要求统计数组中有多少个元素的值落在该区间内(包含边界)。

题目详情

思路分析

这本质上是一个区间计数问题。我们可以复用上一题的思路:

  1. 利用二分查找找到第一个大于等于 x 的元素下标(左边界)。
  2. 利用二分查找找到最后一个小于等于 y 的元素下标(右边界)。
  3. 若找到的边界合法,则区间长度即为 right - left + 1;否则结果为 0。

注意处理边界情况,例如所有元素都小于 x 或都大于 y 的情况,需要在二分结束后校验端点值的合法性。

参考代码

#include <iostream>
using namespace std;

const int N = 1e5 + 10;
typedef long long LL;
LL a[N];
int n;

// 查找区间 [x, y] 内的元素个数
int binary_search(int x, int y) {
    // 查找左端点:第一个 >= x 的位置
    int l = 1, r = n;
    while (l < r) {
        int mid = (l + r) / 2;
        if (a[mid] >= x) r = mid;
        else l = mid + 1;
    }
    int retL = l;
    if (a[l] < x) return 0; // 左边界不合法

    // 查找右端点:最后一个 <= y 的位置
    l = 1; r = n;
    while (l < r) {
        int mid = (l + r + 1) / 2;
        if (a[mid] <= y) l = mid;
        else r = mid - 1;
    }
    if (a[r] > y) return 0; // 右边界不合法

    return r - retL + 1;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    
    int q;
    cin >> q;
    while (q--) {
        int x, y;
        cin >> x >> y;
        cout << binary_search(x, y) << endl;
    }
    return 0;
}

总结

掌握二分算法的关键在于理解'二段性'并熟练运用左右边界模板。在实际编码中,务必注意以下细节:

  1. 防止死循环:当 left 和 right 相邻时,mid 的计算方式决定了向哪边收缩。找右边界时记得加 1。
  2. 边界校验:二分结束后得到的索引可能指向无效值,必须检查 a[index] 是否满足条件。
  3. 数据类型:涉及大数运算或累加时,注意使用 long long 避免溢出。

多刷几道经典模版题,形成肌肉记忆,遇到相关题目就能快速反应出正确的二分策略。

目录

  1. 前言
  2. 题目一:在排序数组中查找元素的第一个和最后一个位置
  3. 题目描述
  4. 思路分析
  5. 参考代码
  6. 题目二:牛可乐和魔法封印
  7. 题目描述
  8. 思路分析
  9. 参考代码
  10. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 Transformers.js 实现前端图片对象检测
  • Python 自学路线:100 课从变量到神经网络
  • VRChat 实时翻译与转录工具 VRCT 使用指南
  • 近五年体内微纳米机器人肿瘤精准治疗综述:聚焦胶质母细胞瘤
  • C++ 特殊类设计实战:拷贝控制、内存分配与单例模式
AIGC 从创意到创造:核心概念与落地场景
  • 2025 年 AI 工程师 RAG 面试核心问题与解答
  • SkyWalking 实现 Kafka 与 RabbitMQ 消息链路追踪实战
  • VSCode 关闭 GitHub Copilot 的两种方案
  • C++ 手写 HTTP 服务器:从请求解析到响应构建实战
  • C++ spdlog 日志库编译与安装详解
  • AI 与数据驱动下的组织进化:未来三年技术与人才趋势
  • 2026 年 AI 编程工具推荐:从 Copilot 到 Trae 的开发者选型指南
  • 2026 年各大高校 AIGC 检测政策汇总
  • 可复位D触发器设计方法:从零实现带异步清零功能
  • HarmonyOS PC 版系统镜像下载与安装指南
  • VibeVoice 与 Whisper 组合:构建本地语音双工交互系统
  • C++ 串口应用开发详解:Qt、Boost 与 Modbus 实战
  • PaddleOCR-VL-WEB 文档智能解析与工程化落地
  • AI前沿技术日更简报 - 2026-03-04
  • 相关免费在线工具

    • 加密/解密文本

      使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

    • Gemini 图片去水印

      基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

    • Base64 字符串编码/解码

      将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

    • Base64 文件转换器

      将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

    • Markdown转HTML

      将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

    • HTML转Markdown

      将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online