当前位置: 首页 > news >正文

算法题之每日温度

每日温度

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]输出: [1,1,4,2,1,1,0,0]

示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

提示:

  • 1 <= temperatures.length <= 105
  • 30 <= temperatures[i] <= 100

解题思路一:反向遍历

一看到题目,要找到下一个更高的温度,首先马上想到可以反向遍历。因为倒序的时候, 可以保证,如果有比当前温度大的下一个温度,一定会在遍历过的元素里。最重要的是,我们需要记录下来已经遍历过的元素。

然后我们看数组的元素的规律,温度的范围在30到100之间 。所以,我们可以维护一个101长度的数组next,温度为30至100度,作为数组的下标,元素设置为数组temperatures的下标。

  • 维护的数组next,我们初始化元素值为Integer.MAX_VALUE
  • 反向遍历数组temperatures,设置当前温度的next元素值为数组temperatures的下标
  • 当前温度+1的位置开始,正向遍历数组next,找到元素值小于Integer.MAX_VALUE的值;这个值就是temperatures的下标,然后从这些元素值中找到最小下标的那个,即为最近的下一个更高的温度

具体代码如下所示:

class Solution {public int[] dailyTemperatures(int[] temperatures) {int [] ans = new int[temperatures.length];int [] next = new int[101];Arrays.fill(next, Integer.MAX_VALUE);for (int i = temperatures.length - 1; i >= 0; i--) {int temperature = temperatures[i];ans[i] = 0;next[temperature] = i;int nextTemperatureIndex = Integer.MAX_VALUE;for (int j = temperature + 1; j < 101; j++) {if (next[j] < nextTemperatureIndex) {                    nextTemperatureIndex = next[j];}}if (nextTemperatureIndex < Integer.MAX_VALUE) {ans[i] = nextTemperatureIndex - i;}}return ans;}
}

 时间复杂度

  • 时间复杂度:O(nm),其中n为数组temperatures的长度,m是数组next的长度。我们需要反向遍历一遍temperatures,并且遍历一遍数组next。
  • 空间复杂度:O(m),其中m 是数组next的长度。

 解题思路二:单调栈

在上面的方法中,我们是通过反向遍历数组temperatures,然后再在额外的数组next中找到最小下标的。那么我们可以换一种数据结构存储温度的下标,提高效率么?

首先,我们来看,如果正向地遍历数组temperatures

  1. 遍历第1个元素的时候,我们记录下来下标0
  2. 遍历第2个元素,我们比较第temperatures[0]和temperatures[1]
  3. 如果temperatures[1]比temperatures[0]大,那么答案ans[0]= 1 - 0 = 1,并且我们就不用记录下标0了,转而记录下标1
  4. 如果temperatures[0]比temperatures[1]大,那么不能确定答案,并且我们还要记录下标1,然后继续下后面遍历,如果能找到下标i(i > 1),依次和下标1、下标0的温度值比较
  5. 如果temperatures[i]比temperatures[1]大,ans[1] = i - 1,并且我们移除记录的下标1;然后和下标0比较,具体类似步骤3、4

按照上面的步骤操作,我们会发现,可以额外用一个栈来记录下标,并且记录的下标对应的温度值,从栈底到栈顶,是依次递减的。每次遍历发现,当前遍历的温度值大于栈内下标对应的温度值时,可以依次弹栈并记录结果。具体代码如下所示:

class Solution {public int[] dailyTemperatures(int[] temperatures) {int[] ans = new int[temperatures.length];Deque<Integer> stack = new LinkedList<Integer>();// Stack<Integer> stack = new Stack<>();for(int i = 0; i < temperatures.length; i++){while(stack.isEmpty() == false && temperatures[stack.peek()] < temperatures[i]){int pre = stack.pop();ans[pre] = i - pre;}stack.push(i);}return ans;}
}

 时间复杂度

  • 时间复杂度:O(n),我们需要正向遍历一遍temperatures,并且每个下标出入栈只有一次。
  • 空间复杂度:O(n),需要使用栈,最坏的情况下为n。

在实际使用中,发现使用Stack的效率较低,时间复杂度甚至高于反向遍历;当我们使用LinkedList的时候,效率是正常的。如果有兴趣,可以看看Stack和LinkedList的源码分别是怎么实现出栈入栈的。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Vue学习记录之三(ref全家桶)
  • 山东潍坊戴尔存储服务器维修 md3800f raid恢复
  • Spring:项目中的统一异常处理和自定义异常
  • MATLAB入门基础篇
  • 2024数学建模研赛华为杯选题建议详细思路代码文章A题B题C题D题E题F题研究生数模竞赛
  • 我的AI工具箱Tauri版-FasterWhisper音频转文本
  • 【毕业设计】基于 PHP 开发的社区交流系统
  • ubuntu 22.04 ~24.04 如何修改登录背景
  • golang学习笔记2-语法要求,注释与代码风格
  • 周边游小程序开发
  • 双击就可以打开vue项目,而不用npm run dev
  • Redis——redispluspls库通用命令以及String类型相关接口使用
  • 实用好软-----电脑端 全能音视频转换器 转换各种音视频格式
  • 打开C嘎嘎的大门:你好,C嘎嘎!(2)
  • 【Stm32】从零建立一个工程
  • 网络传输文件的问题
  • 分享的文章《人生如棋》
  • Android Volley源码解析
  • Angularjs之国际化
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • cookie和session
  • CSS魔法堂:Absolute Positioning就这个样
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • React Native移动开发实战-3-实现页面间的数据传递
  • SQLServer之创建显式事务
  • vue-cli在webpack的配置文件探究
  • 安卓应用性能调试和优化经验分享
  • 前端技术周刊 2019-02-11 Serverless
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 山寨一个 Promise
  • 深入浏览器事件循环的本质
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 一道面试题引发的“血案”
  • 怎么将电脑中的声音录制成WAV格式
  • 怎样选择前端框架
  • 智能合约Solidity教程-事件和日志(一)
  • ionic异常记录
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #include<初见C语言之指针(5)>
  • (+4)2.2UML建模图
  • (1)(1.9) MSP (version 4.2)
  • (52)只出现一次的数字III
  • (Forward) Music Player: From UI Proposal to Code
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (五)c52学习之旅-静态数码管
  • (转)大型网站架构演变和知识体系
  • (转)关于多人操作数据的处理策略
  • .gitignore文件忽略的内容不生效问题解决
  • .L0CK3D来袭:如何保护您的数据免受致命攻击