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

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

探讨二分查找在山脉数组问题中的应用,涵盖峰顶索引与寻找峰值两个经典题目。针对山脉数组峰顶索引,对比了线性遍历与二分查找两种方案,重点解析如何利用单调性将时间复杂度优化至对数级。对于寻找峰值问题,通过分析相邻元素的大小关系确定搜索方向,利用二段性实现高效定位。文章提供 C++ 代码实现及复杂度分析,帮助读者掌握二分查找处理局部极值问题的核心技巧。

SecGuard发布于 2026/3/15更新于 2026/6/2017 浏览
二分查找实战:山脉数组的峰顶索引与寻找峰值

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

在算法面试中,二分查找的应用场景远不止于有序数组的查找。当数据具备某种单调性或二段性特征时,二分法同样能发挥奇效。本文通过两道经典题目——「山脉数组的峰顶索引」和「寻找峰值」,深入剖析如何利用二分查找高效定位局部极值。

021 山脉数组的峰顶索引

题目描述:

文章配图

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

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

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

思路一:暴力遍历

最直观的方法是遍历数组,检查每个元素是否大于其左右相邻的元素。由于题目保证是山脉数组,一旦找到满足条件的元素即可返回。

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int n = arr.size();
        // 遍历数组内每一个元素,直到找到峰顶
        for (int i = 1; i < n - 1; i++) {
            // 峰顶满足的条件:比两侧都大
            if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) {
                return i;
            }
        }
        return -1;
    }
};

时间复杂度: O(n),空间复杂度: O(1)。

虽然可行,但在数据量较大时效率较低。既然数组具有明显的上升和下降趋势,我们可以利用这一特性优化搜索过程。

思路二:二分查找

核心逻辑

观察山脉数组的特性,我们可以将数组分为两段:

  1. 上升段:arr[mid] > arr[mid - 1],说明 mid 位于山峰左侧或就是山峰。
  2. 下降段:arr[mid] < arr[mid - 1],说明 mid 位于山峰右侧。

基于此,我们可以通过比较 mid 与其前驱元素的大小关系来缩小搜索范围:

  • 如果 arr[mid] > arr[mid - 1],说明处于上升趋势,峰顶在右侧(包含 mid),令 left = mid。
  • 如果 arr[mid] < arr[mid - 1],说明处于下降趋势,峰顶在左侧(不包含 mid),令 right = mid - 1。

注意这里使用 left + (right - left + 1) / 2 向上取整,避免死循环。

代码实现
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;
    }
};

时间复杂度: O(log n),空间复杂度: O(1)。

文章配图 文章配图


022 寻找峰值

题目描述:

文章配图

峰值元素是指其值严格大于左右相邻值的元素。数组可能包含多个峰值,返回任何一个即可。假设 nums[-1] = nums[n] = -∞。

算法思路:二分查找

这道题的关键在于发现「二段性」。对于任意一个点 i,我们只需比较它与下一个点 i + 1 的关系:

  1. 若 arr[i] > arr[i + 1]:此时左侧区域一定存在峰值(因为最左侧是负无穷,且当前点在下降),结果在左侧。
  2. 若 arr[i] < arr[i + 1]:此时右侧区域一定存在峰值(因为最右侧是负无穷,且当前点在上升),结果在右侧。

这种性质允许我们像普通二分查找一样不断缩小区间,最终收敛到一个峰值。

代码实现

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]) {
                // 上升趋势,峰值在右侧
                left = mid + 1;
            } else {
                // 下降趋势或峰值,峰值在左侧(含 mid)
                right = mid;
            }
        }
        return left;
    }
};

时间复杂度: O(log n),空间复杂度: O(1)。

文章配图


总结

这两道题展示了二分查找在处理非严格有序数组时的灵活性。核心技巧在于识别数据的单调性变化趋势,并利用它来指导搜索方向。在实际解题中,建议先画图分析边界条件,再编写代码,这样能有效避免死循环或越界问题。

目录

  1. 二分查找实战:山脉数组的峰顶索引与寻找峰值
  2. 021 山脉数组的峰顶索引
  3. 思路一:暴力遍历
  4. 思路二:二分查找
  5. 核心逻辑
  6. 代码实现
  7. 022 寻找峰值
  8. 算法思路:二分查找
  9. 代码实现
  10. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Web3j 快速搭建 Java 区块链应用配置指南
  • C++ Lambda 表达式详解:语法、捕获与底层原理
  • GitHub Copilot 集成安全风险及防护实践
  • JavaScript Promise 完整指南
  • C++ STL 标准库常用算法详解
  • Web3 核心概念与比特币以太坊对比解析
  • PDF Arranger终极指南:快速掌握PDF页面重排的完整教程
  • 七款主流大模型英文降 AI 率效果横向测评
  • 前端如何设计可信的 AI 产品体验
  • 提升 AI 模型能力的 10 个必备技能指南
  • Codex 与 Copilot 简介
  • 华为 ICT 大赛 2024-2025 网络赛道考试分析
  • 低代码结合大模型:中小企业半天构建专属 SaaS 应用路径
  • Python 基于 Flask 的小区停车场管理系统设计与实现
  • GitHub Copilot 使用指南
  • 传统 RAG 与 Agentic RAG 对比分析
  • FAIR plus 机器人全产业链接会:2026 深圳展会前瞻
  • 大模型突破对话边界:天工 3.0 与 SkyMusic 评测
  • Python 零基础学习经验总结与入门技术指南
  • Neovim + LazyVim 现代化配置指南 (Linux)

相关免费在线工具

  • 加密/解密文本

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