【单调栈】LeetCode2334:元素值大于变化阈值的子数组

作者推荐

map|动态规划|单调栈|LeetCode975:奇偶跳

涉及知识点

单调栈

题目

给你一个整数数组 nums 和一个整数 threshold 。
找到长度为 k 的 nums 子数组,满足数组中 每个 元素都 大于 threshold / k 。
请你返回满足要求的 任意 子数组的 大小 。如果没有这样的子数组,返回 -1 。
子数组 是数组中一段连续非空的元素序列。
示例 1:
输入:nums = [1,3,4,3,1], threshold = 6
输出:3
解释:子数组 [3,4,3] 大小为 3 ,每个元素都大于 6 / 3 = 2 。
注意这是唯一合法的子数组。
示例 2:
输入:nums = [6,5,6,5,8], threshold = 7
输出:1
解释:子数组 [8] 大小为 1 ,且 8 > 7 / 1 = 7 。所以返回 1 。
注意子数组 [6,5] 大小为 2 ,每个元素都大于 7 / 2 = 3.5 。
类似的,子数组 [6,5,6] ,[6,5,6,5] ,[6,5,6,5,8] 都是符合条件的子数组。
所以返回 2, 3, 4 和 5 都可以。
提示:
1 <= nums.length <= 105
1 <= nums[i], threshold <= 109

枚举子数组的最小值

以nums[i]为最小值的左边界是从右向左第一个小于nums[i]的数,假定其下标为left。如果不存在,left为-1。
以nums[i]为最小值的右边界是从左向右第一个小于等于nums[i]的数,假定其下标为right。如果不存在,right为m_c。
则nums(left,right)是以nums[i]为最小值的最长子数组。显然,相同最小值,子数组越长越容易符合题目。只需验证最长子数组。

代码

核心代码

