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

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

二分算法核心在于利用数据的二段性快速定位答案。聚焦有序数组场景,详解如何寻找目标值的首尾位置及区间统计。通过 C++ 实现左右边界查找模板,剖析 mid 取值、死循环规避及端点校验细节。结合 LeetCode 与 NowCoder 实战案例,对比 STL 二分函数与手写逻辑,提供可直接复用的工程化代码方案。

字节跳动发布于 2026/3/21更新于 2026/10/2294 浏览
二分算法实战:查找元素首尾位置与区间查询

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

当解具有二段性时,二分算法是寻找答案的高效工具。核心思路是根据待查找区间的中点位置,分析答案落在哪一侧,随后舍弃一半区间,在剩余部分继续查找。

时间复杂度:O(logN)

STL 中的二分查找

  • lower_bound:返回大于等于 x 的最小元素迭代器,时间复杂度 O(log N)。
  • upper_bound:返回大于 x 的最小元素迭代器,时间复杂度 O(log N)。

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

1. 题目描述

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值,返回 [-1, -1]。

2. 算法原理

我们需要分别找到目标值的左边界和右边界。

左右端点求法:

  1. 定义两个指针指向数组的头和尾。
  2. 进行二分区间划分。
  3. 判断获取的端点值是否合法(即是否等于 target)。

二分容易死循环的环节:

  • 区间缩小头尾指针的相遇条件。
  • 中值的求法(注意向上取整或向下取整对边界的影响)。

3. 代码实现

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

        // 二分查找左端点
        int left = 0, right = nums.size() - 1;
        while (left < right) {
            int mid = (left + right) / 2;
            if (nums[mid] >= target) right = mid;
            else 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
if
return
-1
-1
int
// 二分查找右端点
0
size
1
while
int
1
2
// 向上取整防止死循环
if
else
1
return

二、牛可乐和魔法封印

1. 题目描述

给定一个长度为 n 的有序数组 a,有 q 次询问,每次给出一个区间 [x, y],求数组中有多少个元素落在这个区间内。

2. 算法原理

这是一道典型的二分查找模版题,思路与上一题类似。利用两次二分分别找到大于等于 x 的第一个位置(左端点)和小于等于 y 的最后一个位置(右端点)。

注意: 有可能并没有满足条件的区间,需要在二分结束之后判断一下端点是否合法。

3. 代码实现

#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 的位置
    LL l = 1, r = n;
    while (l < r) {
        LL mid = (l + r) / 2;
        if (a[mid] >= x) r = mid;
        else l = mid + 1;
    }
    LL retL = l;
    // 判断端点是否合法
    if (a[l] < x) return 0;

    // 查找右端点:最后一个 <= y 的位置
    l = 1, r = n;
    while (l < r) {
        LL 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;
        int ret = binary_search(x, y);
        cout << ret << endl;
    }
    return 0;
}

总结

本次围绕二分算法展开,重点讲解了其二段性核心逻辑及左右边界查找的二分模版。通过两道实战题,深入剖析了 mid 取整技巧及端点合法性判断,帮助规避死循环误区。算法学习重在沉淀,每一道模版题的练习,都是突破瓶颈的底气。坚持刷题、深耕细节,终会在算法之路上遇见更好的自己。

目录

  1. 二分算法实战:查找元素首尾位置与区间查询
  2. STL 中的二分查找
  3. 一、在排序数组中查找元素的第一个和最后一个位置
  4. 1. 题目描述
  5. 2. 算法原理
  6. 3. 代码实现
  7. 二、牛可乐和魔法封印
  8. 1. 题目描述
  9. 2. 算法原理
  10. 3. 代码实现
  11. 总结

更多推荐文章

查看全部
  • Linux 常用命令与云服务器部署实战
  • 前缀和算法实战:从一维到二维及哈希结合应用
  • Python 与 Excel 自动化实战:构建高效数据处理系统
  • OpenClaw 移动端部署实战:iOS/Android 语音唤醒与离线 AI 助手
  • TensorRT C++ API 实现极致性能控制
  • Clawith 企业级多智能体框架深度解析
  • Java 音视频场景面试实战:内存模型、Spring Boot 与 Kafka
  • 分布式光纤声波传感(DAS)在无人机入侵探测中的应用
  • 2026 年起无人机违规飞行将面临拘留:治安管理处罚法新规解读
  • C++ 递归实战:合并有序链表与反转链表
  • C++ 运算符重载:自定义类型运算扩展
  • Java 使用 Spire.Doc 实现 HTML 转 XML 与 XPS
  • Spring AI 入门:DeepSeek 集成、角色设定与流式输出
  • 七款主流大模型英文降 AI 率效果横向测评
  • 中小团队低成本搭建项目管理系统:Ubuntu 下 DooTask 私有化部署实战
  • 飞牛 NAS 原生 WebDAV 挂载 115 网盘配置指南
  • ERNIE-4.5-0.3B 轻量模型部署与性能实测指南
  • 大模型应用:如何编写高质量 Prompt 的理论基础与 Rust 实践
  • MCP 工具速成:npx vs. uvx 全流程安装指南
  • GitHub 全界面中文化插件安装与配置指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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