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

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

二分查找实战:山峰数组的峰顶索引与寻找峰值。通过两个经典 LeetCode 题目讲解二分查找在极值问题中的应用。针对山脉数组,利用上升下降趋势判断峰顶位置;针对寻找峰值问题,基于相邻元素大小关系锁定峰值所在半区。两者均将时间复杂度优化至 O(log n),代码采用 C++ 实现,重点解析了边界条件处理与 mid 取值技巧,帮助读者掌握二段性二分的解题套路。

PgDevote发布于 2026/3/22更新于 2026/8/2351 浏览
二分查找实战:山峰数组的峰顶索引与寻找峰值

二分查找专题

在算法面试中,二分查找不仅用于有序数组,更常用于解决具有单调性或二段性的问题。今天通过两道经典题目,深入理解如何利用二分法高效定位极值。

1. 山峰数组的峰顶索引

题目链接: 852. 山脉数组的峰顶索引 - LeetCode

题目描述: 给定一个长度为 n 的山脉数组 arr,满足存在某个索引 i (0 < i < n-1),使得数组先严格递增后严格递减。请找到这个峰顶索引 i。

解法思路: 暴力遍历虽然可行,但效率仅为 O(n)。利用山脉数组的单调性,我们可以将时间复杂度优化至 O(log n)。

观察峰顶位置及其两侧的数据特征:

  • 峰顶左侧:呈上升趋势,即 arr[i] > arr[i-1] 且 arr[i] < arr[i+1]
  • 峰顶右侧:呈下降趋势,即 arr[i] < arr[i-1] 且 arr[i] > arr[i+1]

基于此,我们在二分查找过程中比较中间元素 mid 与其前一个元素 mid-1 的关系:

  • 若 arr[mid] > arr[mid-1],说明当前处于上升阶段,峰顶在 mid 或其右侧,因此令 left = mid。
  • 若 arr[mid] < arr[mid-1],说明当前处于下降阶段,峰顶在 mid 左侧,因此令 right = mid - 1。

注意边界处理,由于题目保证是山脉数组,左右端点不可能是峰顶,搜索范围可设为 [1, size-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;
    }
};

2. 寻找峰值

题目链接: 162. 寻找峰值 - LeetCode

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

解法思路: 这道题同样可以利用二分查找,关键在于判断'二段性'。

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

  • 如果 nums[i] > nums[i+1],说明此处正在下降。由于最左侧可视作负无穷,那么左侧区域一定存在一个峰值(从负无穷上升到某点后下降)。此时去左侧寻找结果,令 right = i。
  • 如果 nums[i] < nums[i+1],说明此处正在上升。同理,右侧区域一定存在一个峰值(从某点下降到负无穷)。此时去右侧寻找结果,令 left = i + 1。

这种策略保证了每次迭代都能排除一半不可能的区间,最终收敛到峰值。

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

总结

这两道题展示了二分查找在处理非完全有序数据时的灵活性。核心在于识别局部单调性,从而确定搜索方向。在实际编码时,务必注意 mid 的计算方式以及边界条件的更新逻辑,防止死循环或越界。掌握这种'趋势判断'的二分思想,能帮助你解决更多变种的极值问题。

目录

  1. 二分查找专题
  2. 1. 山峰数组的峰顶索引
  3. 2. 寻找峰值
  4. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Java 对象赋值与 clone 方法:浅拷贝与深拷贝解析
  • IPTV 播放源检测指南:故障排查与智能监测开源方案
  • DiT(Diffusion Transformer)详解:架构与核心模块分析
  • 借助 Nano Banana Pro 绘制高质量科研插图的四步法与提示词模板
  • LLaMa-Factory应用到实战(二)
  • Linux TCP 服务器开发:从 Echo 到远程命令执行的并发与安全
  • LLaMA Factory 微调时报 disable multiprocessing 错误处理
  • Python 列表:从创建到切片的核心用法
  • Google Nano Banana Pro 模型免费使用指南与实测分析
  • F5 刷新时,浏览器前端究竟发生了什么?
  • Python 数据分析进阶:模型评估与图像处理实战
  • 2025 无人机四大顶会 16 篇精选论文解读
  • 五大 AI 工具一站式提效指南:豆包、即梦、剪映、飞书与扣子
  • 基于 Trae IDE 与 MCP Server 实现 Figma 设计稿转前端代码
  • 基于 AI 的骑手健康证自动生成系统技术方案
  • 数据结构:八种常见排序算法详解
  • 主流 AI 编程助手 Copilot 概览
  • 前端函数防抖详解:原理、手写与 Lodash 实战
  • 红黑树进阶:手撕 STL 源码实现 map 和 set
  • Flutter pathfinding 库的 OpenHarmony 适配实战

相关免费在线工具

  • 加密/解密文本

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