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

二分查找实战:山峰数组峰顶索引与寻找峰值

二分查找是处理有序或半有序数据的高效手段。通过两道经典题目——山峰数组的峰顶索引与寻找峰值,演示如何利用“二段性”特征将时间复杂度优化至 O(log n)。重点在于分析数组单调性变化点,通过比较中间值与相邻元素关系,快速锁定目标位置。掌握这一模式有助于应对各类变体问题。

云朵棉花糖发布于 2026/3/27更新于 2026/6/1118 浏览
二分查找实战:山峰数组峰顶索引与寻找峰值

二分查找实战:山峰数组峰顶索引与寻找峰值

在算法面试中,二分查找的应用远不止于简单的有序数组查找。当数据呈现某种特定的单调性或'二段性'时,我们依然可以利用二分思想来加速搜索。今天主要拆解两道基于二分查找的经典题目:山峰数组的峰顶索引和寻找峰值。

1. 山峰数组的峰顶索引

题目描述

给定一个长度为 n 的山脉数组 arr,其中存在某个索引 i (0 < i < n - 1) 满足:

  • arr[0] < arr[1] < ... < arr[i]
  • arr[i] > arr[i+1] > ... > arr[n-1]

我们需要找到这个峰顶索引 i。

山脉数组示意图

解题思路

这道题的关键在于利用数组的单调性。虽然整个数组不是有序的,但我们可以将其视为两个有序部分:上升段和下降段。

观察中间位置 mid 与其相邻元素的关系:

  • 如果 arr[mid] < arr[mid + 1],说明当前处于上升阶段,峰值一定在右侧(包含 mid+1)。
  • 如果 arr[mid] > arr[mid + 1],说明当前处于下降阶段或已经是峰值,峰值一定在左侧(包含 mid)。

通过不断缩小搜索区间,最终 left 和 right 会收敛到同一个位置,即峰值索引。

C++ 实现

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 0;
        int right = arr.size();
        
        while (left < right) {
            // 使用向上取整避免死循环,确保 mid 偏向右侧
            int mid = left + (right - left + 1) / 2;
            
            // 比较 mid 与前一个元素,判断趋势
            if (arr[mid - 1] < arr[mid]) {
                // 上升趋势,峰值在右侧
                left = mid;
            } else {
                // 下降趋势,峰值在左侧
                right = mid - 1;
            }
        }
        return left;
    }
};

代码细节解析: 这里我选择了 [小于等于峰值], [大于峰值] 的区间划分方式。注意 mid 的计算使用了 (right - left + 1) / 2,这是为了防止 left 和 right 相邻时出现死循环。因为当 left = mid 时,如果 mid 计算偏左,left 永远不会增加。实际运行中,这种写法能更稳健地定位右边界。

算法流程解析


2. 寻找峰值

题目描述

给定一个整数数组 nums,找到任意一个峰值元素的索引并返回。峰值元素是指其值严格大于左右相邻值的元素。假设 nums[-1] = nums[n] = -∞。

寻找峰值示意图

解题思路

这道题比上一道稍微抽象一些,它不要求整个数组是山脉形状,只要求找到一个局部峰值。核心依然是寻找'二段性'。

任取一个点 i,比较它与下一个点 i+1 的值:

  • 若 nums[i] < nums[i + 1]:说明右侧有上升趋势。由于最右侧边界是负无穷,那么右侧区域必然存在一个峰值(从上升转为下降的点)。此时可以去右侧寻找。
  • 若 nums[i] > nums[i + 1]:说明左侧有上升趋势(或者当前就是峰值)。由于最左侧边界是负无穷,左侧区域必然存在一个峰值。此时可以去左侧寻找。

只要确定了哪一侧可能存在峰值,就可以用二分法快速逼近。

C++ 实现

class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1;
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            
            // 比较 mid 与 mid + 1
            if (nums[mid] < nums[mid + 1]) {
                // 上升趋势,峰值在右侧
                left = mid + 1;
            } else {
                // 下降趋势或峰值,峰值在左侧(含 mid)
                right = mid;
            }
        }
        return left;
    }
};

代码细节解析: 这里的区间划分是 [小于峰值], [大于等于峰值]。注意 mid 的计算没有加 1,因为我们使用的是 left = mid + 1 来跳过当前点,所以不需要担心死循环问题。这种写法逻辑上更直观:只要右边比当前大,就往右跑;否则就停在左边找。

算法流程解析


总结

这两道题的核心都在于识别'趋势'。一旦确定了哪一侧可能存在峰值,就可以果断舍弃另一侧。掌握这一模式有助于应对各类变体问题,比如旋转排序数组的最小值等。在实际编码时,务必注意边界条件和 mid 的计算方式,避免陷入死循环。

目录

  1. 二分查找实战:山峰数组峰顶索引与寻找峰值
  2. 1. 山峰数组的峰顶索引
  3. 题目描述
  4. 解题思路
  5. C++ 实现
  6. 2. 寻找峰值
  7. 题目描述
  8. 解题思路
  9. C++ 实现
  10. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Apache SeaTunnel Web 可视化数据集成实战指南
  • 基于 YOLO12 的无人机航拍视角目标检测系统
  • Cogito-v1-preview-llama-3B 开源模型部署与特性介绍
  • 大语言模型综述:背景、技术与资源
  • GitHub Copilot 配置与性能优化关键技术
  • Google 发布多模态嵌入模型 Gemini Embedding 2,MuleRun 推出自进化个人 AI
  • 深度剖析 Rokid SLAM 算法:从传感器融合到空间重建的技术链路
  • CoPaw 个人助理部署与定制指南:从零开始打造专属数字搭档
  • 6 款主流 AI 写作工具实测:网文创作效率对比
  • GitHub Copilot 学生认证指南:Pro 版免费权益获取流程
  • Z-Image-Turbo 极速云端创作室入门与提示词实战指南
  • 大模型 Agent 智能体原理与核心架构解析
  • GitHub Copilot 学生认证指南:Pro 版免费权益获取
  • Coze 基于行业文章生成思维导图工作流详解
  • 本地部署 Apache Answer 问答平台并实现公网访问
  • 深度拆解:为什么学了很多 AI 工具却赚不到钱
  • SpringBoot 启动引导类的命名约定与核心原理
  • UI-UX-Pro-Max Skill 实战指南:AI 辅助前端界面开发
  • GitHub Copilot 学生认证流程详解与 Pro 版激活指南
  • TRAE 中国版 SOLO 模式全量免费开放,重塑 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