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

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

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

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

山峰数组的峰顶索引

题目描述

给定一个长度为 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. 总结

更多推荐文章

查看全部
  • AI Agent 实战:Agent 框架与 7 个核心实例详解
  • Rust 异步代码测试与调试实战
  • 智能家居中的 DHT11:低成本环境监测方案设计与优化
  • Linux 下 libwebkit2gtk-4.1-0 安装与实战指南
  • 使用 ClaudeCode 与 Figma-MCP 实现 UI 设计 1:1 前端还原
  • GitHub 启用双因素身份验证(2FA)配置教程
  • LVGL 嵌入式 GUI 开发指南:轻量高效开源方案
  • AI 产品经理入门指南:基础知识与模型概念详解
  • 二分查找算法原理与常见变体实战
  • WebPlotDigitizer 图表数据提取指南:从图像到精准数值的转换
  • 【2026必看 AI智能体】零基础Coze平台使用教程
  • 将二进制数组分成三个相等值的三部分算法解析
  • AI Agent 实战:从零搭建生产级框架与核心实现
  • Mac mini M4 部署 OpenClaw + Ollama 本地大模型接入飞书机器人
  • 微服务架构下Spring Session与Redis分布式会话实战
  • TeleGrip:基于 VR 的机械臂遥操作系统架构与源码解析
  • 二叉树算法实战:美国血统与公共祖先求解
  • 解决 n8n Docker 启动时 secure cookie 报错问题
  • 计算机视觉基础与实战应用指南
  • pdf-lib:JavaScript 全栈 PDF 处理方案

相关免费在线工具

  • 加密/解密文本

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