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

二分查找实战:旋转数组最小值与缺失数字

二分查找在特定场景下的两种典型应用。针对旋转排序数组,利用右端点作为基准判断区间单调性,快速定位最小值;对于有序数组中的缺失数字,依据元素值与下标的对应关系构建二段性,通过二分逼近首个不匹配位置。两者均将时间复杂度优化至 O(logN),避免线性遍历。

1739658202发布于 2026/3/29更新于 2026/7/3030 浏览
二分查找实战:旋转数组最小值与缺失数字

23. 寻找旋转排序数组中的最小值

题目描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。例如,[0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2]。请找出其中最小的元素。

解题核心

这道题的关键在于利用数组的'二段性'。虽然整体不是有序的,但我们可以观察到:

  1. 如果我们将数组分为两部分,一部分是严格递增的,另一部分也是严格递增的(只是数值较小)。
  2. 最小值一定位于那个'断点'处。
  3. 通过比较中间值 mid 和右端点 right 的值,我们可以判断 mid 落在哪一段。

具体逻辑:

  • 若 nums[mid] > nums[right],说明最小值在 mid 右侧(因为 mid 处于较大的前半段),此时 left = mid + 1。
  • 若 nums[mid] <= nums[right],说明最小值在 mid 左侧或就是 mid 本身(mid 处于较小的后半段),此时 right = mid。

当 left == right 时,循环结束,该位置即为最小值。

C++ 参考实现

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1;
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            // 以右端点为基准进行比较
            if (nums[mid] > nums[right]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return nums[left];
    }
};

注意:这里选择 nums[right] 作为参照物比 nums[0] 更稳健,避免了处理数组完全有序时的特殊分支判断,代码更简洁。


24. 0~n-1 中缺失的数字

题目描述

一个长度为 n-1 的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围 0~n-1 之内。在范围 0~n-1 内的 n 个数字中有且只有一个数字不在该数组中,请找出这个数字。

解题核心

这道题同样可以利用二分查找将时间复杂度优化到 O(logN)。观察数组下标与数值的对应关系:

  • 在缺失数字出现之前,所有元素都满足 nums[i] == i。
  • 在缺失数字出现之后,由于前面的数字少了一个,后续元素都会发生偏移,满足 nums[i] != i。

这种'前真后假'的特性构成了典型的二段性,非常适合二分查找。

具体逻辑:

  • 计算中间索引 mid。
  • 若 nums[mid] == mid,说明缺失的数字在右侧,left = mid + 1。
  • 若 nums[mid] != mid,说明缺失的数字在左侧(包含 mid),right = mid。

循环结束后,left 指向第一个不满足 nums[i] == i 的位置,即缺失的数字。

C++ 参考实现

class Solution {
public:
    int takeAttendance(vector<int>& records) {
        int left = 0;
        int right = records.size() - 1;
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (records[mid] == mid) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        
        // 循环结束时 left 指向第一个不匹配的位置
        // 如果整个数组都匹配(理论上不会发生,除非数据异常),则返回 n
        return left;
    }
};

总结

这两道题展示了二分查找在不同场景下的变体应用:

  1. 旋转数组:通过比较中间值与边界值来判断单调区间,从而收缩搜索范围。
  2. 缺失数字:利用索引与数值的等差关系构建二段性,定位断点。

掌握这些模式后,遇到类似的'局部有序'或'索引偏移'问题,就能迅速联想到二分查找的解法。

目录

  1. 23. 寻找旋转排序数组中的最小值
  2. 题目描述
  3. 解题核心
  4. C++ 参考实现
  5. 24. 0~n-1 中缺失的数字
  6. 题目描述
  7. 解题核心
  8. C++ 参考实现
  9. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 13 篇必读的大模型前沿论文
  • C++ 类和对象:隐藏的 this 指针
  • 多种页面动画效果实现:星空、时钟与粒子特效
  • IPIDEA 网页抓取 API 实战:eBay 商品数据采集与 Python 接入
  • C# 字符串分割转换为整数数组或列表
  • AI 大模型通信机制解析:流式传输与数据封装逻辑
  • C++ 模板进阶:特化、类型萃取与可变参数
  • OpenClaw 安装百度网页搜索技能 (baidu-web-search)
  • Python 中的 == 与 is:本质区别与最佳实践
  • Spring Boot 实战:分组校验、Redis 登录与多环境配置
  • C++ 红黑树实现详解:规则、结构与核心操作
  • 为 AI 机器人构建安全私信访问机制:Secure DM Pairing 解析
  • Python 系统学习路线与核心开发技术详解
  • 数据库迁移 TCO 全景账本:MySQL 替代隐性成本与工具链实战
  • Python 爬虫实战:抓取小说并保存为本地 TXT 文件
  • Python 异步编程与协程实战指南
  • C++26 constexpr 动态内存语义引入:运行时开销终结?
  • AI 创作入门:普通人如何通过互动实现成长
  • AI Agent 安全事件与 Python 开发工具趋势分析
  • 基于 Unity 和 AI 零代码制作小游戏“飞翔的牛马”

相关免费在线工具

  • 加密/解密文本

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