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

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

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

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

二分查找算法详解

二分查找(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. 实战练习题目(含链接)
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 鸿蒙电商购物车全栈项目:订单管理、支付管理与 AI 原生功能实现
  • Python 环境配置与 pip 安装教程
  • IntelliJ IDEA 常用快捷键指南
  • 基于 ESP32-S3 的智能家居键盘 SmartKB32_v2 双模控制器设计
  • 如何将本地已有项目关联并推送到指定的远程仓库
  • Spring 配置文件详解:Properties 与 YAML 格式对比及实战
  • Java 驱动的无人共享宠物洗澡物联网系统架构
  • Linux 系统部署 OpenClaw 并接入 QQ 机器人指南
  • OpenClaw 接入 QVeris:让你的 AI 助手拥有实时数据查询能力
  • 在 PPT 中嵌入 AI 生成的 H5 代码使用方法
  • Flutter 开发环境搭建:从零到第一次运行
  • MySQL 8.4 安装与配置教程
  • JavaScript 返回到上一页的三种常用方法
  • Rust 核心内存安全机制:所有权、借用与生命周期
  • Vue2 和 Vue3 集成 WangEditor 富文本编辑器及自定义上传实战
  • 基于 AI 的骑手健康证自动生成系统实现
  • 基于 SpringBoot+Vue 的网上摄影工作室管理系统设计与实现
  • Llama 7B 迁移至 MindSpore 实战指南:避坑与优化
  • AI 绘画工具崩溃排查与性能优化实战指南
  • Vue 项目 i18n 国际化配置与实战

相关免费在线工具

  • 加密/解密文本

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