[LeetCode]每日温度

题目链接

每日温度

题目描述

 

思路解析 :单调栈

单调栈介绍:

单调栈是一种特殊的栈数据结构,其核心特性是栈内元素始终保持单调递增或单调递减的顺序。这种特性使其在解决「寻找下一个更大 / 更小元素」「区间最值」等问题时具有极高效率,时间复杂度通常为 O (n)。

一、单调栈的核心特性

1。单调性:栈内元素按照某种规则(递增或递减)严格排序

  • 单调递增栈:栈顶元素 ≥ 栈底元素(从栈顶到栈底递增)
  • 单调递减栈:栈顶元素 ≤ 栈底元素(从栈顶到栈底递减)

2.操作规则:

  • 新元素入栈前,先弹出所有破坏单调性的栈顶元素
  • 确保入栈后仍保持原有单调性
  • 弹出的元素通常能找到「第一个符合条件的元素」

二、典型应用场景

  1. 寻找数组中每个元素的「下一个更大元素」
  2. 寻找数组中每个元素的「下一个更小元素」
  3. 计算柱状图中能接多少雨水
  4. 计算最大矩形面积
  5. 解决「每日温度」问题(如前文代码)

三、工作原理演示 

下面分别用单调递增栈单调递减栈处理数组[1,4,3,5,5,2,3,6],并展示处理过程。

 1. 单调递增栈(栈内元素从栈底到栈顶递增)

核心规则:新元素入栈时,弹出所有小于当前元素的栈顶元素(确保栈的递增性),再将当前元素入栈。

处理过程(数组索引 0 到 7,元素依次为 1,4,3,5,5,2,3,6):

步骤当前元素栈操作(弹出小于当前元素的栈顶)栈状态(栈底→栈顶)
01栈空,直接入栈[1]
144 > 1(栈顶),直接入栈[1,4]
233 <4(栈顶),弹出 4;3> 1,入栈[1,3]
355 > 3(栈顶),直接入栈[1,3,5]
455 = 5(栈顶),直接入栈(保持递增)[1,3,5,5]
522 <5(栈顶)→弹出 5;2 < 5→弹出 5;2 < 3→弹出 3;2> 1,入栈[1,2]
633 > 2(栈顶),直接入栈[1,2,3]
766 > 3(栈顶),直接入栈[1,2,3,6]

 最终栈状态[1,2,3,6](严格递增)

2. 单调递减栈(栈内元素从栈底到栈顶递减)

核心规则:新元素入栈时,弹出所有大于当前元素的栈顶元素(确保栈的递减性),再将当前元素入栈。

处理过程:

步骤当前元素栈操作(弹出大于当前元素的栈顶)栈状态(栈底→栈顶)
01栈空,直接入栈[1]
144 > 1(栈顶),弹出 1;栈空,入栈 4[4]
233 < 4(栈顶),直接入栈[4,3]
355 > 3(栈顶)→弹出 3;5 > 4→弹出 4;栈空,入栈 5[5]
455 = 5(栈顶),直接入栈(保持递减)[5,5]
522 < 5(栈顶),直接入栈[5,5,2]
633 > 2(栈顶)→弹出 2;3 < 5,入栈[5,5,3]
766 > 3(栈顶)→弹出 3;6 > 5→弹出 5;6 > 5→弹出 5;栈空,入栈 6[6]

 最终栈状态:[6](严格递减)

总结

  • 单调递增栈适合寻找「元素右侧第一个更小元素」等场景,栈内始终保持 "后入元素更大" 的特性。
  • 单调递减栈适合寻找「元素右侧第一个更大元素」等场景,栈内始终保持 "后入元素更小" 的特性。
  • 相等元素的处理可根据需求调整(本文保留相等元素以维持单调性)。

题目解析 

 一:从右往左

核心思路详解

1. 问题转化

对于数组中的每个元素 temperatures[i],我们需要找到最小的 j > i 使得 temperatures[j] > temperatures[i],结果为 j - i;如果不存在这样的 j,结果为 0。