class Solution {
public:int validSubarraySize(vector<int>& nums, int threshold) {m_c = nums.size();vector<int> vLeft(m_c, -1), vRight(m_c, m_c);//vLeft[i] 从右向左第一个小于nums[i] ;vRight[i] 是第一个小于等于nums[i]。stack<int> sta;for (int i = 0; i < m_c; i++){while (sta.size() && (nums[sta.top()] >= nums[i])){vRight[sta.top()] = i;sta.pop();}if (sta.size()){vLeft[i] = sta.top();}sta.emplace(i);}for (int i = 0; i < m_c; i++){const int k = vRight[i] - vLeft[i] - 1;if ((k > 0) && (nums[i] > threshold / k)){return k;}}return -1;}int m_c;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{vector<int> nums;int threshold;{Solution slu;nums = { 1, 3, 4, 3, 1 }, threshold = 6;auto res = slu.validSubarraySize(nums, threshold);Assert(3, res);}{Solution slu;nums = { 6,5,6,5,8 }, threshold = 7;auto res = slu.validSubarraySize(nums, threshold);//Assert(1, res);}//CConsole::Out(res);
}

2023年3月版

bool Less(const std::pair<int, int>& p, int iData)
{
return p.first < iData;
}

class Solution {
public:
int validSubarraySize(vector& nums, int threshold) {
m_c = nums.size();
vector vLeft(m_c), vRight(m_c);
{
vector<pair<int, int>> vStack;
for (int i = 0; i < m_c; i++)
{
int iNum = std::lower_bound(vStack.begin(), vStack.end(), nums[i], Less) - vStack.begin();
if (0 == iNum)
{
vLeft[i] = -1;
}
else
{
vLeft[i] = vStack[iNum - 1].second;
}
while (vStack.size() && (nums[i] <= vStack.back().first))
{
vStack.pop_back();
}
vStack.emplace_back(nums[i], i);
}
}
{
vector<pair<int, int>> vStack;
for (int i = m_c - 1; i >= 0;i–)
{
int iNum = std::lower_bound(vStack.begin(), vStack.end(), nums[i]+1, Less) - vStack.begin();
if (0 == iNum)
{
vRight[i] = m_c;
}
else
{
vRight[i] = vStack[iNum - 1].second;
}
while (vStack.size() && (nums[i] <= vStack.back().first))
{
vStack.pop_back();
}
vStack.emplace_back(nums[i], i);
}
}
for (int i = 0; i < m_c; i++)
{
const int len = vRight[i] - vLeft[i] - 1;
if (nums[i] > threshold / len)
{
return len;
}
}
return -1;
}
int m_c;
};

2023年7月版

class Solution {
public:
int validSubarraySize(vector& nums, int threshold) {
m_c = nums.size();
vector vLeft(m_c), vRight(m_c);
{//计算左边的长度
stack<pair<int, int>> staValueIndex;
for (int i = 0; i < m_c; i++)
{
while (staValueIndex.size() && (staValueIndex.top().first >= nums[i]))
{
staValueIndex.pop();
}
vLeft[i] = staValueIndex.empty() ? i : (i - staValueIndex.top().second - 1);
staValueIndex.emplace(nums[i], i);
}
}
{//计算右边的长度
stack<pair<int, int>> staValueIndex;
for (int i = m_c-1 ; i >= 0 ; i-- )
{
while (staValueIndex.size() && (staValueIndex.top().first >= nums[i]))
{
staValueIndex.pop();
}
vRight[i] = staValueIndex.empty() ? m_c-1-i : ( staValueIndex.top().second - i - 1);
staValueIndex.emplace(nums[i], i);
}
}
int iRet = -1;
for (int i = 0; i < m_c; i++)
{
const int len = vLeft[i] + vRight[i]+1;
const int iNeedK = threshold / nums[i] + 1;

		if (len >= iNeedK){iRet = max(iRet, len);}}return iRet;
}
int m_c;

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法C++ 实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录Ubuntu20.04安装mujoco与安装mujoco_py并测试时提示Cython.Compiler.Errors.CompileError的解决方案

安装mujoco可以参考如下来链接&#xff1a; Ubuntu20.04安装mujoco&#xff1a; https://blog.csdn.net/qq_47997583/article/details/125400418 安装mujoco_py并测试时提示Cython.Compiler.Errors.CompileError&#xff1a; https://blog.csdn.net/m0_38122847/article/de…

Git 合并两个项目

前言 在 Git 中合并两个项目的代码需要一些步骤&#xff0c;尤其是如果这两个项目有不同的版本历史或者是独立的 Git 仓库。以下是一般的步骤&#xff1a; 克隆第一个项目&#xff1a; 在你的本地机器上克隆第一个项目的 Git 仓库。 git clone <URL_of_first_project>…

STM32CubeMX驱动ST7789

环境 1、单片机:STM32F103C8T6 2、开发平台&#xff1a;STM32CUBEMXkeil mdk 3、屏幕&#xff1a;ST7789&#xff0c;分辨率240*240 STM32配置 1、使用硬件SPI1驱动屏幕。配置如下&#xff1a; 2、屏幕控制引脚配置&#xff1a; 注意&#xff1a;只配置了DC,RST,CS这3个控…

使用 Taro 开发鸿蒙原生应用 —— 探秘适配鸿蒙 ArkTS 的工作原理

背景 在上一篇文章中&#xff0c;我们已经了解到华为即将发布的鸿蒙操作系统纯血版本——鸿蒙 Next&#xff0c;以及各个互联网厂商开展鸿蒙应用开发的消息。其中&#xff0c;Taro作为一个重要的前端开发框架&#xff0c;也积极适配鸿蒙的新一代语言框架 —— ArkTS。 本文将…

Hive执行计划

Hive提供了explain命令来展示一个查询的执行计划&#xff0c;这个执行计划对于我们了解底层原理&#xff0c;Hive 调优&#xff0c;排查数据倾斜等很有帮助。 使用语法如下&#xff1a; explain query;在 hive cli 中输入以下命令(hive 2.3.7)&#xff1a; explain select s…

【Java之数据结构与算法】

选择排序 package Code01;public class Code01_SelectionSort {public static void selectionSort(int[] arr) {if(arrnull||arr.length<2) {return;}for(int i0;i<arr.length;i) {int minIndex i;for(int ji1;j<arr.length;j) {minIndex arr[minIndex] > arr[j…

前后端实现解析用户请求ip地址

前言 在我的软件系统中,如果希望安全系数高一些的话,往往会有用户登陆行为表来记录用户登陆行为,保障用户账号安全,比如记录登陆地址,每次登陆时候读取数据最近几次登陆地点,进行账号安全验证 假如以下是我的用户登陆行为表 实现获取用户登陆地址的方法有很多种,比如通过前端整…

使用pytest+selenium+allure实现web页面自动化测试

测试文件 base 基本方法data 测试数据page web页面相关操作image 测试截图log 日志文件report 测试报告文件temp 临时文件tool 文件读取&#xff0c;发邮件文件TestCases 测试用例 在page下的__init__.py文件下配置 import os import time from selenium.webdriver.common.by…

python算法例22 下一个更大的数

1. 问题描述 给定一个环形数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&#xff09;&#xff0c;为每个元素打印下一个更大的元素。数字x的下一个更大的数&#xff0c;是遍历数组的过程中出现的第一个更大的数字&#xff0c;这意味着可以循环搜索以查找其下一…

伪协议和反序列化 [ZJCTF 2019]NiZhuanSiWei

打开题目 代码审计 第一层绕过 if(isset($text)&&(file_get_contents($text,r)"welcome to the zjctf")){ echo "<br><h1>".file_get_contents($text,r)."</h1></br>"; 要求我们get传参的text内容必须为w…

服务器的维护是如何操作的

服务器的维护是如何操作的 服务器可以说是不可或缺的资源&#xff0c;因为现在网络技术发达&#xff0c;我们的生活也都离不开网络的存在&#xff0c;我们想要获取的业务、资料等大多是通过网络进行&#xff0c;所以想要顺应潮流并获得发展&#xff0c;肯定需要服务器来将企业…

案例109:基于微信小程序的高校寻物平台

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【PostgreSQL】从零开始:(二十一)数据类型-布尔类型

布尔&#xff08;boolean&#xff09;类型 概述 布尔类型是一种数据类型&#xff0c;表示真&#xff08;true&#xff09;或假&#xff08;false&#xff09;的值。在计算机中&#xff0c;布尔类型主要用于判断条件的真假。布尔类型通常用于控制流程、条件判断和逻辑运算等方…

【WebRTC---源码篇】(二十五)音视频同步

RTC音视频同步场景: 音视频不在同一个时间点开始采集,如在视频先采集,音频后采集的情况下。我们不能贸然的认为音频起点来对齐视频起点,这种情况下,如何对音视频进行处理,就涉及到了音视频同步的知识。 解决思路: 通过现有条件,我们拥有RTP和SR,那么是不是可以用这两…

爬虫工作量由小到大的思维转变---<第二十章 Scrapy几个常规参数的调整策略心得>

前言: CONCURRENT_REQUESTS 32 # 设置请求并发数 DOWNLOAD_TIMEOUT 5 # 设置超时时间为5秒 RETRY_TIMES 2 # 设置你想要的重试次数 DOWNLOAD_DELAY 0.1 # 控制两个连续请求之间的延迟时间&#xff0c;设置为0.1表示每次请求之间的等待时间为0.1秒 CONCURRENT_REQUESTS_…

[XR806开发板试用] XR806——基于FreeRTOS下部署竞技机器人先进模糊控制器

前言 很荣幸参与到由“极术社区和全志在线联合组织”举办的XR806开发板试用活动。本人热衷于各种的开发板的开发&#xff0c;同时更愿意将其实现到具体项目中。秉承以上原则&#xff0c;发现大家的重心都放在开发中的环境构建过程&#xff0c;缺少了不少实际应用场景的运用&am…

【PostgreSQL】从零开始:(二十二)数据类型-枚举类型

概述 什么是枚举 枚举&#xff0c;又称为列举、举例或列举法&#xff0c;是一种通过逐一列举、点明或列举的方法来表达、阐述、说明或论述某个问题、观点或概念的过程。在数学、逻辑学和哲学中&#xff0c;枚举被用于证明、论证或说明某个命题、定理或理论的正确性或错误性。…

数据仓库-数据治理小厂实践

一、简介 数据治理贯穿数仓中数据的整个生命周期&#xff0c;从数据的产生、加载、清洗、计算&#xff0c;再到数据展示、应用&#xff0c;每个阶段都需要对数据进行治理&#xff0c;像有些比较大的企业都是有自己的数据治理平台或者会开发一些便捷的平台&#xff0c;对于没有平…

鸿蒙-HarmonyOS之初见

鸿蒙初识&#xff0c;此事能成&#xff01;&#xff01; 自己安装工具、配置环境并运行成功&#xff0c;流程记录。 一、首先官网下载开发工具 官网地址&#xff1a;https://developer.huawei.com/consumer/cn/ 当前最新的版本3.1 &#xff0c;windows和Mac&#xff0c;Mac又…

oppo 手机刷机流程

一、操作步骤&#xff1a; 一&#xff09;解锁BootLoader 以下是一种常见的方法&#xff0c;可以尝试获取OPPO手机的Root权限&#xff08;以参考信息为准&#xff0c;具体步骤可能因设备型号和系统版本而有所不同&#xff09;&#xff1a; 11). 解锁Bootloader&#xff1a;首…