HOT100-4-每日温度
题目描述
给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
示例 1:
1 | 输入: temperatures = [73,74,75,71,69,72,76,73] |
具体见题目描述。
算法思路
这道题我写的自认为是$O(n)$的复杂度,但仔细分析后其实应该接近$O(n^2)$算法很简单:直接从当前温度开始找下一个温度高的天数即可,代码如下:
1 | class Solution { |
只有一层循环,但是我们操作两个指针i,j,所以最后是 $n^2$复杂度,毫不意外超时了(测试样例通过46/48),这要是蓝桥杯那种OJ说不定就算了。
算法优化
我考虑过算法优化,进行简单的剪枝,但是天色有点晚了,懒得动,大体思路是,用一个临时变量去记录此次寻找过程中的最大温度值 tmp_max
,当进行下一个位置的查找时,如果temperature[i+1] < tmp_max,那说明i, j 之间必有一值k满足 $temperature[k] > temperature[i], i < k <= j$ ,此时将j设置为i+1即可。否则我们不需要将j移回来,直接j设置为j+1开始遍历。或许可以过最后两个测试样例?但是我觉得提升不大,就没有尝试
借鉴思路
方法1-单调栈
单调栈这个思路真的很高效,我也感觉很容易想出来,但是真的就是差了一点,最后看的是官方题解。主要利用 递减栈 :栈里面只有递减元素。
算法流程如下:
- 第一个元素先入栈。从第二个元素开始执行下列操作:
- 如果当前数字大于栈顶,那么就直接取出栈顶,
ans[栈顶元素索引] = 当前元索引 - 栈顶元素索引
。 - 如果当前数字小于栈顶,那么将其入栈,作为新的栈顶,继续看新的元素,转2。
非常好理解,关键就是需要把元素的索引入栈,此时需要理解他们的数值对应关系,否则不好计算天数。复杂度为 O(n)
代码如下:
1 | class Solution { |
方法2-线性探测+倒序遍历
这道题目的标签是 单调栈 ,但是我看到一个比较容易理解的思路,使用了 线性探测 + 倒序遍历,其实我认为 倒序遍历 是这个题目的核心,因为整个题目就是需要向后检测,如果后面的子问题解决了,前面的问题解决起来比较轻松;线性探测 在这个题目里也比较聪明,先看代码:
1 | class Solution { |
我们记结果为 ans
,比较数的索引为 compare
,数组长度为 n
, 算法流程如下:
- 从倒数第二个数开始,先看其后面一个数,如果最后一个数大于倒数第二个数,那么很显然
ans[n - 2] = 1
,否则ans[n - 2] = 0
。 - 然后再去看第i个,先比较
temperature[i]和temperature[compare]
,如果 $temperature[i] < tempareture[compare]$ , 那么ans[i] = compare - i
,否则我们需要找到比tempareture[compare]
大的那个温度,很显然,这个温度是ans[compare]
,然后以这个ans[compare]
为比较值,转2继续比较。 - 最后肯定会因为while循环不满足,或者
res[compare] != 0
跳出这个循环,此时再比较temperature[i]和temperature[compare]
的结果确定这个ans[i]是compare-i还是0。