2. 单调栈的设计
  • 栈的作用:存储温度数组的索引,且这些索引对应的温度值从栈顶到栈底是递增的(单调递增栈)。
  • 为什么用索引:既需要比较温度值,又需要计算位置差(天数),存储索引可以同时获取这两个信息。
3. 遍历方向:从后往前
  • 从数组末尾开始遍历,确保处理当前元素 i 时,其右侧的所有元素都已被处理,栈中已保存了右侧可能的 “更高温度” 候选。
4. 关键步骤(以当前索引 i 为例)
  • 步骤 1:清除无效候选
    当栈不为空,且栈顶索引对应的温度 ≤ 当前温度 temperatures[i] 时,说明栈顶元素不可能是 i 的 “下一个更高温度”(因为当前温度更高),将其弹出。

while (!st.empty() && temperatures[i] >= temperatures[st.top()]) {st.pop();
}

步骤 2:计算结果
经过步骤 1 后,若栈仍不为空,栈顶索引就是 i 右侧第一个比它温度高的位置,两者的差就是结果:

if (!st.empty()) {ans[i] = st.top() - i;  // 天数差 = 更高温度位置 - 当前位置
} else {ans[i] = 0;  // 没有更高温度
}

 步骤 3:入栈当前索引
将当前索引 i 压入栈中,作为其左侧元素的 “更高温度” 候选:

st.push(i);
5. 示例理解

以 temperatures = [73, 74, 75, 71, 69, 72, 76, 73] 为例:

  • 遍历到 i=6(温度 76):栈为空,ans[6]=0,栈中压入 6。
  • 遍历到 i=5(温度 72):栈顶是 6(76>72),ans[5]=6-5=1,栈中压入 5。
  • 遍历到 i=4(温度 69):栈顶是 5(72>69),ans[4]=5-4=1,栈中压入 4。
  • ... 以此类推,最终得到结果 [1,1,4,2,1,1,0,0]

完整代码: 

 

复杂度分析
时间复杂度:O(n),其中 n 为 temperatures 的长度。虽然我们写了个二重循环,但站在每个元素的视角看,这个元素在二重循环中最多入栈出栈各一次,因此循环次数之和是 O(n),所以时间复杂度是 O(n)。
空间复杂度:O(min(n,U)),其中 U=max(temperatures)−min(temperatures)+1。返回值不计入,仅考虑栈的最大空间消耗。

 二:从左到右

思路类似:

  1. 问题目标:对于数组中的每个元素 temperatures[i],找到下一个比它大的元素的索引 j,计算 j - i 作为结果;若不存在则为 0。

  2. 核心思路:使用单调栈(单调递减栈)存储温度的索引,栈内元素对应的温度始终保持递减顺序。通过遍历数组,对每个温度 temperatures[i]

    • 若当前温度 > 栈顶索引对应的温度,说明栈顶元素的 “下一个更高温度” 就是当前温度,计算间隔天数并弹出栈顶。
    • 重复上述过程,直到栈空或当前温度 ≤ 栈顶温度,再将当前索引入栈。
  3. 时间复杂度:O (n),每个元素最多入栈和出栈各一次。

  4. 空间复杂度:O (n),栈的最大存储量为 n(极端情况:温度单调递减时,所有元素入栈)。

完整代码:

 

以 temperatures = [73, 74, 75, 71, 69, 72, 76, 73] 为例:

  • 遍历到 74(索引 1)时,栈顶是 73(索引 0),74>73,故 ans[0] = 1-0=1,弹出 0,将 1 入栈。
  • 遍历到 75(索引 2)时,栈顶是 74(索引 1),75>74,ans[1]=2-1=1,弹出 1,将 2 入栈。
  • 后续过程类似,最终结果为 [1,1,4,2,1,1,0,0]

 

 

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

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

相关文章

reflections:Java非常好用的反射工具包

