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

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

二分查找算法应用于山脉数组峰顶索引与寻找峰值问题。通过暴力遍历与二分查找思路对比,利用数组上升下降趋势构建二段性,确定搜索区间。核心在于根据 mid 与相邻元素关系调整左右边界,将时间复杂度从 O(n) 优化至 O(logn)。提供 C++ 代码实现及详细逻辑推导。

t ag发布于 2026/3/28更新于 2026/6/320 浏览
二分查找算法:山脉数组的峰顶索引与寻找峰值

021 山脉数组的峰顶索引

题目描述: 文章配图

1.1 思路一:暴力解法

1.1.1 算法思路

峰顶的特点:比两侧的元素都要大。 因此,我们可以遍历数组内的每一个元素,找到某一个元素比两边的元素大即可。

1.1.2 算法实现
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;
        }
        // 为了处理 oj 需要控制所有路径都有返回值
        return -1;
    }
};

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

文章配图

1.2 思路二:二分查找

1.2.1 算法思路

1、分析峰顶位置的数据特点,以及山峰两旁的数据的特点:

(1)峰顶数据特点:arr[i] > arr[i - 1] && arr[i] > arr[i + 1];

(2)峰顶左边的数据特点:arr[i] > arr[i - 1] && arr[i] < arr[i + 1],也就是呈现上升趋势;

(3)峰顶右边数据的特点:arr[i] < arr[i - 1] && arr[i] > arr[i + 1],也就是呈现下降趋势。

2、因此,根据 mid 位置的信息,我们可以分为下面三种情况:

(1)如果 mid 位置呈现上升趋势,说明我们接下来要在 [mid + 1, right] 区间继续搜索;

(2)如果 mid 位置呈现下降趋势,说明我们接下来要在 [left, mid - 1] 区间搜索;

(3)如果 mid 位置就是山峰,直接返回结果。

1.2.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(logn),空间复杂度:O(1)。

文章配图 文章配图

022 寻找峰值

题目描述: 文章配图

2.1 算法思路:二分查找

2.1.1 算法思路

寻找二段性——

任取一个点 i,与下一个点 i + 1,会有如下两种情况:

(1)arr[i] > arr[i + 1]:此时【左侧区域】一定会存在山峰(因为最左侧是负无穷),那么我们可以去左侧去寻找结果;

(2)arr[i] < arr[i + 1]:此时【右侧区域】一定会存在山峰(因为最右侧是负无穷),那么我们可以去右侧去寻找结果。

当我们找到【二段性】的时候,就可以尝试用【二分查找】算法来解决问题。

2.2 算法实现
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
                right = mid;
        }
        return left;
    }
};

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

文章配图

目录

  1. 021 山脉数组的峰顶索引
  2. 1.1 思路一:暴力解法
  3. 1.1.1 算法思路
  4. 1.1.2 算法实现
  5. 1.2 思路二:二分查找
  6. 1.2.1 算法思路
  7. 1.2.2 算法实现
  8. 022 寻找峰值
  9. 2.1 算法思路:二分查找
  10. 2.1.1 算法思路
  11. 2.2 算法实现
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • HiDream-I1 开源:消费级显卡运行 17B 文生图模型实战
  • MySQL 数据库基础与 Linux 环境安装指南
  • 宇树机器人 G1 二次开发:导航仿真与地图转换教程
  • Stable Diffusion 整合包实战:小白快速上手 AI 绘画指南
  • AI 应用开发不仅是调接口:从面试看技术深度与工程实践
  • Cloudflare + Ingress + 自签名证书实现域名代理与流量限制
  • 4G Cat.1 模组赋能 AI 教育机器人:政策与技术的融合机遇
  • Java RESTful 接口开发:核心详解与最佳实践
  • 基于 Rokid 灵珠平台构建旅游 AR 智能体
  • Linux 信号内核结构、保存与处理全链路剖析
  • Mac mini 部署 OpenClaw:接入国产大模型与飞书机器人
  • AI 变现核心逻辑:为何学完百种工具仍难盈利
  • 链式二叉树详解:递归遍历与核心接口实现
  • 基于 aivectormemory 实现 AI 长期记忆方案
  • Python 官方文档查阅与打包技术指南
  • IntelliJ IDEA 中修改 Git 提交用户名的方法
  • 基于 FPGA 的北斗导航自适应抗干扰算法设计与实现
  • Linux 下 OpenClaw 快速安装、初始化与 Web UI 配置指南
  • GitHub 多模态大模型项目复现流程
  • Java IO 流与文件操作实战指南

相关免费在线工具

  • 加密/解密文本

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