跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

二分算法实战:查找元素范围及区间统计

二分算法适用于具有二段性的问题,通过不断折半缩小搜索区间实现 O(logN) 复杂度。本文重点讲解如何分别查找目标值的左右边界,以解决排序数组中元素的首尾位置查找及区间计数问题。关键在于处理 mid 取整方式(向上或向下)以及循环终止条件,避免死循环并正确判断端点合法性。结合 STL 函数 lower_bound 与 upper_bound 可快速定位,手写二分时需仔细校验边界条件。

CoderByte发布于 2026/3/24更新于 2026/5/47 浏览
二分算法实战:查找元素范围及区间统计

二分算法核心逻辑

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

时间复杂度通常为 O(logN)。在实际开发中,C++ STL 提供了 lower_bound(大于等于 x 的最小元素)和 upper_bound(大于 x 的最小元素),它们均返回迭代器且效率为 O(log N),能简化边界查找过程。但理解手写二分的底层逻辑对于处理复杂边界条件至关重要。

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

问题描述

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

思路解析

我们需要分别找到目标值的左边界和右边界。这可以通过两次二分查找完成:

  1. 查找左端点:寻找第一个大于等于 target 的位置。当 nums[mid] >= target 时,说明目标可能在左侧或就是 mid,因此 right = mid;否则 left = mid + 1。注意这里使用 while(left < right) 配合 mid = (left + right) / 2 向下取整,避免死循环。
  2. 查找右端点:寻找最后一个小于等于 target 的位置。当 nums[mid] <= target 时,说明目标可能在右侧或就是 mid,因此 left = mid;否则 right = mid - 1。此时需使用 mid = (left + right + 1) / 2 向上取整,防止 left 无法移动导致死循环。
  3. 合法性校验:找到左右指针后,必须检查该位置的值是否真的等于 target,以防数组中不存在该值。

代码实现

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if (nums.empty()) 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

牛可乐和魔法封印

问题描述

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

思路解析

这道题本质上是区间计数问题,依然依赖二分查找。我们需要找到第一个大于等于 x 的位置(左边界)和最后一个小于等于 y 的位置(右边界)。如果找到的左边界值大于 x 或者右边界值小于 y,说明没有符合条件的元素。

关键在于处理好边界判断:二分结束后,必须验证 a[l] 和 a[r] 是否满足题目给定的范围条件,因为二分只能保证位置性质,不能直接保证数值一定在范围内(特别是当目标值不存在时)。

代码实现

#include <iostream>
using namespace std;

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

int binary_search(int x, int y) {
    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;

    // 查找右端点
    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;
        cout << binary_search(x, y) << endl;
    }
    return 0;
}

总结

二分查找的难点往往不在于模板本身,而在于细节控制。编写时需注意三点:一是 mid 的取整方式((l+r)/2 与 (l+r+1)/2)决定了收缩方向;二是循环终止条件(< 还是 <=)影响搜索范围;三是最终结果必须经过合法性校验,确保找到的索引对应的值确实符合题意。掌握这些细节,就能从容应对各类变体问题。

目录

  1. 二分算法核心逻辑
  2. 在排序数组中查找元素的第一个和最后一个位置
  3. 问题描述
  4. 思路解析
  5. 代码实现
  6. 牛可乐和魔法封印
  7. 问题描述
  8. 思路解析
  9. 代码实现
  10. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • LeetCode 49. 字母异位词分组:两种高效 C++ 解法
  • AI Prompt 工程指南:提示词设计原则与实战技巧
  • 闲置小米 9 变身复古掌机:天马 G 前端配置与原理
  • Llama-2-7b-chat-hf 本地部署全流程指南
  • 算法优选:位运算实战技巧与经典例题解析
  • Linux 基础命令与文件操作实战笔记
  • C++ 手写 JSON 与 HTTP Web 服务器实战
  • Java 树形结构转换为扁平列表
  • Linux 下基于 Socket 的 HTTP 服务器实现与协议解析
  • JDK 26 新 API 能力概览与实战指引
  • DFS 与 BFS 实战:从图论遍历到岛屿问题(C++ 版)
  • .NET 集成 GoView 低代码可视化大屏实战详解
  • 使用 C++ 实现 2048 小游戏
  • 网络安全学习指南:核心知识与技能路径
  • Java 设计模式详解
  • Stable Diffusion v1.5 Web UI 高级功能:图生图、局部重绘及蒙版编辑
  • 基于 Brython 与 LocalStorage 实现本地记仇本应用
  • C++ 模板与 string 类使用指南
  • 小米 MiLoco 大模型智能家居解决方案部署指南
  • 链表经典算法题解:相加、重排与合并

相关免费在线工具

  • 加密/解密文本

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