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

二分查找算法详解与模板总结:从原理到变体

二分查找算法,涵盖基本原理、步骤及代码实现。介绍了基础版本及三种常见变体(查找首个/末个等于目标值、查找首个大于等于目标值)。分析了时间与空间复杂度,列举了有序数组查找、求平方根等应用场景,并总结了注意事项与易错点。最后提供通用模板及 LeetCode 实战练习题,帮助读者掌握该算法。

LinuxPan发布于 2026/3/25更新于 2026/9/882 浏览
二分查找算法详解与模板总结:从原理到变体

二分查找算法详解

二分查找(Binary Search)是一种在有序数组中查找特定元素的高效算法。它的核心思想是分而治之,每次将搜索范围缩小一半。

基本原理

想象你在查英语字典找"apple"这个词:

  1. 翻开字典的中间
  2. 如果这一页的单词在"apple"之前,就往后翻
  3. 如果这一页的单词在"apple"之后,就往前翻
  4. 重复这个过程,直到找到"apple"

这就是二分查找的生活例子。

算法步骤

假设有一个升序数组 arr,要查找目标值 target:

  1. 初始化左指针 left = 0,右指针 right = n-1
  2. 当 left <= right 时循环:
    • 计算中间位置 mid = left + (right - left) / 2(防止整数溢出)
    • 如果 arr[mid] == target,找到目标,返回 mid
    • 如果 arr[mid] < target,说明目标在右半部分,left = mid + 1
    • 如果 arr[mid] > target,说明目标在左半部分,right = mid - 1
  3. 循环结束未找到,返回 -1

代码实现

基础版本(查找精确值)
int binarySearch(vector<int>& nums, int target) {
    int left = 0;
    int right = nums.size() - 1;
    while (left <= right) {
        // 避免 (left + right) 可能溢出
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            return mid; // 找到目标
        } else if (nums[mid] < target) {
            left = mid + 1; // 目标在右半部分
        } else {
            right = mid - 1; // 目标在左半部分
        }
    }
     ; 
}
return
-1
// 未找到

时间复杂度分析

  • 时间复杂度:O(log n)
    • 每次比较后,搜索范围减半
    • 对于大小为 n 的数组,最多需要 log₂(n) 次比较
  • 空间复杂度:O(1)
    • 只需要常数级别的额外空间

二分查找的变体

1. 查找第一个等于目标的位置
int findFirst(vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1;
    int result = -1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            result = mid; // 记录当前位置
            right = mid - 1; // 继续向左查找
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}
2. 查找最后一个等于目标的位置
int findLast(vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1;
    int result = -1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            result = mid; // 记录当前位置
            left = mid + 1; // 继续向右查找
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}
3. 查找第一个大于等于目标的位置
int findFirstGreaterOrEqual(vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] >= target) {
            right = mid - 1; // 虽然满足条件,但继续向左找更小的
        } else {
            left = mid + 1; // 当前太小,向右找
        }
    }
    return left; // left 就是第一个 >= target 的位置
}

常见应用场景

  1. 有序数组的查找 - 最基础的应用
  2. 求平方根 - 在 0 到 x 之间二分查找
  3. 旋转数组的查找 - 如 [4,5,6,7,0,1,2] 中查找
  4. 寻找峰值 - 在山峰数组中找到最大值
  5. 在答案空间二分 - 如"找到最小速度使得在规定时间内完成任务"

注意事项和常见错误

  1. 循环条件:left <= right vs left < right 的选择
  2. 边界更新:left = mid + 1 和 right = mid - 1 要正确
  3. 整数溢出:使用 mid = left + (right - left) / 2 而非 (left + right) / 2
  4. 数组必须有序:二分查找的前提是有序,否则结果错误
  5. 重复元素:处理重复元素时要明确需求(找第一个/最后一个)

二分查找虽然原理简单,但细节容易出错。建议多练习不同类型的题目,熟练掌握各种变体的写法。

二分算法模板总结

在这里插入图片描述

// 找左边
while (left < right) {
    int mid = left + (right - left) / 2;
    // 左边
    if (nums[mid] >= target) right = mid;
    // 右边
    else left = mid + 1;
}

// 找右边
while (left < right) {
    int mid = left + (right - left + 1) / 2;
    // 右边
    if (nums[mid] <= target) left = mid;
    // 左边
    else right = mid - 1;
}

实战练习题目(含链接)

二分查找(easy)
在排序数组中查找元素的第一个和最后一个位置(medium)
搜索插入位置(easy)
x 的平方根(easy)
山峰数组的峰顶(easy)
寻找峰值(medium)
搜索旋转排序数组中的最小值(medium)
0〜n-1 中缺失的数字(easy)

目录

  1. 二分查找算法详解
  2. 基本原理
  3. 算法步骤
  4. 代码实现
  5. 基础版本(查找精确值)
  6. 时间复杂度分析
  7. 二分查找的变体
  8. 1. 查找第一个等于目标的位置
  9. 2. 查找最后一个等于目标的位置
  10. 3. 查找第一个大于等于目标的位置
  11. 常见应用场景
  12. 注意事项和常见错误
  13. 二分算法模板总结
  14. 实战练习题目(含链接)

更多推荐文章

查看全部
  • GitHub Copilot 接入第三方 OpenAI 兼容模型方法
  • weiciyuan 主题切换功能:实现日间/夜间模式切换的技术方案
  • 大模型本地部署:在 Mac 上运行 AI 大模型
  • 前端大文件分片上传实现与断点续传方案
  • Web 安全实战:robots.txt 协议原理、利用与防御指南
  • Python 使用 Turtle 库绘制动态彩色爱心动画
  • Linux 基础使用与 Java 项目部署指南
  • 高并发、分布式场景下的 ID 生成策略
  • 前端实战:如何让用户回到上次阅读位置
  • Qwen3-Reranker-0.6B AR 导航空间语义排序效果解析
  • 10 个优质 Python 学习网站推荐
  • JWT 结构化知识体系:从原理到生产落地
  • DGX Spark 部署 vLLM + Open WebUI 运行 Qwen3-Coder-Next-FP8(CUDA 13.0 兼容版)
  • 基于 Coze 构建专属 AI 应用:从智能体开发到 Web 部署实战
  • 大语言模型 (LLM) 入门学习路线图
  • Qwen2.5-7B-Instruct 大模型 vLLM 推理加速与前端调用
  • IDEA 中 AI 编程插件实测:Copilot、TRAE 与灵码深度对比
  • C 语言指针与数组的深度关联及实战应用
  • 如何系统学习 AI Agent:从理论到实践
  • 前端部署:从开发到生产的全流程指南

相关免费在线工具

  • 加密/解密文本

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