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

二分查找算法原理与常见场景应用

综述由AI生成二分查找是处理有序数据查找的高效算法,核心在于通过比较中间值排除一半区间。文章解析了三套二分模板,分别用于基础查找、确定目标范围、搜索插入位置以及寻找旋转数组最小值。重点讲解了边界条件的判断逻辑,如 left=mid+1 与 right=mid 的区别,以及如何避免死循环。通过 C++ 代码示例展示了具体实现,帮助理解算法在面试和实际开发中的应用。

全栈工匠发布于 2026/3/15更新于 2026/6/1326 浏览
二分查找算法原理与常见场景应用

【一】'二分'算法原理剖析

二分查找通常要求数据有序。其本质是通过目标值排除一半的区间,解决传统的从头到尾遍历查找。只要目标数据与目标值满足一定的大小关系,即可使用二分法。

第一套模版:

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 + 1) / 2;
    if (nums[mid] > target) right = mid - 1;
    else if (nums[mid] <= target) left = mid;
}

【二】简单的二分查找

(1)题目链接

https://leetcode.cn/problems/binary-search

(2)算法解析

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

【三】找目标范围

(1)题目链接

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

(2)算法解析

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

算法解析:(以下是找的到 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,跳过 + 收缩。

(3)代码
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;
    }
};

【四】搜索插入位置

(1)题目链接

https://leetcode.cn/problems/search-insert-position

(2)算法解析

对于有二段线的数组 + 目标值的,我们采用二分的方法,下面是思路,采用第几套模板:

我们观察这两组值: 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 相遇出循环,此时判断是不是目标值,再做返回值处理。

(3)代码
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;
    }
};

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

(1)题目链接

https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array

(2)算法解析

对于数组中找值的这类题目,我们先看有没有二段性,很明显有:数组中最小的元素。 每旋转一次是把最后一个值拿到前面来,因此,就像一个蜿蜒的山峰:

因此可以以 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 的时候。

(3)代码
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. (1)题目链接
  4. (2)算法解析
  5. 【三】找目标范围
  6. (1)题目链接
  7. (2)算法解析
  8. (3)代码
  9. 【四】搜索插入位置
  10. (1)题目链接
  11. (2)算法解析
  12. (3)代码
  13. 【五】寻找旋转数组中的最小值
  14. (1)题目链接
  15. (2)算法解析
  16. (3)代码
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Qwen3-VL WEBUI 部署与交错 MRoPE 长视频推理实战
  • Cursor 中 MCP 服务配置与使用指南
  • Python 核心语法精讲:变量、流程控制与数据结构
  • Cursor 中配置与使用 MCP 服务指南
  • Timed Out 错误处理:传统方法与 AI 辅助对比
  • AI 驱动游戏:鸿蒙生态的机会在哪里?
  • 算法实战:LeetCode 1419 数青蛙(模拟法)
  • 在 Cursor 中配置和使用 MCP 服务
  • 在 Cursor 中配置和使用 MCP 服务
  • 大语言模型(LLM)初学者入门教程与学习路线指南
  • GitHub Copilot、Cursor、JetBrains AI Assistant 实战指南
  • Cursor 中 MCP 服务配置与使用指南
  • Cursor 中使用 MCP 服务配置与实战指南
  • 在 Cursor 中配置和使用 MCP 服务实现自动化任务
  • UniApp 小程序自定义底部 TabBar 闪烁白屏优化方案
  • Mac 上主流 SSH 终端客户端对比评测
  • 道德驱动机制设计在分层碳交易市场的应用
  • LangChain 实战:Agent 思维框架与代码实现
  • JavaAI 智能编程助手:功能特性与全流程开发指南
  • JavaScript 运算符与流程控制详解

相关免费在线工具

  • 加密/解密文本

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