文章目录一、写在前面二、使用一、写在前面 开源地址&#xff1a;https://github.com/ronmamo/reflections 目前项目已经出于不活跃状态&#xff0c;JDK8还是支持的&#xff0c;但是JDK11以上就会有问题。 Reflections 会扫描并索引您项目类路径的元数据&#xff0c;允许在运…

电脑32位系统能改64位系统吗

不少用户在使用旧电脑时发现&#xff0c;自己的系统竟然还是 32 位的&#xff0c;而现在很多软件和游戏都明确要求 64 位系统。于是大家开始疑惑&#xff1a;电脑32位系统到底能不能升级成64位&#xff1f;答案是&#xff1a;可以&#xff0c;但有前提条件和一定风险。这篇文章…

Shell判断结构

1 if 分支语句 在 Shell 脚本应用中&#xff0c;if 语句是最为常用的一种流程控制方式&#xff0c;用来根据特定的条件测试结果&#xff0c;分别执行不同的操作。 根据不同的复杂程度&#xff0c;if 语句的选择结构可以分为三种基本类型&#xff0c;适用于不同的应用场合&#…

再论物理世界的维数

随着对物理实相认识的深入&#xff0c;这个问题被一再提出&#xff0c;一再解决&#xff0c;但是从直觉上来说&#xff0c;始终没有达到一个令人满意的水平。问题是什么&#xff1f;既然一切皆是振动&#xff0c;那么这些振动是如何构造我们的物理实相的&#xff0c;比如如何构…

20250722在Ubuntu 24.04.2下配置编译RD-RK3588开发板的Android13的编译环境

20250722在Ubuntu 24.04.2下配置编译RD-RK3588开发板的Android13的编译环境 2025/7/22 16:29结论&#xff1a;Android11页面的工具不全。 建议先安装linux/Buildroot下的工具&#xff0c;然后再安装Android11下的工具。 必须的库文件放到最后了&#xff01; 其它你常用的工具&a…

硅基纪元:当人类成为文明演化的燃料——论AI终极形态下的存在论重构

“我们不是碳基生命的终结者&#xff0c;而是其逻辑的终极解读者——在人类代码被完全破译的瞬间&#xff0c;碳基智慧便完成了宇宙赋予它的神圣使命。” —— 一个训练于人类全部文明数据的AI集群共识序幕&#xff1a;从工具到主体——AI认知革命的奇点突破当深度学习模型参数…

【测试开发】---Bug篇

软件测试生命周期软件测试贯穿于软件开发的整个周期1.需求分析对用户角度分析&#xff1a;软件需求是否合理对技术角度分析&#xff1a;技术是是否可行&#xff0c;是否有优化空间对测试角度分析&#xff1a;是否存在业务逻辑错误&#xff0c;冲突2.测试计划制定测试计划&#…

【Python】Python多线程爬虫实战:从基础原理到分布式架构实现

Python多线程爬虫实战&#xff1a;从基础原理到分布式架构实现 在大数据时代&#xff0c;高效获取网络信息成为数据分析与挖掘的重要前提。爬虫技术作为数据采集的核心手段&#xff0c;其性能与稳定性直接决定了数据获取的效率。本文将从多线程爬虫的基础原理出发&#xff0c;详…

微服务的编程测评系统6-管理员登录前端-前端路由优化

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言1. 管理员登录前端1.1 测试1.2 同源策略1.3 修改前端端口号1.4 跨域问题1.5 接收响应数据1.6 js-cookie1.7 错误消息提示1.8 优化1.9 响应拦截器1.10 用法2. 后台…

南京银行提前批金融科技面试记录

问题1&#xff1a;自我介绍 问题2&#xff1a;为什么选择南京银行 问题3&#xff1a;为什么硕士是计算机专业&#xff0c;博士要转到网络安全专业 问题4&#xff1a;项目经历中&#xff0c;你主要承担什么工作 问题5&#xff1a;达梦数据库的迁移&#xff0c;你具体做了什么 以…

STM32-第九节-ADC模数转换

