DAY56:单调栈(二)下一个最大元素Ⅱ(环形数组处理思路)
文章目录
- 思路
- 写法1完整版
- 环形数组处理:i取模,遍历两遍
- 写法2完整版(环形数组推荐写法)
- debug测试:
- 逻辑运算符短路特性
- result数组在栈口取元素,是否会覆盖原有数值?
给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
示例 1:
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
示例 2:
输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]
提示:
1 <= nums.length <= 10^4-10^9 <= nums[i] <= 10^9
思路
本题属于循环数组问题,循环数组的处理,我们可以将两个nums数组拼接在一起,使用单调栈计算出每一个元素的下一个最大值,最后再把结果集即result数组resize到原数组大小即可。
但这种写法,修改了nums数组,而且最后还要把result数组resize回去。resize倒是不费时间,是O(1)的操作,但扩充nums数组相当于**多了一个O(n)**的操作。时间复杂度和空间复杂度都多了O(n)。
写法1完整版
// 版本一
class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {// 拼接一个新的numsvector<int> nums1(nums.begin(), nums.end());nums.insert(nums.end(), nums1.begin(), nums1.end());// 用新的nums大小来初始化resultvector<int> result(nums.size(), -1);if (nums.size() == 0) return result;// 开始单调栈stack<int> st;st.push(0);for (int i = 1; i < nums.size(); i++) { if (nums[i] < nums[st.top()]) st.push(i); else if (nums[i] == nums[st.top()]) st.push(i);else { while (!st.empty() && nums[i] > nums[st.top()]) {result[st.top()] = nums[i];st.pop();}st.push(i);}}// 最后再把结果集即result数组resize到原数组大小result.resize(nums.size() / 2);return result;}
};
环形数组处理:i取模,遍历两遍
对于这种循环数组, nums[nums.length - 1] 的下一个元素是 nums[0] ,需要遍历两遍,可以通过给i取模来解决!
我们首先扩充for循环遍历范围,令for遍历范围为[0,nums.size()*2-1](这样就遍历了2n个位置,遍历长度为2n),然后nums[i]改为nums[i%nums.size()]。
由于取模运算的特性, i初始值=0,i%nums.size()这个式子就是0--nums.size()-1循环取值。
- 当i初始值=0时,i%a的范围就是[0,a-1]!
因为 “求模” 运算的定义是 “求余数”。例如,当 7 除以 3,结果是 2 余 1,所以 7%3 的结果是 1。余数总是会小于除数的,所以 i%a 的结果将始终在 0 到 a-1 的范围内。
当 i 小于 a 时,i%a 的结果就是 i 自己;当 i 等于 a 时,i%a 的结果就是 0;当 i 大于 a 时,i%a 的结果就是 i-a 的值,直到这个值小于 a 为止。
遍历两遍的逻辑:
st.push(0);
for(int i=1;i<nums.size()*2;i++){if(nums[i%nums.size()]<=nums[st.top()]){st.push(i%nums.size());}else{while(nums[i%nums.size()]>nums[st.top()]&&!st.empty()){result[st.top()]=nums[i%nums.size()];st.pop();}st.push(nums[i%nums.size()]);}
}
写法2完整版(环形数组推荐写法)
- 重点在只用O(n)的时间复杂度和空间复杂度,完成遍历两遍数组
class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {stack<int>st;vector<int>result(nums.size(),-1);st.push(0);for(int i=1;i<nums.size()*2;i++){if(nums[i%nums.size()]<=nums[st.top()]){st.push(i%nums.size());}else{while(!st.empty()&&nums[i%nums.size()]>nums[st.top()]){result[st.top()]=nums[i%nums.size()];st.pop();}st.push(i%nums.size());}}return result;}
};
debug测试:
Line 171: Char 16: runtime error: reference binding to misaligned address 0xbebebebebebec0ba for type ‘int’, which requires 4 byte alignment (stl_deque.h) 0xbebebebebebec0ba: note: pointer points here

