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

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

利用二分查找解决山峰数组峰顶索引及寻找峰值问题。核心在于识别数组局部极大值的二段性特征,通过比较中间值与相邻元素大小关系收缩搜索区间,将时间复杂度优化至对数级。C++ 实现中需注意边界处理与 mid 计算方式,避免死循环或越界,相比线性扫描显著提升效率。

星星泡饭发布于 2026/3/24更新于 2026/5/87 浏览
二分查找实战:山峰数组峰顶索引与寻找峰值解析

山峰数组的峰顶索引

题目描述

给定一个长度为 n 的山峰数组 arr,满足:

  • arr.length >= 3
  • 存在 i (0 < i < arr.length - 1) 使得 arr[0] < arr[1] < ... < arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1]

找出任意一个满足条件的索引 i。

参考链接:852. 山脉数组的峰顶索引 - LeetCode

解题思路

这道题的核心在于利用'二段性'进行二分查找。观察数组特性,在峰值左侧是严格递增的,右侧是严格递减的。

我们可以根据中间值 mid 与其后一个值 mid + 1 的关系来判断当前处于哪一段:

  • 如果 arr[mid] < arr[mid + 1],说明 mid 处于上升坡,峰值一定在 mid 右侧(包含 mid + 1)。
  • 如果 arr[mid] > arr[mid + 1],说明 mid 处于下降坡,或者就是峰值本身,峰值一定在 mid 左侧(包含 mid)。

注意边界条件,由于题目保证是山脉数组,不需要额外检查左右边界是否越界。

C++ 实现

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 0;
        int right = arr.size() - 1;
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            
            // 如果中间值小于右边,说明在上升阶段,峰值在右侧
            if (arr[mid] < arr[mid + 1]) {
                left = mid + 1;
            } else {
                // 否则在下降阶段或就是峰值,峰值在左侧(含 mid)
                right = mid;
            }
        }
        return left;
    }
};

山峰数组示意图

寻找峰值

题目描述

给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。你可以假设 nums[-1] = nums[n] = -∞。

参考链接:162. 寻找峰值 - LeetCode

解题思路

虽然题目允许返回任意峰值,但本质上还是寻找局部极大值。同样可以利用二分查找优化时间复杂度到 O(log n)。

关键在于理解'二段性':对于任意位置 i,如果 nums[i] < nums[i+1],说明右侧有上升趋势,且最右侧是负无穷,那么右侧必然存在一个峰值;反之,如果 nums[i] > nums[i+1],说明左侧有上升趋势,左侧必然存在峰值。

因此,每次比较 mid 和 mid+1:

  • 若 nums[mid] < nums[mid+1],去右半边找。
  • 若 nums[mid] > nums[mid+1],去左半边找(mid 可能是峰值)。

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

寻找峰值流程

总结

这两道题都利用了二分查找的特性,将线性扫描 O(n) 优化为对数级 O(log n)。核心技巧在于通过比较相邻元素确定搜索方向,无需遍历整个数组。在实际工程中,面对有序或半有序数据时,优先考虑此类分治策略。

目录

  1. 山峰数组的峰顶索引
  2. 题目描述
  3. 解题思路
  4. C++ 实现
  5. 寻找峰值
  6. 题目描述
  7. 解题思路
  8. C++ 实现
  9. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Copilot 核心功能、版本区别及使用场景
  • ZeroClaw Gateway + LM Studio + Reflex 本地 AI 管理面板搭建
  • 前端面试复盘:透过问题看技术深度与工程素养
  • 通义万相 2.1 开源视频生成模型功能解析
  • 基于 Dify 的 CRNN OCR 集成方案实现智能表单识别
  • 分布式系统唯一 ID 生成方案技术详解
  • 基于 Java 大数据的智能家居能耗预测与节能策略优化实战
  • 无人机视角高速路面损害检测数据集及 YOLOv8 训练方案
  • 微信 Mac 版防撤回与多开工具:WeChatTweak-macOS
  • PyCharm 安装通义灵码插件实现 AI 辅助编码
  • whisperX 入门指南:从安装到实现语音识别功能
  • 非科班背景字节后端面试经历与备战经验分享
  • Android 使用 Intent.ACTION_SEND 分享图片和文字内容示例
  • Claude Code 进阶指南:利用 Everything 配置打造有记忆的 AI 助手
  • 金仓数据库 KingbaseES 在电商平台迁移与运维中的实践
  • 企业微信外部群机器人主动推送消息实现指南
  • Docker 镜像基础与操作详解
  • 数据结构与算法:Morris 遍历
  • 服务器导轨分类及安装拆卸实操指南(含 Dell R740 示例)
  • npm 安装 OpenClaw 时 Git 报错的解决方法

相关免费在线工具

  • 加密/解密文本

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