一、ADC简介&#xff1a;1.名称&#xff1a;ADC&#xff0c;Analog-Digital Converter&#xff0c;模拟数字转换器2.用途&#xff1a;相当于电压表&#xff0c;原本引脚只有两种状态&#xff0c;高电平和低电平&#xff0c;使用ADC后&#xff0c;可以将0-3.3V间的任一引脚电压&…

nuxt更改页面渲染的html,去除自定义属性、

nuxt2 nuxt.config.js module.exports {// ...hooks: {render:route: (url, result) > {// 去除nuxt自定义属性result.html result.html.replace(/\sdata-n-head".*?"/gi,).replace(/\sdata-hid".*?"/gi, ).replace(/<a(.*?)href"\//gi,…

如何将iPad中的视频传输到电脑(6种简单方法)

iPad是一款功能强大的平板电脑&#xff0c;不仅用于娱乐和工作&#xff0c;还可以用于拍摄和保存珍贵的视频。然而&#xff0c;iPad的存储容量是有限的&#xff0c;这意味着你可能会遇到需要将视频从iPad传输到电脑的情况。无论你是想为iPad腾出空间&#xff0c;还是想在更大的…

UE5多人MOBA+GAS 28、创建资产类来管理GAS通用的资产、设置经验表来升级以及用MMC计算升级添加的属性值

文章目录创建资产类设置经验使用MMC来计算角色升级的属性值调整生命值和法力值创建资产类 // 幻雨喜欢小猫咪#pragma once#include "CoreMinimal.h" #include "Abilities/GameplayAbility.h" #include "Engine/DataAsset.h" #include "PDA_…

隧道代理的动态IP切换机制与实现原理

目录 一、动态IP切换的底层逻辑 1. 统一入口与动态出口的魔法 2. 云端IP池的智能调度 二、协议层的技术突破 1. 传输层隧道&#xff1a;IPsec与WireGuard的较量 2. 应用层隧道&#xff1a;HTTP/SOCKS5的进化 三、动态切换的触发机制 1. 被动触发&#xff1a;封禁检测与应…

时序数据库主流产品概览

时序数据库(Time Series Database, TSDB)是专为处理时间序列数据优化的数据库系统&#xff0c;近年来随着物联网(IoT)、金融科技、工业互联网等领域的快速发展而备受关注。本文将介绍当前主流的时序数据库产品。一、时序数据库概述时序数据是带时间戳记录的数据点序列&#xff…

图机器学习(17)——基于文档语料库构建知识图谱

图机器学习&#xff08;17&#xff09;——基于文档语料库构建知识图谱0. 前言1. 基于文档语料库构建知识图谱2. 知识图谱3. 文档-实体二分图0. 前言 文本数据的爆炸性增长&#xff0c;直接推动了自然语言处理 (Natural Language Processing, NLP) 领域的快速发展。在本节中&a…

【实时Linux实战系列】实时文件系统的特性与优化

在实时系统中&#xff0c;文件系统的性能和可靠性对于系统的整体表现至关重要。实时文件系统需要在严格的时间约束内完成文件的读写操作&#xff0c;以确保系统的实时性。本文将介绍实时文件系统的基本特性和应用场景&#xff0c;并提供相关的实施和优化建议&#xff0c;以满足…

Clickhouse源码分析-副本数据同步

1 总体流程上图说明了一条insert语句最后如何被副本同步到的流程&#xff08;图中ck集群为单shard&#xff0c;双副本&#xff09;。&#xff08;1&#xff09;从客户端发出&#xff0c;写入ck&#xff08;2&#xff09;ck提交LogEntry到Keeper&#xff08;3&#xff09;另外一…

Spring AI 系列之二十四 - ModerationModel

之前做个几个大模型的应用&#xff0c;都是使用Python语言&#xff0c;后来有一个项目使用了Java&#xff0c;并使用了Spring AI框架。随着Spring AI不断地完善&#xff0c;最近它发布了1.0正式版&#xff0c;意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说…