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

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

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

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

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


🎬艾莉丝的简介:


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


目录

021  山脉数组的峰顶索引

1.1  思路一:暴力解法

1.1.1  算法思路

1.1.2  算法实现

1.2  思路二:二分查找

1.2.1  算法思路

1.2.2  算法实现

1.3  博主手记

022  寻找峰值

2.1  算法思路:二分查找

2.1.1  算法思路

2.2  算法实现

2.3  博主手记

结尾



021  山脉数组的峰顶索引

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

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

题目描述:

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)。

1.3  博主手记

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


022  寻找峰值

力扣链接:162. 寻找峰值

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

题目描述:

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)。

2.3  博主手记

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


结尾

往期回顾:

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

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

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

૮₍ ˶ ˊ ᴥ ˋ˶₎ა


Read more

Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12)

Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12)

Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12) 本文整理收集了各版本 macOS 系统对应的 Docker Desktop 历史版本下载链接,方便需要特定版本的用户下载使用。 各 macOS 版本对应的 Docker Desktop 最终支持版本 🍎 macOS Catalina (10.15) 最后一个支持版本 版本号:v4.15.0 下载链接: * Intel 芯片:https://desktop.docker.com/mac/main/amd64/93002/Docker.dmg 🍎 macOS Big Sur (11.x)

By Ne0inhk
Flutter 三方库 klutter 的鸿蒙化适配指南 - 掌握 Kotlin Multiplatform (KMP) 互操作技术、助力鸿蒙应用构建极致复用且高性能的跨端业务逻辑共享体系

Flutter 三方库 klutter 的鸿蒙化适配指南 - 掌握 Kotlin Multiplatform (KMP) 互操作技术、助力鸿蒙应用构建极致复用且高性能的跨端业务逻辑共享体系

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 klutter 的鸿蒙化适配指南 - 掌握 Kotlin Multiplatform (KMP) 互操作技术、助力鸿蒙应用构建极致复用且高性能的跨端业务逻辑共享体系 前言 在 OpenHarmony 鸿蒙应用全场景覆盖的演进旅程中,开发者往往面临着“如何在保障 UI 高一致性的同时,最大化复用核心业务逻辑”的命题。特别是对于那些已经积累了大量成熟 Kotlin 代码的团队,如何让这些逻辑在鸿蒙端“无感”运行?klutter 作为一个专注于“Flutter 与 Kotlin Multiplatform 胶水层”的互操作框架,旨在为鸿蒙开发者提供一套标准的、类型安全的跨端逻辑桥接方案。本文将详述其在鸿蒙端的实战技法。 一、原原理分析 / 概念介绍 1.1 基础原理 klutter

By Ne0inhk

Flutter 三方库 performance_timer 的鸿蒙化适配指南 - 实现毫秒级性能剖析、支持嵌套计时与自动化性能报告输出

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 performance_timer 的鸿蒙化适配指南 - 实现毫秒级性能剖析、支持嵌套计时与自动化性能报告输出 前言 在 Flutter for OpenHarmony 的高性能调优过程中,准确识别应用中的卡顿点和耗时逻辑(Hotspots)是至关重要的。虽然可以使用鸿蒙的调试工具,但在代码层面实现轻量级的自动化性能监控往往更高效。performance_timer 是一个专为颗粒化性能评估设计的库,它能以极简洁的代码实现对业务链路的精准计时。本文将带领大家在鸿蒙端实战性能剖析。 一、原理解析 / 概念介绍 1.1 基础原理 performance_timer 封装了 Dart 的 Stopwatch,并引入了计分(Lap)和分组概念。它通过记录执行前后的纳秒级时间戳,计算差值并进行结构化汇总。 监控引擎 高精度时钟 API 时间差计算

By Ne0inhk
Flutter 组件 hydrated_mobx 的适配 鸿蒙Harmony 实战 - 驾驭自动化状态持久化、实现鸿蒙端 UI 状态在重启与多任务切换时的无缝恢复方案

Flutter 组件 hydrated_mobx 的适配 鸿蒙Harmony 实战 - 驾驭自动化状态持久化、实现鸿蒙端 UI 状态在重启与多任务切换时的无缝恢复方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 hydrated_mobx 的适配 鸿蒙Harmony 实战 - 驾驭自动化状态持久化、实现鸿蒙端 UI 状态在重启与多任务切换时的无缝恢复方案 前言 在鸿蒙(OpenHarmony)生态的深度体验中,用户对“断点续作”有着天然的期待。想象一下,用户正在你的鸿蒙平板 App 上填写一份复杂的表单,或者正在调整一个精密的编辑器参数,此时突然接到了一个紧急的鸿蒙系统推送流转,导致 App 被切入后台甚至因为内存压力被系统回收。 当用户再次点击图标回到 App 时,看到的是冷冰冰的初始化界面,还是瞬间恢复到上一次操作的完美现场? hydrated_mobx 为 Flutter 开发者提供了一套近乎魔法的状态持久化方案。它是对经典 MobX 的强力增强,通过简单的注解或扩展,就能让你的 Store 自动具备“

By Ne0inhk