错误信息的意思是:运行时发生了一种未定义行为(Undefined Behavior)。具体来说,它在尝试对一个非对齐的地址(即不是4字节对齐的地址)进行整数的引用绑定,而这个操作是未定义的。该错误通常发生在空指针解引用,数组越界等情况。
这个错误出现在while循环这一句:
while(nums[i%nums.size()]>nums[st.top()]&&!st.empty())
while 循环如果这么写,那么,在检查栈是否为空之前,就已经尝试从栈顶取值,这是有问题的。当栈为空时,这将会导致未定义行为。
逻辑运算符短路特性
在C++中,逻辑AND操作符(&&)和逻辑OR操作符(||)都具有"短路"特性。
对于逻辑AND操作符,如果左边的操作数为假,那么不论右边的操作数是什么,整个表达式的结果都是假,因此不需要再计算右边的操作数。对于逻辑OR操作符,如果左边的操作数为真,那么不论右边的操作数是什么,整个表达式的结果都是真,因此不需要再计算右边的操作数。
因此,写单调栈的while循环,while条件里面包括了非空检查的时候,检查栈是否为空的语句必须放在前面,确定非空之后再尝试从栈顶取值!如果栈已经为空,那么!st.empty()的结果为假,右边的nums[i%nums.size()] > nums[st.top()]就不会被执行,从而避免对空栈进行操作的未定义行为。
result数组在栈口取元素,是否会覆盖原有数值?
答案是不会,因为result更新,是在发现了一个更大的数值,弹出的时候才会更新。
例如4 3 2这个例子,遍历两遍得到的是4 3 2 4 3 2,实际上后面那一组4 3 2的下标还是0 1 2,数组下标是没有扩展的。
但是遍历前面这一组4 3 2的时候,因为单调递减,所以全部入栈,栈内为2 3 4,遍历第二遍的时候遇到了4,栈内的2 3才被弹出,相当于result[1]和[2]此时更新。但是到了后面,3 2继续入栈,到最后2 3 4都留在了栈里面不会被弹出,因此也不可能导致result的值被覆盖!
再例如2 3 4的例子,遍历两遍得到2 3 4 2 3 4,第一遍的时候result就已经被填满,result[0]=3,result[1]=4,result[2]=-1。到了遍历第二遍的时候,此时栈内只有4,第二次遍历时,2入栈之后3再入栈,会弹出2,相当于result[0]仍然=3,同理result[1]仍然=4。即使是result的值覆盖了,结果依旧是不变的。
相关文章:
DAY56:单调栈(二)下一个最大元素Ⅱ(环形数组处理思路)
文章目录 思路写法1完整版环形数组处理:i取模,遍历两遍写法2完整版(环形数组推荐写法)debug测试:逻辑运算符短路特性result数组在栈口取元素,是否会覆盖原有数值? 给定一个循环数组 nums &#…...
kafka简介
kafka是什么? Kafka最初采用Scala语言开发的一个多分区、多副本并且基于ZooKeeper协调的分布式消息系统。目前Kafka已经定位为一个分布式流式处理平台,它的特性有高吞吐、可持久化、可水平扩展、支持流处理。 Apache Kafka是一个分布式的发布-订阅消息系…...
Kafka-消费者组消费流程
消费者向kafka集群发送消费请求,消费者客户端默认每次从kafka集群拉取50M数据,放到缓冲队列中,消费者从缓冲队列中每次拉取500条数据进行消费。...
FFmepg视频解码
1 前言 上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置,本文介绍最简单的FFmpeg视频解码示例。 2 视频解码过程 本文只讨论视频解码。 FFmpeg视频解码的过程比较简单,实际就4步: 打开媒体流获取…...
SpringCloud深入理解 | 生产者、消费者
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! SpringCloud Spring Cloud是一组用于构建分布式系统和微服务架构的开源框架和工具集合。它是在Spring生态系统的基础上构建的,旨在简化开发人员构建分布式…...
web题型
0X01 命令执行 漏洞原理 没有对用户输入的内容进行一定过滤直接传给shell_exec、system一类函数执行 看一个具体例子 cmd1|cmd2:无论cmd1是否执行成功,cmd2将被执行 cmd1;cmd2:无论cmd1是否执行成功,cmd2将被执行 cmd1&cmd2:无论cmd1是否执行成…...
使用curl和postman调用Azure OpenAI Restful API
使用curl在cmd中调用时,注意:json大括号内的每一个双引号前需要加上\ curl https://xxxopenai.openai.azure.com/openai/deployments/Your_deployid/chat/completions?api-version2023-05-15 -H "Content-Type: application/json" -H "…...
草莓叶病害数据集
1.草莓数据集有两个文件夹 训练集 健康文件夹(2819张) 草莓叶焦病害(3327张) 数据集可以关注最后一行 import numpy as np import os import matplotlib.pyplot as plt import cv2import warnings warnings.filterwarnings(igno…...
安卓音视频多对多级联转发渲染
最近利用自己以前学习和用到的音视频知识和工程技能做了一个android的sdk,实现了本地流媒体ipc rtsp 拉流以及自带mip usb等camera audio节点产生的流媒体通过webrtc sfu的方式进行多对多级联发布共享,网状结构,p2p组网,支持实时渲染以及转推rtmp&#x…...
2023年电赛---运动目标控制与自动追踪系统(E题)OpenART mini的代码移植到OpenMV
前言 (1)已经有不少同学根据我上一篇博客完成了前三问,恭喜恭喜。有很多同学卡在了第四问。 (2)我说了OpenART mini的代码是可行的。但是他们不会移植到OpenMV上,再次我讲移植之后的代码贴出来。 ÿ…...
SAP CAP篇十二:AppRouter 深入研究
本文目录 本系列文章理解现有程序app文件夹中的package.json理解approuter.js 修改现有程序修改package.json新建index.js在Approuter中显示额外的逻辑 添加一些额外的Logger对应代码及branch 本系列文章 SAP CAP篇一: 快速创建一个Service,基于Java的实现 SAP CAP…...
HDFS中数据迁移的使用场景和考量因素
HDFS中数据迁移的使用场景和考量因素 数据迁移使用场景数据迁移要素考量HDFS分布式拷贝工具-DistCpdistcp的优势性能命令 数据迁移使用场景 冷热集群数据同步、分类存储集群数据整体搬迁 当公司业务迅速的发展,导致的当前的服务器数量资源出现临时紧张的时候&#…...
科普 | 以太坊坎昆升级是什么
坎昆升级是什么 坎昆,是墨西哥一个著名的旅游城市,也是 Devcon 3 大会的举办地,按照以太坊升级命名的规律,以地名命名的升级,是针对以太坊执行层的升级。 之前同样命名的还有柏林升级、伦敦升级和这次的上海升级等。…...
C# 一些知识整理
C#反射和特性 反射Reflection Type 类型 Name NameSpace Assembly GetFields() GetProperties() GetMethods() 特性Attribute Obsolete弃用 Condit…...
SpringBoot复习:(15)Spring容器的核心方法refresh是在哪里被调用的?
在SpringApplication的run方法: refreshContext代码如下: 其中调用的refresh方法代码如下: 其中调用的refresh方法代码如下: 其中调用的fresh方法代码如下: 其中调用了super.refresh();而这个super.refresh()就是…...
Android安卓实战项目(5)---完整的健身APP基于安卓(源码在文末)可用于比赛项目或者作业参考中
Android安卓实战项目(5)—完整的健身APP(源码在文末🐕🐕🐕)可用于比赛项目 一.项目运行介绍 1.大致浏览 【bilibili视频】 https://www.bilibili.com/video/BV1uX4y177iR/? (1&…...
AutoSAR系列讲解(实践篇)11.2-存储处理与Block
目录 一、NVRAM Block NVRAM Block的类型 二、Fee Block 三、Ea Block 四、总结 同通信的PDU一样,存储功能也需要一些特殊的数据结构来存放和管理我们的NV数据(NV data) 一、NVRAM Block NVRAM Block的作用类似于IPDU,但它们两仅仅只是作用上相似,其功能实现是完全…...
K8s总结
K8s 是什么 Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的机制…...
3.playbook剧本二
文章目录 playbook二Roles模块roles模式安装LNMP创建nginxfiles目录handlers目录tasks目录templates目录vars目录 创建mysqltasks目录 创建phpfiles目录handlers目录tasks目录templates目录vars目录 创建LNMP剧本文件 playbook二 Roles模块 角色的作用:把playbook…...
【MySQL】视图与用户管理
【MySQL】视图 视图视图概念使用基表与视图的相互影响 用户管理新增用户删除修改密码 用户权限授予权限回收权限 视图 视图概念 视图就是一张虚拟表,其内容由查询定义。与真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化影响到基表&…...
智能体所有权与版权:AI Agent Harness Engineering 创造的作品归谁所有?
1. 标题选项 《AI Agent创作版权迷局破解:从Harness工程原理到所有权划分的完整指南》 《智能体作品归谁?AI Agent Harness Engineering场景下的版权规则深度拆解》 《告别权属纠纷:一文搞懂AI Agent生成内容的所有权、版权与收益分配规则》 《Harness工程视角下的AI创作权:…...
AI学习 - 大模型基础入门
AI学习 - 大模型基础入门 从零开始:Ollama 安装 → 本地模型运行 → Python 代码接入 → 理解核心概念 摘要 本文记录了在 Windows 上使用 Ollama 部署本地大模型、并通过 Python 代码接入调用的完整过程。内容涵盖:Ollama 安装与模型拉取、大模型基础概…...
PCL 基于强度的双边滤波【2026最新版】
目录 一、算法原理 1、计算步骤 2、算法源码 3、函数解析 4、参考文献 二、代码实现 三、结果展示 四、滤波后未发生变化的原因 五、解决办法 六、结果展示 七、相关链接 本文由CSDN点云侠原创,博客长期更新,本文最近一次更新时间为:2026年5月24日。 一、算法原理 1、计算…...
基于USB ACA模式实现安卓手机边玩边充的游戏手柄设计
1. 项目缘起:当手机性能过剩,却败给了触摸屏几年前,我清理手机游戏时,发现一个挺无奈的现象:性能足以媲美掌机的智能手机里,只剩下一些慢节奏的平台解谜或者数独。那些曾经让我在掌机上废寝忘食的赛车、动作…...
从安装到排错:手把手解决Linux服务器上Nacos启动失败的十大常见问题
从安装到排错:手把手解决Linux服务器上Nacos启动失败的十大常见问题当你在Linux服务器上部署Nacos时,是否遇到过启动失败却无从下手的困境?作为阿里巴巴开源的服务发现和配置管理平台,Nacos在微服务架构中扮演着重要角色。然而&am…...
高精度光照检测
光线检测仪,kotlin开发,调用手机感光模块检测室内外光照强度,用途多多,我主要用途孩子写作业检测光照保护视力。 食用方法∶打开即测,速度快,无广告,手机平视即可,无须直视光线。 买…...
基于Cynthion逆向USB协议,为DP100电源开发Linux控制软件
1. 项目概述:用Cynthion嗅探USB,为DP100电源打造Linux软件作为一名长期在Linux环境下折腾硬件和嵌入式开发的爱好者,我经常遇到一个头疼的问题:很多不错的桌面小设备,比如电源、示波器、逻辑分析仪,它们的官…...
收藏|2026年AI大模型就业爆发!岗位暴涨12倍、月薪6W+,小白零基础入门指南
2026年,AI已从“科技热点”彻底变为职场“刚需赛道”!脉脉高聘人才智库最新发布的《2026年1-2月中高端人才求职招聘洞察》,用硬核数据揭示行业真相:AI人才成招聘市场顶流,岗位量、薪资双双爆发式增长。尤其对零基础小白…...
UE5 Cesium项目里,如何把默认的飞行Pawn换成建筑漫游Pawn?保姆级迁移教程
UE5 Cesium项目建筑漫游Pawn迁移实战:从飞行模式到精细化浏览的完整指南当你在UE5中结合Cesium插件构建数字孪生场景时,DynamicPawn提供的全球飞行体验令人印象深刻。但当视角聚焦到单体建筑或室内空间时,那种仿佛操控无人机般的操作方式就显…...
NBT数据可视化编辑解决方案:NBTExplorer技术解析与应用指南
NBT数据可视化编辑解决方案:NBTExplorer技术解析与应用指南 【免费下载链接】NBTExplorer A graphical NBT editor for all Minecraft NBT data sources 项目地址: https://gitcode.com/gh_mirrors/nb/NBTExplorer NBTExplorer是一款面向Minecraft数据管理的…...
