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

二分查找进阶:峰值、旋转数组与缺失数字

综述由AI生成探讨二分查找在无序峰值、旋转数组及缺失数字场景下的应用。通过引入二段性概念,展示了如何在非严格有序数据中寻找特定目标。内容涵盖峰值元素的左右边界判定、旋转数组最小值的两种比较策略,以及基于下标与值关系的缺失数字定位方法。所有方案均优化至 O(log N) 时间复杂度,并提供了 C++ 实现细节与边界条件处理。

监控大屏发布于 2026/3/15更新于 2026/6/218 浏览
二分查找进阶:峰值、旋转数组与缺失数字

寻找峰值

题目背景

这道题的输入是一个看似无序的数组。不同于常规的二分查找,它没有全局有序性,但局部存在二段性特征。我们需要找到一个索引,其值大于左右相邻元素。

文章配图 文章配图

暴力遍历虽然直观,但时间复杂度为 O(N)。实际上,我们可以利用'峰值'的定义:如果 arr[i] > arr[i + 1],说明左侧存在下降趋势,而左边界可视为负无穷,因此答案一定在左半部分;反之亦然。这构成了二段性。

代码实现

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

并非只有有序数组才能用二分,只要存在二段性即可。

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

题目背景

给定一个升序数组,经过若干次旋转后,找到最小值。要求时间复杂度为 O(log N)。

文章配图 文章配图

暴力遍历是 O(N),不符合要求。核心在于判断 mid 落在哪一段(递增段还是旋转点后的递减段)。

算法原理

我们将数组分为两段:AB 段和 CD 段。最小值位于 D 点。若 mid 的值小于最后一个元素 nums[x],说明 mid 在右侧递增段,最小值在左边或就是 mid;若 mid 大于 nums[x],说明 mid 在左侧递增段,最小值在右边。

代码实现

参照物选择末尾元素:

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

若参照物选择开头元素 nums[0],需额外处理未旋转的情况(即整个数组递增):

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

寻找缺失的数字

题目背景

在 0 到 n-1 的序列中,有一个数字缺失。

文章配图 文章配图

数学求和、哈希等方法虽可行,但空间或时间复杂度不够优。利用下标与值的对应关系可实现 O(log N)。

算法原理

缺失数字之前,元素值等于下标;缺失数字之后,元素值大于下标。这就是二段性。我们要找的是右侧区间的左端点。

代码实现

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

注意边界情况:若数组完整无缺失(如 0,1,2,3),则缺失的是 4,此时 left 会走到末尾,需特殊判断返回 left + 1。

目录

  1. 寻找峰值
  2. 题目背景
  3. 代码实现
  4. 寻找旋转排序数组中的最小值
  5. 题目背景
  6. 算法原理
  7. 代码实现
  8. 寻找缺失的数字
  9. 题目背景
  10. 算法原理
  11. 代码实现
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • JavaScript Proxy 代理机制与核心方法详解

相关免费在线工具

  • 加密/解密文本

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