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

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

二分查找算法在定位极值问题上效率显著。针对山峰数组峰顶索引问题,利用数组先增后减的单调特性,通过比较中间元素与前驱元素确定搜索区间,时间复杂度降为 O(log n)。寻找峰值问题则进一步泛化,依据 mid 与 mid+1 的大小关系判断峰值位于左侧还是右侧,无需完整排序即可锁定任意峰值。两题均体现了二分法中判断趋势、缩小范围的核心思想,是面试高频考点。

GopherDev发布于 2026/3/280 浏览
二分查找实战:山峰数组峰顶索引与寻找峰值

二分查找是处理有序或具有单调性数据结构的利器。今天我们来通过两道经典题目,深入理解如何利用二分法在 O(log n) 时间内定位极值点。

山峰数组的峰顶索引

给定一个山脉数组,我们需要找到其峰顶元素的索引。山脉数组的定义是存在某个索引 i,使得左侧严格递增,右侧严格递减。

暴力遍历虽然可行,但既然数组具备单调性特征,二分查找才是正解。关键在于判断当前中间位置处于上升段还是下降段。如果 arr[mid] 大于前一个元素,说明我们还在爬坡阶段,峰顶肯定在右边(包括 mid);反之,如果在下坡或者已经过了峰顶,则向左收缩。

具体实现时,左右边界初始化为 1 和 size-2,因为首尾不可能是峰顶。循环条件设为 left < right,避免死循环。当 arr[mid] > arr[mid-1] 时,将左边界移至 mid,否则右边界移到 mid-1。最终 left 即为答案。

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

寻找峰值

第二道题稍微抽象一点,要求找出任意一个峰值元素。峰值定义为大于相邻元素的值。数组两端可视作负无穷。

这道题的核心在于'二段性'。对于任意中间点 mid,比较它和下一个点 mid+1 的大小。如果 nums[mid] > nums[mid+1],说明此刻处于下降趋势,那么峰值一定在左侧(包含 mid),因为左边有负无穷作为起点,必然存在一个高点;反之,如果 nums[mid] < nums[mid+1],说明正在上升,峰值在右侧(不包含 mid)。

同样使用二分框架,边界为 0 到 size-1。若满足下降条件,右边界收至 mid;否则左边界推至 mid+1。循环结束时 left 指向的就是一个峰值位置。

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

这两道题展示了二分查找在处理局部极值问题时的通用模式:利用单调性或趋势判断搜索方向。掌握这种'找趋势'的思路,比死记硬背模板更重要。

目录

  1. 山峰数组的峰顶索引
  2. 寻找峰值
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Claude Code 配置指南:CLAUDE.md 加载机制与最佳实践
  • LIO-SAM 算法在 Ubuntu 22.04 与 ROS2 Humble 环境下的仿真部署实战
  • OpenClaw 部署指南:Minimax/DeepSeek 模型与飞书机器人集成
  • C++ 多态详解:从实现条件到底层原理
  • 位运算算法实战:6 道经典题目详解(字符唯一性、缺失数字等)
  • KingbaseES 内核级 SQL 防火墙:白名单机制与零误报实践
  • PowerShell Invoke-WebRequest 报错 Invalid URL 和 CommandNotFound 排查指南
  • RTD1296PB 与 RK3568:NAS 与智能家居芯片实战对比
  • 位运算算法实战:字符唯一性、丢失数字与消失数字
  • 前端 JS 加载失败怎么办?重试与多源备份方案
  • 前端地图开发基础:服务类型、坐标系与 SDK 简介
  • OpenClaw 部署指南:集成 Minimax/DeepSeek 模型与飞书机器人
  • OpenClaw 部署指南:模型接入与飞书机器人配置
  • 秋叶绘世 Stable Diffusion 整合包技术解析与使用指南
  • AI 零基础入门:从概念到实践的完整指南
  • 阿里开源 Page-Agent:一行 JS 代码实现大模型前端 DOM 操控
  • OpenClaw 部署指南:环境搭建、模型接入与飞书机器人配置
  • 算法实战:Z 字形变换与外观数列的模拟解法
  • Win10/11 系统下 WSL2 + Ubuntu 20.04 全流程安装指南(支持安装至 D 盘)
  • 2026 年 3 月全球 AI 前沿动态:模型、智能体与硬件突破

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,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

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online