《算法题讲解指南:优选算法-二分查找》--21.山峰数组的的峰顶索引,22.寻找峰值

《算法题讲解指南:优选算法-二分查找》--21.山峰数组的的峰顶索引,22.寻找峰值

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》

《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--从优选到贪心

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

21. 山峰数组的的峰顶索引

题目链接:

题目描述:

题目示例:

解法(二分查找):

算法思路:

C++算法代码:

算法总结及流程解析:

22. 寻找峰值

题目链接:

题目描述:

题目示例:

解法(二分查找):

算法思路:

C++算法代码:

算法总结及流程解析:

结束语


21. 山峰数组的的峰顶索引

题目链接:

852. 山脉数组的峰顶索引 - 力扣(LeetCode)

题目描述:

题目示例:

解法(二分查找):

算法思路:

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

  • 峰顶数据特点:arr[ i ]>arr[ i - 1 ] && arr[ i ]>arr[ i + 1 ]
  • 峰顶左边的数据特点:arr[ i ] > arr[ i - 1 ] && arr[ i ] < arr[ i + 1 ],也就是呈上升趋势
  • 峰顶右边数据的特点:arr[ i ] < arr[ i - 1 ] && arr[ i ] > arr[ i + 1 ],也就是呈下降趋势

      因此,我们可以分为以下两种情况:

  • 如果 mid 位置的值小于 mid-1 位置的值 left=mid;
  • 如果 mid 位置的值大于 mid-1 位置的值 right=mid-1;

C++算法代码:

class Solution { public: int peakIndexInMountainArray(vector<int>& arr) { //区间划分:[ 小于峰值 ], [ 大于等于峰值 ](相当于查找左端点) // int left = 0; int right = arr.size(); // while(left < right) // { // int mid = left + (right - left) / 2; // //对于偶数而言mid始终是在左边,所以判断条件是arr[mid] < arr[mid + 1] // if(arr[mid] < arr[mid + 1]) // { // left = mid + 1; // } // else // { // right = mid; // } // } // return left; //区间划分:[ 小于等于峰值 ], [ 大于峰值 ](相当于查找右端点) int left = 0; int right = arr.size(); while(left < right) { int mid = left + (right - left + 1) / 2; //对于偶数而言mid始终是在右边,所以判断条件是arr[mid - 1] < arr[mid] if(arr[mid - 1] < arr[mid]) { left = mid; } else { right = mid - 1; } } return left; } };

算法总结及流程解析:

22. 寻找峰值

题目链接:

162. 寻找峰值 - 力扣(LeetCode)

题目描述:

题目示例:

解法(二分查找):

算法思路:

      寻找二段性:任取一个点 i,与下一个点 i+1,会有如下两种情况:

  • arr[ i ] > arr[ i + 1 ]:此时【左侧区域】一定会存在山峰(因为最左侧是负无穷),那么我们就可以去左侧寻找结果
  • arr[ i ] < arr[ 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]) { left = mid + 1; } else { right = mid; } } return left; } };

算法总结及流程解析:

结束语

      到此,21.山峰数组的的峰顶索引,22.寻找峰值 这两道算法题就讲解完了。以题带点,详细分析了山峰数组的特性:峰顶同时大于左右相邻值,左侧呈上升趋势,右侧呈下降趋势。解题时抓住"二段性"特征,通过比较中间值与相邻元素的关系,逐步缩小搜索范围。希望大家能有所收获!

Read more

HarmonyOS6 底部导航栏组件 rc_concave_tabbar 使用指南

HarmonyOS6 底部导航栏组件 rc_concave_tabbar 使用指南

文章目录 * 前言 * 组件特性 * 适用场景 * 使用说明 * 安装组件 * 安装步骤 * 步骤一:引入相关依赖 * 步骤二:创建菜单数据 * 步骤三:使用导航组件 * 运行效果 * 参数介绍 * TabsConcaveCircle 组件参数 * TabMenusInterfaceIRequired 菜单项配置 * 进阶使用 * 自定义单个菜单项颜色 * 调整动画速度 * 自定义高度和颜色 * 注意事项 * 总结 前言 rc_concave_tabbar 是一个功能强大、样式精美的 HarmonyOS 底部导航栏组件库,提供凹陷圆形动画效果样式,适用于多种场景。本篇将介绍 rc_concave_tabbar 的使用方法以及其相关的设计理念。 组件特性 * 流畅动画:支持流畅的凹陷圆形切换动画效果 * 高度定制:支持自定义背景色、字体颜色、高度等多种样式配置 * 灵活配置:支持全局配置和单项配置,满足不同场景需求

By Ne0inhk

微信小程序案例 - 自定义 tabBar

一、前言:为什么需要自定义 tabBar? 微信小程序原生 tabBar 虽然简单易用,但存在明显限制: * ❌ 不支持中间“+”号等凸起按钮 * ❌ 图标和文字样式无法高度自定义(如选中态动画) * ❌ 无法动态隐藏/显示 tabBar * ❌ 不能嵌入徽标(Badge)、红点等业务元素 解决方案:使用自定义 tabBar! 本文将带你从零实现一个支持中间凸起按钮、带动画、可扩展的自定义 tabBar,并封装为通用组件。 二、最终效果预览 ✅ 底部 5 个 tab(中间为“+”发布按钮) ✅ 点击 tab 平滑切换页面 ✅ 中间按钮跳转独立功能页(如发布内容) ✅ 支持徽标、选中高亮、图标切换 三、实现原理 由于小程序页面是全屏渲染,我们无法像 H5 那样用 fixed 布局直接覆盖原生

By Ne0inhk
【neo4j】安装使用教程

【neo4j】安装使用教程

一、安装 1.0 前置条件 安装配置好jdk17及以上 注意我使用的是neo4j 5.26.10版本,匹配java17刚好 Java Archive Downloads - Java SE 17.0.12 and earlier 无脑安装即可 配置以下环境变量 1.1 安装程序 Neo4j Deployment Center - Graph Database & Analytics 下载解压即可,Windows是绿色版本 1.2 配置环境 添加neo4j的地址 二、基本使用 2.1 开启、关闭和查看运行状态 进入安装目录的bin文件夹,cmd窗口输入 ./neo4j.

By Ne0inhk

Windows 10/11环境下USB-Blaster驱动安装详解

USB-Blaster驱动在Win10/Win11下的“玄学”安装?一文彻底讲透! 你有没有遇到过这样的场景: FPGA代码写完,板子上电正常,Quartus Prime也打开了——结果点“Program”时弹出红字警告:“ No hardware available ”。 设备管理器里多了一个黄色感叹号的“未知设备”,或者干脆显示“USB-Blaster [Invalid]”。 别急,这几乎每个用Altera(现Intel FPGA)开发的人都踩过的坑。问题不在你的代码,也不在硬件,而是在那个看似简单、实则暗藏玄机的 USB-Blaster 驱动安装 。 尤其是在 Windows 10 和 Windows 11 系统下,微软对驱动签名和内核安全越来越“较真”,传统的“插上去自动识别”早已成为过去式。今天我们就来把这件事从根儿上说清楚:为什么装不上?怎么才能稳稳地装上?以及那些官方文档不会告诉你的实战技巧。 不是所有“USB下载线”

By Ne0inhk