LeetCode 739:每日温度 Daily Temperatures
题目:
根据每日 气温
列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0
来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
,你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]
。
Given a list of daily temperatures T
, return a list such that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put 0
instead.
For example, given the list of temperatures T = [73, 74, 75, 71, 69, 72, 76, 73]
, your output should be [1, 1, 4, 2, 1, 1, 0, 0]
.
提示:气温
列表长度的范围是 [1, 30000]
。每个气温的值的均为华氏度,都是在 [30, 100]
范围内的整数。
Note: The length of temperatures
will be in the range [1, 30000]
. Each temperature will be an integer in the range [30, 100]
.
解题思路:
最容易想到和理解的就是暴力穷举,两个指针,一个指针指向当前温度,第二指针向后遍历找到最近一个比当前温度高的温度,记录两个指针的索引差即可。可以说效率非常低了。
另一种方法是借助栈倒序遍历原数组,存入较高的温度的索引,也很容易理解,时间复杂度为 O(n)。其实现逻辑为:
原数组:[73, 74, 75, 71, 69, 72, 76, 73],指针 i 从末尾向前遍历,返回数组res=[0,0,0,0,0,0,0]
第一次遍历: i = 7, T[i] = 73, stack = []
栈为空,res[7] = 0 ,73所在索引7入栈。stack = [7]
第二次遍历: i = 6, T[i] = 76, stack = [7]
栈顶对应索引7的温度T[7]=76,76>73,索引7出栈,此时栈为空,res[6] = 0。索引6入栈,stack = [6]
第三次遍历: i = 5, T[i] = 72, stack = [6]
栈顶对应索引6的温度T[6]=76,72<76,满足要求,当前索引5入栈。res[5] = 栈顶索引6 - 当前索引5 = 1, stack = [6,5]
第四次遍历: i = 4, T[i] = 69, stack = [6,5]
栈顶对应索引5的温度T[5]=72,69<72,满足要求,当前索引4入栈。res[4] = 栈顶索引5-当前索引4=1, stack = [6,5,4]
第五次遍历: i = 3, T[i] = 71, stack = [6,5,4]
栈顶对应索引的温度T[4]=69,71>69,栈顶元素出栈。stack = [6,5]
栈顶对应索引的温度T[5]=72,满足要求,当前索引3入栈。res[3] = 栈顶索引5-当前索引3=2, stack = [6,5,3]
第六次遍历: i = 2, T[i] = 75, stack = [6,5,3]
栈顶对应索引的温度T[3]=71,75>71,栈顶元素出栈。stack = [6,5]
栈顶对应索引的温度T[5]=72,75>72,栈顶元素出栈。stack = [6]
栈顶对应索引的温度T[6]=76,75<76,满足要求,当前索引2入栈。res[2] = 栈顶索引6-当前索引2=4, stack = [6,2]
第七次遍历: i = 1, T[i] = 74, stack = [6,2]
栈顶对应的温度T[2]=75,满足要求,当前索引1入栈。res[1] = 2-1=1, stack = [6,2,1]
第八次遍历: i = 0, T[i] = 73, stack = [6,2,1]
栈顶对应的温度T[1]=74,满足要求,当前索引0入栈。res[0] = 1-0=1, stack = [6,2,1,0]
遍历结束: res = [1,1,4,2,1,1,0,0]
这种方法下,栈存入索引对应的温度值始终按升序排列,当栈为空时,证明当前温度为 从该温度向后的所有温度里 最大的。
Java:
class Solution {
public int[] dailyTemperatures(int[] T) {
int len=T.length;
int[] res = new int[len];
Stack<Integer> stack = new Stack<>();//初始化栈
for (int i = len - 1; i >= 0; i--) {
while (!stack.isEmpty() && T[stack.peek()] <= T[i]) {
stack.pop();
}
if (stack.isEmpty()) res[i] = 0;
else res[i] = stack.peek() - i;
stack.push(i);
}
return res;
}
}
事实上就这道题而言这并不是一个好方法,因为提示已经明确规定了数据范围:
列表长度的范围是
[1, 30000]
。每个气温的值的均为华氏度,都是在[30, 100]
范围内的整数。
最多30000个数据量,数据非常小,入栈出栈,获取栈顶元素,判断栈是否空,在数据量很少的情况下这些函数反复调用,相对就占用了很多运行时间,其最终评测运行总时间为 109 ms。那么如何优化?
由于所有数据值的范围均在30到100之间,那么意为着按升序排列温度的栈的大小 最大不会超过71(因为从30到100只有71个元素)。那就可以不用栈这个需要反复调用函数的数据结构。直接用长度为71的数组顺序存入索引即可,定义一个指针,索引减一代替出栈,索引加一并赋值代替入栈,索引是否溢出代替判断栈是否为空,无虚函数调用。
优化后:
总运行时间为 4ms,降低了105毫秒
class Solution {
public int[] dailyTemperatures(int[] T) {
int len = T.length;
int[] res = new int[len], stack = new int[71];
int index = -1;
for (int i = len - 1; i >= 0; i--) {
while (index >= 0 && T[stack[index]] <= T[i]) {
index--;
}
if(index >= 0) res[i] = stack[index] - i;
stack[++index] = i;
}
return res;
}
}
Python:
python并没有队列、栈这种数据结构,因为数组就可以做到先进先出、后进先出等操作。
class Solution:
def dailyTemperatures(self, T: List[int]) -> List[int]:
tLen = len(T)
stack = []
res = [0] * tLen
for i in range(tLen - 1, -1, -1):
while stack and T[i] >= T[stack[-1]]:
stack.pop()
if stack: res[i] = stack[-1] - i
stack.append(i)
return res
欢迎关注微.信公.众号 一起学习:爱写Bug
LeetCode 739:每日温度 Daily Temperatures的更多相关文章
- Java实现 LeetCode 739 每日温度(暴力循环)
739. 每日温度 根据每日 气温 列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temper ...
- [Swift]LeetCode739. 每日温度 | Daily Temperatures
Given a list of daily temperatures T, return a list such that, for each day in the input, tells you ...
- [LeetCode]739. 每日温度(单调栈)
题目 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperatures ...
- LeetCode——739. 每日温度
根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperatures = ...
- LeetCode 739 每日温度
1.直接遍历 暴力求解 class Solution { public: vector<int>dailyTemperatures(vector<int>& T) { ...
- LeetCode:每日温度【739】
LeetCode:每日温度[739] 题目描述 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高的天数.如果之后都不会升高,请输入 0 来代替. 例如,给定一个列 ...
- [每日一题2020.06.13]leetcode #739 #15 单调栈 双指针查找
739 每日温度 ( 单调栈 ) 题目 : https://leetcode-cn.com/problems/daily-temperatures/ 题意 : 找到数组每一个元素之后第一个大于它的元素 ...
- 739. Daily Temperatures - LeetCode
Question 739. Daily Temperatures Solution 题目大意:比今天温度还要高还需要几天 思路:笨方法实现,每次遍历未来几天,比今天温度高,就坐标减 Java实现: p ...
- 【LeetCode】739. Daily Temperatures 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 倒序遍历 栈 日期 题目地址:https://leetcode ...
随机推荐
- leetcode一刷总结,明天二刷
1:基础的数据结构:图掌握极差,二叉树次之 2:常用的算法思想:dp,深度有先,广度优先等等. 3:优化以解决的题目,注意思想的总结 4:将约150道题都刷掉 5:优先解决设计算法思想的题目类别,其次 ...
- 记录使用echarts的graph类型绘制流程图全过程(二)- 多层关系和圆形图片的设置
本文主要记录在使用echarts的graph类型绘制流程图时候遇到的2个问题:对于圆形图片的剪切和多层关系的设置 图片的设置 如果用echarts默认的symbol参数来显示图片,会显示图片的原始状态 ...
- Ansible快速开始-指挥集群
Ansible可以集中地控制多个节点,批量地执行ssh命令.由于其使用ssh进行操作,因此远端服务器除了安装openssh-server(一般服务器已经内置)之外,不需要安装额外的软件,因此使用非常简 ...
- EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks
增加模型精度的方法有增加网络的深度,特征图的通道数以及分辨率(如下图a-d所示).这篇文章研究了模型缩放,发现仔细平衡网络的深度.宽度和分辨率可以获得更好的性能(下图e).在此基础上,提出了一种新的缩 ...
- vscode 通过ftp发布vue到azure服务器
参考资料:vs code配置ftp连接远程服务器实现代码文自动上传 1.在vscode应用商店中搜索拓展sftp插件,然后进行安装.2.安装完成后重启窗口,按快捷键Ctrl+shift+p,输入sft ...
- 利用Python突破验证码限制
一.实验说明 本实验将通过一个简单的例子来讲解破解验证码的原理,将学习和实践以下知识点: Python基本知识 PIL模块的使用 二.实验内容 安装 pillow(PIL)库: $ sudo apt- ...
- IOC控制反转、Unity简介
参考博客地址: Unity系列文章,推荐:http://www.cnblogs.com/qqlin/archive/2012/10/16/2717964.html https://www.cnblog ...
- SIP协议分析
- SIP流程 一个标准的SIP通话流程如下: 1. A向B发送一个INVITE消息,邀请B通话. 2.B振铃,向A回复一个RING消息,通知A振铃中,A等待. 3.B提机,向A发一个OK消息, 通 ...
- [20190920]完善vim调用sqlplus脚本.txt
[20190920]完善vim调用sqlplus脚本.txt --//以前写的http://blog.itpub.net/267265/viewspace-2140936/=>[20170617 ...
- Python—函数基础篇
https://www.cnblogs.com/littlefivebolg/p/9017449.html Python 解释器的内置函数 内置函数 作用 实例 abs() 返回数字的绝对值. abs ...