【优选算法必刷100题】第021~22题(二分查找算法):山脉数组的峰顶索引、寻找峰值

🔥艾莉丝努力练剑:个人主页

专栏传送门:《C语言》《数据结构与算法》C/C++干货分享&学习过程记录Linux操作系统编程详解笔试/面试常见算法:从基础到进阶

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬艾莉丝的简介:

************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************


🎬艾莉丝的算法专栏简介:

************************************************************************************************************************************************************************************************


目录

[021 山脉数组的峰顶索引](#021 山脉数组的峰顶索引)

[1.1 思路一:暴力解法](#1.1 思路一:暴力解法)

[1.1.1 算法思路](#1.1.1 算法思路)

[1.1.2 算法实现](#1.1.2 算法实现)

[1.2 思路二:二分查找](#1.2 思路二:二分查找)

[1.2.1 算法思路](#1.2.1 算法思路)

[1.2.2 算法实现](#1.2.2 算法实现)

[1.3 博主手记](#1.3 博主手记)

[022 寻找峰值](#022 寻找峰值)

[2.1 算法思路:二分查找](#2.1 算法思路:二分查找)

[2.1.1 算法思路](#2.1.1 算法思路)

[2.2 算法实现](#2.2 算法实现)

[2.3 博主手记](#2.3 博主手记)

结尾



021 山脉数组的峰顶索引

力扣链接:852. 山脉数组的峰顶索引

力扣题解链接:二分查找模版解决【山脉数组的峰顶索引】问题

题目描述:

1.1 思路一:暴力解法

1.1.1 算法思路

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

1.1.2 算法实现

代码演示如下------

cpp 复制代码
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 > arri - 1 && arr i > arri + 1];

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

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

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

(1)如果mid位置呈现上升趋势,说明我们接下来要在mid + 1,right区间继续搜索;
(2)如果mid位置呈现下降趋势,说明我们接下来要在left,mid - 1区间搜索;
(3)如果mid位置就是山峰,直接返回结果。

1.2.2 算法实现

代码演示如下------

cpp 复制代码
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)。

1.3 博主手记

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下手记的推导过程!最好做题的过程中自己也推导一遍!!!自己能够推导很重要!


022 寻找峰值

力扣链接:162. 寻找峰值

力扣题解链接:二分查找模版解决【寻找峰值】问题

题目描述:

2.1 算法思路:二分查找

2.1.1 算法思路

寻找二段性------

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

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

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

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

2.2 算法实现

代码演示如下------

cpp 复制代码
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)。

2.3 博主手记

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下手记的推导过程!最好做题的过程中自己也推导一遍!!!自己能够推导很重要!


结尾

往期回顾:

【优选算法必刷100题】第019~20题(二分查找算法):x 的平方根、搜索插入位置

结语: 都看到这里啦!请大佬不要忘记给博主来个"一键四连"哦!

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡

૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
huang57914739 分钟前
哈希算法的抗碰撞机制与安全性增强策略4
算法
林浩杨_1 小时前
SIGIR 2026|南京大学:Video-GAR:“通过生成 Query 来验证视频语义理解”的生成增强范式
论文阅读·人工智能·算法
Logic1011 小时前
C语言/数据结构位运算题解:异或XOR找出货船中的“独特载货量“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Elsa️7461 小时前
算法一周刷题总结
c++·算法
风合星语2 小时前
2026 机器人工程实例(五):让 Allegro Hand 在 MuJoCo 中完成接触抓取——抓取状态机、稳定抬升与受控释放
c++·python·机器人·仿真
小羊没烦恼!2 小时前
Memory 记忆设计讨论:Agent Memory 的数据模型可以怎么设计
java·开发语言·前端·c++·c#
小小程序猴12 小时前
深圳乘路资讯AI培训怎么样?课程靠谱吗?——一套课程可信度评估模型与实证分析
人工智能·算法
云上先途2 小时前
标签化服务适合哪些人?常见适用场景一次讲清
大数据·人工智能·算法·音视频
welfare9622 小时前
新号别搞:内存管理+模板初阶+STL简介
开发语言·c++
彧azz2 小时前
DFS与BFS:图遍历的两大核心算法
数据结构·学习·算法·深度优先·广度优先