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

二分查找算法原理及常见变种解析

综述由AI生成深入解析二分查找算法,涵盖三种常用模板及其适用场景。内容包含基础二分查找、查找目标范围、搜索插入位置以及旋转数组最小值等经典变种的原理分析与 C++ 代码实现。重点讲解了边界条件的处理、mid 的计算方式以及左右指针的收缩逻辑,帮助读者掌握二分法的核心思想并应用于实际开发与面试中。

灵魂摆渡发布于 2026/3/30更新于 2026/5/2235 浏览
二分查找算法原理及常见变种解析

一、'二分'算法原理剖析

'二分'的刻板印象是目标数据需要有序,如 0,1,2,3,4,5。但'二分'的本质是通过目标值排除一半区间,解决传统的从头到尾遍历查找。只要目标数据与目标值满足一定的大小关系,即可应用。

第一套模版:

int left = 0, right = nums.size() - 1;
int mid = 0; //找左端点
while(left < right) {
    mid = (right + left) / 2;
    if(nums[mid] > target) right = mid - 1;
    else if(nums[mid] < target) left = mid + 1;
}

第二套模板: 推论:假设找 target 连续的区间(找左端点)。 首先看左边区间:如果 mid 落在左边的区间,那么 mid 不可能命中到目标值,left = mid + 1。 8 在右边的一坨中,那么 mid 不能超过这个区间,right = mid。 mid 的中值计算应该为:left + (right - left) / 2(计算左端点)。 循环条件应该是:left < right,如果等于,会由于判断条件导致循环。 现象:如果 mid 落在左边,就必须超过竖划线收缩;在右边应该不断收缩,但是不能超过竖划线。

int left = 0, right = nums.size() - 1;
int mid = 0; //找左端点
while(left < right) {
    mid = left + (right - left) / 2;
    if(nums[mid] >= target) right = mid;
    else if(nums[mid] < target) left = mid + 1;
}

第三套模板: 推论:假设找 target 连续的区间(找右端点)。 首先看左边区间:如果 mid 落在左边的区间,那么 mid 可能命中到目标值,left = mid。 mid 落在右边的一坨,那么 mid 不能超过这个区间,right = mid - 1。 mid 的中值计算应该为:left + (right - left + 1) / 2(计算右端点)。 循环条件应该是:left < right,如果等于,会由于判断条件导致循环。 现象:如果 mid 落在左边,就不能超过竖划线收缩;在右边应该不断收缩,必须要超过竖划线。

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

二、简单的二分查找

题目链接:https://leetcode.cn/problems/binary-search

算法解析:这题大家套'二分算法原理剖析'的第一套模板即可。

三、找目标范围

题目链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array

算法解析:暴力解法是遍历数组,找先目标值,再看是否有连续的目标值,记录它们的下标即可。

算法解析(以下是找的到 target 的情况,需要判断找不到的情况): 首先找左端点:以上图为例,具备完美的边界(二段性),左边界的 8 比左边的 0,3,5,6 都要大,如果 mid 落在边界左边,不管怎样都要找比 mid 位置大的数,所以如果小于目标值,left = mid + 1。 那么如果 mid 落在>=8(左边界的 8)的位置,right 不应该跳过且收缩,所以 right = mid。 其次是右端点:以上图为例,具备完美的边界(二段性),同理: 如果落在最右边 8 的左边,那么 left 不能跳过这段区间,只能是 left = mid,不断收缩。 如果落在最右边 8 的右边,那么 right 最终肯定要跳过才行,所以 right = mid - 1,跳过 + 收缩。

代码:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.size() == 0) return {-1, -1};
        vector<int> V;
        int left = 0, right = nums.size() - 1;
        int mid = 0;
        //找左端点
        while(left < right) {
            mid = left + (right - left) / 2;
            if(nums[mid] >= target) right = mid;
            else if(nums[mid] < target) left = mid + 1;
        }
        if(nums[left] == target) {
            V.push_back(left);
        } else {//如果找不到
            V.push_back(-1);
        }
        //找右端点
        left = 0, right = nums.size() - 1;
        while(left < right) {
            mid = left + (right - left + 1) / 2;
            if(nums[mid] > target) right = mid - 1;
            else if(nums[mid] <= target) left = mid;
        }
        if(nums[left] == target) {
            V.push_back(left);
        } else {//如果找不到
            V.push_back(-1);
        }
        return V;
    }
};

