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

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

二分查找在峰值问题中应用广泛。针对山脉数组峰顶索引与寻找峰值两道题,核心在于利用数组局部单调性构建二段性。通过比较中间元素与相邻值大小,判断峰值位于左侧还是右侧,从而将搜索区间减半。C++ 实现需注意边界条件,如 left/right 初始值及 mid 计算方式,确保循环收敛。该方法时间复杂度为 O(log n),优于线性扫描。

板砖工程师发布于 2026/3/29更新于 2026/10/2395 浏览
二分查找实战:山峰数组峰顶索引与寻找峰值

前言

二分查找不仅适用于有序数组,在满足特定单调性的场景下同样高效。本文通过两道经典题目,探讨如何利用二分思想快速定位数组中的峰值。

21. 山峰数组的峰顶索引

题目描述: 给定一个长度为 n 的山脉数组 arr,其中存在唯一的峰顶索引 i,使得数组先严格递增后严格递减。即 arr[0] < arr[1] < ... < arr[i-1] < arr[i] > arr[i+1] > ... > arr[n-1]。请返回该峰顶索引。

算法思路: 这道题的关键在于识别'二段性'。虽然整个数组不是有序的,但相对于峰顶位置,它呈现出明显的两段特征:

  • 左侧区间 [0, peak] 是递增的,即 arr[mid] < arr[mid + 1]
  • 右侧区间 [peak, n-1] 是递减的,即 arr[mid] > arr[mid + 1]

利用这一特性,我们可以用二分查找来逼近峰顶。如果中间元素比右边元素大,说明处于下降段,峰顶在左侧(包含 mid);反之则处于上升段,峰顶在右侧(mid 右侧)。

注意边界处理,由于首尾不可能是峰顶,搜索范围可设为 [1, n-2]。

C++ 代码实现:

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 1;
        int 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;
    }
};

22. 寻找峰值

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

算法思路: 这道题比上一道更灵活,因为数组不一定呈山脉状,只要找到一个局部极大值即可。核心逻辑依然是利用'二段性': 任取一点 i,比较 nums[i] 和 nums[i+1]:

  • 若 nums[i] > nums[i+1],说明当前处于下降趋势,左侧一定存在峰值(因为最左端可视作负无穷),向左搜索。
  • 若 nums[i] < nums[i+1],说明当前处于上升趋势,右侧一定存在峰值,向右搜索。

这种策略能保证每次迭代都将搜索空间减半,时间复杂度为 O(log n)。

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

总结

这两道题展示了二分查找在非严格有序序列中的应用技巧。解题时不必拘泥于传统'找目标值'的思维,而是关注数据分布的单调性特征。通过比较中间值与邻居的关系,判断搜索方向,往往能化繁为简。在实际编码中,务必注意 mid 的计算方式及边界条件,避免死循环或越界。

目录

  1. 前言
  2. 21. 山峰数组的峰顶索引
  3. 22. 寻找峰值
  4. 总结

更多推荐文章

查看全部
  • 深入理解 llama.cpp:本地高效运行大语言模型
  • 2025 蓝桥杯网络安全 CTF 省赛真题详解 (Web/Misc/Crypto/Reverse)
  • C++ STL 常用容器详解:从 Vector 到 Map 实战指南
  • Python 二级考试基础操作题真题及参考代码汇总
  • 具身智能机器人运控通讯架构与实现指南
  • MCP 协议详解:与 Function Call 的区别及 Python 实战
  • LangChain 速成课程:构建基于 OpenAI LLM 的应用
  • OpenFang 深度体验:Rust 驱动的 Agent OS 本土落地实践
  • AI 应用开发的技术深度:超越 API 调用的工程实践
  • 2025 年 12 月 GitHub 十大热门开源项目
  • ASR 文本润色实战:基于 Llama-Factory 的微调方案
  • 人工智能模型评估:核心指标与方法体系
  • 企业级图像 AIGC 技术观察:Seedream 4.0 能力与应用场景分析
  • MySQL 权限管控与 C/C++ 客户端接入实战指南
  • C++ 四十年演进史与基础入门指南
  • 昇腾 Ops-CV 库:AIGC 多模态视觉生成加速方案
  • Ubuntu Server 24.04.3 LTS 安装指南
  • Python GUI 可视化设计:3 步完成专业界面开发
  • Python 核心语法详解:变量、流程控制与函数实战
  • AI 在前后端开发中的差异化落地指南:DAU 规模分层策略

相关免费在线工具

  • 加密/解密文本

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