【单调栈】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.hqwc.cn/news/291773.html

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

相关文章

CentOS 7 Tomcat服务的安装

前提 安装ava https://blog.csdn.net/qq_36940806/article/details/134945175?spm1001.2014.3001.5501 1. 下载 wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.84/bin/apache-tomcat-9.0.84.tar.gzps: 可选择自己需要的版本下载安装https://mirr…

论文中公式怎么降重 papergpt

大家好&#xff0c;今天来聊聊论文中公式怎么降重&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文中公式怎么降重 一、引言 在论文撰写过程中&#xff0c;公式是表达学…

Python算法例21 交错正负数

1. 问题描述 给出一个含有正整数和负整数的数组&#xff0c;将其重新排列成一个正负数交错的数组。 2. 问题示例 给出数组[-1&#xff0c;-2&#xff0c;-3&#xff0c;4&#xff0c;5&#xff0c;6]&#xff0c;重新排序之后&#xff0c;变成[-1&#xff0c;5&#xff0c;-…

Hive执行计划

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

【已解决】修改了网站的class样式name值,会影响SEO,搜索引擎抓取网站及排名吗?

问题&#xff1a; 修改了网站的class样式name值&#xff0c;会影响搜索引擎抓取网站及排名吗&#xff1f; 解答&#xff1a; 如果你仅仅修改了网站class样式的名称&#xff0c;而没有改变网站的结构和内容&#xff0c;那么搜索引擎通常不会因此而影响它对网站的抓取和排名。但…

「Verilog学习笔记」使用握手信号实现跨时钟域数据传输

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1ns module data_driver(input clk_a,input rst_n,input data_ack,output reg [3:0]data,output reg data_req);reg data_ack_reg_1, data_ack_reg_2 ; reg …

IntelliJ IDEA 2023.3 安装教程

引言 IntelliJ IDEA&#xff0c;通常简称为 IDEA&#xff0c;是由 JetBrains 开发的一款强大的集成开发环境&#xff0c;专为提升开发者的生产力而设计。它支持多种编程语言&#xff0c;包括 Java、Kotlin、Scala 和其他 JVM 语言&#xff0c;同时也为前端开发和移动应用开发提…

用户管理第2节课-idea 2023.2 后端一删除表,从零开始---【本人】

一、清空model文件夹下&#xff0c;所有文件 1.1.1效果如下&#xff1a; 1.1代码内容 package com.daisy.usercenter.model;import lombok.Data;Data public class User {private Long id;private String name;private Integer age;private String email; }二、清空mapper文件…

如何在 openKylin 上使用 ONLYOFFICE 桌面编辑器

文章作者&#xff1a;ajun ONLYOFFICE 桌面编辑器是一款基于依据 AGPL v.3 许可进行分发的开源办公套件。使用这款应用&#xff0c;您无需保持网络连接状态即可处理存储在计算机上的文档。 本文章基于中国根操作系统 openKylin 操作系统&#xff0c;使用软件商店快速安装与手…

阿里云林立翔:基于阿里云 GPU 的 AIGC 小规模训练优化方案

云布道师 本篇文章围绕生成式 AI 技术栈、生成式 AI 微调训练和性能分析、ECS GPU 实例为生成式 AI 提供算力保障、应用场景案例等相关话题展开。 生成式 AI 技术栈介绍 1、生成式 AI 爆发的历程 在 2022 年的下半年&#xff0c;业界迎来了生成式 AI 的全面爆发&#xff0c…

案例135:基于微信小程序的房屋租赁管理系统的设计与实现

文末获取源码 开发语言&#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 小程序…

Ubuntu 常用命令之 du 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 Ubuntu系统下的du命令是一个用来估计和显示文件和目录所占用的磁盘空间的命令。du是“disk usage”的缩写&#xff0c;这个命令可以帮助用户了解磁盘被哪些文件和目录使用。 du命令的常见参数有 -a&#xff1a;列出所有文件和目…