跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

二分查找实战:旋转数组最小值与点名问题

二分查找是处理有序数据的高效策略。本文通过两道经典题目解析其核心应用:一是寻找旋转排序数组中的最小值,利用数组局部有序特性,通过比较中点与边界值收缩区间;二是点名缺失数字问题,依据元素值与下标的一致性判断缺失位置。掌握“二段性”判断标准,可将时间复杂度优化至 O(log n)。

DevStack发布于 2026/3/16更新于 2026/4/262 浏览
二分查找实战:旋转数组最小值与点名问题

二分查找实战:旋转数组最小值与点名问题

二分查找不仅仅是简单的折半搜索,关键在于找到合适的判断标准,将查找区间一分为二。下面通过两道经典题目,深入剖析二分法在不同场景下的应用逻辑。

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

题目描述: 已知一个长度为 n 的升序排列数组,在某个未知的下标 k 处进行了旋转(例如 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2])。请找出其中最小的元素。

解题思路

旋转后的数组可以看作由两个有序部分组成。虽然整体无序,但局部依然保留了单调性。我们可以利用这种特性来缩小搜索范围。

核心在于比较中间元素 mid 与边界值的关系:

  • 如果 nums[mid] >= nums[0],说明 mid 位于左半部分(较大值区域),最小值一定在右侧,因此更新 left = mid + 1。
  • 如果 nums[mid] < nums[0],说明 mid 位于右半部分(较小值区域),最小值可能是 mid 或者在左侧,因此更新 right = mid。

当 left == right 时,指针指向的元素即为最小值。此外,若数组本身未发生旋转(即 nums[0] <= nums[n-1]),直接返回首元素即可。

参考实现

class Solution {
public:
    int findMin(vector<int>& nums) {
        int n = nums.size();
        // 如果数组没有旋转,第一个元素就是最小值
        if (nums[0] <= nums[n - 1]) {
            return nums[0];
        }

        int left = 0, right = n - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            // 中点值大于等于首元素,说明在左半段,最小值在右边
            if (nums[mid] >= nums[0]) {
                left = mid + 1;
            } else {
                // 否则在右半段,最小值在左边或就是 mid
                right = mid;
            }
        }
        return nums[left];
    }
};

24. 点名

题目描述: 某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于递增数组 records,若某位同学缺席,则其学号缺失。请返回缺席同学的学号。

解题思路

这道题同样可以利用二分查找优化时间复杂度至 O(log n)。观察数组特征可以发现明显的'二段性':

  • 在缺失数字出现之前,数组元素的值与其下标是相等的(nums[i] == i)。
  • 从缺失数字开始,后续所有元素的值都会比下标大 1(nums[i] > i)。

基于这个规律,我们比较 nums[mid] 和 mid:

  • 若 nums[mid] == mid,说明缺失位置在右侧,令 left = mid + 1。
  • 若 nums[mid] != mid(实际为 > mid),说明缺失位置在左侧或就是当前位置,令 right = mid。

循环结束后,left 指向第一个不满足 nums[i] == i 的位置。如果遍历完整个数组都满足条件,则缺失的是最后一个编号 n。

参考实现

class Solution {
public:
    int takeAttendance(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            // 值等于下标,说明缺失点在右侧
            if (nums[mid] == mid) {
                left = mid + 1;
            } else {
                // 值不等于下标,缺失点在左侧
                right = mid;
            }
        }
        
        // 如果所有位置都匹配,则缺失的是最后一个数
        if (nums[left] == left) {
            return left + 1;
        }
        return left;
    }
};

这两道题展示了二分查找的核心思想:不要只盯着'找目标值',更要关注'如何根据当前状态划分区间'。只要找到那个能让区间一分为二的判断依据,就能高效解决问题。

目录

  1. 二分查找实战:旋转数组最小值与点名问题
  2. 23. 寻找旋转排序数组中的最小值
  3. 解题思路
  4. 参考实现
  5. 24. 点名
  6. 解题思路
  7. 参考实现
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • STM32Cube AI Studio:MCU 端 AI 模型优化、验证与代码生成
  • Flink 运行时组件深度解析:架构设计与实战
  • TRAE Skills 全解析:从概念到实践
  • VS Code 远程连接服务器后 GitHub Copilot 无法使用的问题排查
  • 自然语言处理在金融领域的应用与实战
  • 五种主流编程语言的特点与职业发展建议
  • 使用 MCP Server 插件将 Dify 工作流发布为第三方服务
  • 策略模式详解:将 if-else 转化为可切换算法
  • 基于 Qwen3-VL-WEBUI 的数字人构建与部署实战
  • SpringBoot 整合 Neo4j 图数据库项目实战
  • RAG 入门:LangChain Embedding 介绍与使用
  • OpenClaw 跨平台部署:WSL Ubuntu 与 CentOS9 安装及飞书对接
  • 大模型人才年薪百万引关注,行业需求旺盛
  • 使用 Selenium 搭建免费 Web 搜索 API 服务
  • Linux 内核源码下载指南:官方源、镜像加速与完整性校验
  • Java 是否会被 Python 取代
  • 基于 Microi 吾码的服务器虚拟化资源管理与网络配置实践
  • Llama Factory 微调显存估算与云资源配置指南
  • GLM-4v-9b 开源模型优势与闭源 API 成本效益对比
  • Rust 嵌入式开发实战:从 ARM 裸机编程到 RTOS 应用

相关免费在线工具

  • 加密/解密文本

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