四、搜索插入位置

题目链接:https://leetcode.cn/problems/search-insert-position

算法解析:对于有二段线的数组 + 目标值的,我们采用二分的方法,下面是思路,采用第几套模板: 我们观察这两组值: nums = [1,3,5,6], target = 2 nums = [1,3,5,6], target = 7 可以看到:找的都是稍大的位置,比如第一组目标位置是 1 号下标,那么如果 nums[i]<2,有没有可能?完全没有,所以如果算出的目标值比小,那么 left = mid + 1,只要确定了一边,那么另一边就出来了,right = mid,循环条件是 left < right,最后肯定是 left 和 right 相遇出循环,此时判断是不是目标值,再做返回值处理。

代码:

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        int mid = 0;
        //找左端点
        while(left < right) {
            mid = left + (right - left) / 2;
            if(nums[mid] >= target) right = mid;
            else if(nums[mid] < target) left = mid + 1;
        }
        if(nums[left] < target) return left + 1;
        return left;
    }
};

五、寻找旋转数组中的最小值

题目链接:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array

算法解析:对于数组中找值的这类题目,我们先看有没有二段性,很明显有:数组中最小的元素。 每旋转一次是把最后一个值拿到前面来,因此,就像一个蜿蜒的山峰。 因此可以以 nums[0] 和 nums[size-1] 来作为基准值:以 nums[0] 为例: 如果比 nums[0] 大,说明在数组第二象限,left = mid + 1(因为不可能在这段区间),反之如果<它,那么可能在第四象限,就需要缩小区间,right = mid,切记不能跳过 mid,最后处理边界情况: 如果 left 一直满足 left = mid + 1,出循环也就是 left == nums.size(),比如 0,1,2,3,4,即 left=right 的时候。

代码:

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0, right = nums.size();
        while(left < right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] >= nums[0]) left = mid + 1;
            else right = mid;
        }
        return left == nums.size() ? nums[0] : nums[left];
    }
};

目录

  1. 一、“二分”算法原理剖析
  2. 二、简单的二分查找
  3. 三、找目标范围
  4. 四、搜索插入位置
  5. 五、寻找旋转数组中的最小值
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 基于 DeepSeek-R1-Distill-Llama-8B 的 OpenSpec 协议分析
  • 2026 年主流 AI 写作工具横向测评:逻辑、拟人与成本对比
  • Eino ADK 核心解析:为什么 Agent 必须是一层独立抽象
  • 基于 Web 和 Android 的漫画阅读平台
  • OpenClaw Gateway 安装失败 systemctl --user is-enabled unavailable 排查与解决
  • 机器人调试学习规划
  • Llama-Factory 强化学习微调支持与 RLHF 模块进展解析
  • LLaMA-Factory 全流程模型训练与推理实战
  • MySQL 数据库的基本操作与管理
  • 在 PyTorch 镜像中部署 Whisper.cpp 语音识别模型
  • Qwen3Guard-Gen-WEB AI 伦理防火墙部署与实战体验
  • Git 原理与使用进阶:远程协作、标签管理及企业级模型
  • Python 字符串格式化、编码与深浅拷贝详解
  • ORB-SLAM3:开源视觉、视觉惯性及多地图 SLAM 库
  • 基于 DeepFace 与 OpenCV 的实时情绪分析器
  • 前端实时推送与 WebSocket 面试题(2026 版)
  • GitHub开源项目日报:AI代理与本地助手热榜 (2026-02-19)
  • 双指针算法实战:移动零与复写零详解
  • 数据结构:堆与优先级队列
  • Stable Diffusion 模型原理与本地部署实践

相关免费在线工具

  • 加密/解密文本

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