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

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

基于二分查找解决山峰数组峰顶索引与寻找峰值问题。利用山脉数组单调性特征,通过比较中间值与相邻元素大小,快速锁定峰值区域。两种场景均具备二段性,可将线性扫描优化为对数级复杂度,关键在于正确设定左右边界收缩条件。

JavaCoder发布于 2026/3/28更新于 2026/9/942 浏览
二分查找实战:山峰数组峰顶索引与寻找峰值

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

在算法面试中,利用单调性或二段性进行二分查找是高频考点。今天我们来深入探讨两个经典问题:山脉数组的峰顶索引和寻找任意峰值。这两个问题看似不同,但核心逻辑都在于通过比较中间值与相邻元素的关系,快速缩小搜索范围。

1. 山脉数组的峰顶索引

题目描述

给定一个长度为 n 的山脉数组 arr,其中存在唯一的峰顶索引 i,满足:

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

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

解题思路

山脉数组具有明显的单调性特征:左侧严格递增,右侧严格递减。这意味着数组中存在一个分界点,使得前半部分满足 arr[mid] < arr[mid + 1],后半部分满足 arr[mid] > arr[mid + 1]。

我们可以利用这一特性进行二分查找:

  1. 初始化左边界 left = 0,右边界 right = arr.size()。
  2. 计算中间位置 mid。
  3. 如果 arr[mid] < arr[mid + 1],说明当前处于上升阶段,峰顶在右侧,更新 left = mid + 1。
  4. 否则,说明当前处于下降阶段或就是峰顶,更新 right = mid。
  5. 循环直到 left == right,此时即为峰顶索引。

这种写法实际上是在寻找第一个不满足 arr[mid] < arr[mid + 1] 的位置,即区间的右端点。

代码实现

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 0;
        int right = arr.size();
        
        while (left < right) {
            int mid = left + (right - left) / 2;
            // 判断趋势:如果在上升段,峰顶肯定在右边
            if (arr[mid] < arr[mid + 1]) {
                left = mid + 1;
            } else {
                // 否则峰顶在左边或就是当前位置
                right = mid;
            }
        }
        return left;
    }
};

注意: 这里的 mid 计算采用向下取整,配合 left = mid + 1 可以避免死循环。同时访问 mid + 1 时需注意边界,由于题目保证是山脉数组且长度至少为 3,mid 不会越界到最后一个元素。


2. 寻找峰值

题目描述

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

解题思路

与山脉数组不同,这里不需要整个数组先增后减,只需要找到一个局部极大值即可。关键在于理解'二段性':

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

  • 如果 nums[i] < nums[i+1],说明处于上升趋势,根据边界条件(最左侧为负无穷),峰值一定存在于 [i+1, end] 区间内。
  • 如果 nums[i] >= nums[i+1],说明处于下降趋势或持平,峰值一定存在于 [start, i] 区间内。

因此,我们依然可以使用二分查找,每次将搜索空间减半。

代码实现

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;
    }
};

关键点解析:

  • 为什么 right = mid 而不是 mid - 1?因为当 nums[mid] >= nums[mid+1] 时,mid 本身就有可能是峰值,不能排除。
  • 为什么 left = mid + 1?因为当 nums[mid] < nums[mid+1] 时,mid 肯定不是峰值,可以直接跳过。
  • 时间复杂度均为 O(log n),空间复杂度 O(1)。

总结

这两道题的核心都在于识别数组中的单调性变化。二分查找不仅仅是用于有序数组的查找,更适用于任何具备'二段性'的问题场景。在实际编码中,务必注意边界条件的处理以及 mid 的计算方式,避免死循环或越界访问。掌握这种思维模式,能帮助你解决更多复杂的搜索类问题。

目录

  1. 二分查找实战:山峰数组峰顶索引与寻找峰值
  2. 1. 山脉数组的峰顶索引
  3. 题目描述
  4. 解题思路
  5. 代码实现
  6. 2. 寻找峰值
  7. 题目描述
  8. 解题思路
  9. 代码实现
  10. 总结

更多推荐文章

查看全部
  • C++ 异常处理机制详解:从基础到实践
  • 25 个实用提示词:有效降低 AI 生成内容的检测率
  • 基于 C++ 构建 DeepSeek 大模型推理 SDK:架构设计与工程落地
  • 二分算法实战:A-B 数对与高考志愿问题解析
  • 单向链表六大核心操作详解:销毁、查找、倒置与排序
  • Flutter 与 Web 混合开发实践:构建跨平台统一体验
  • AI绘画的商业应用:广告、插画与游戏设计
  • Spring Cloud Gateway 微服务网关核心原理与实战
  • AI 编程工具全方位对比:从 Copilot 到 Cursor,开发者如何选择?
  • Python 并发编程:多线程与多进程实战
  • 手撕 vector:从 0 到 1 模拟实现 STL 容器
  • TCGA 结直肠癌 WSI 数据下载与临床信息解析
  • 九联 UNT413A 刷机全流程解析与避坑
  • Visual C++ 运行库管理指南:故障诊断与部署维护
  • DFS 深度优先搜索:从原理到实战
  • JavaScript 生成 UUID 的常见方案与避坑指南
  • C++ 继承机制:同名成员隐藏规则与默认函数详解
  • MySQL 数据类型详解:数值、字符串与时间类型实战
  • 基于 BlueBubbles 与 OpenClaw 的本地 iMessage AI 集成方案
  • Linux 进程创建与终止:fork 原理与退出机制实战

相关免费在线工具

  • 加密/解密文本

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