LeetCode72 - 每日温度
📝 题目描述
题目链接:每日温度
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例:
1 | 示例 1: |
提示:
1 <= temperatures.length <= 10^530 <= temperatures[i] <= 100
💡 解题思路
方法一:单调栈
维护一个存储温度下标的栈,从栈底到栈顶,所索引的温度是递减的。
倒序遍历温度数组(倒序入栈 相当于 正序出栈),对于每一个索引 i:
- 只要栈不空,那么查看
temperatures[stack.top()]与temperatures[i]的大小,如果栈顶索引代表的温度小于等于i所代表的温度,则出栈(这里可以理解为把数组的元素想象成并列站立的人,元素大小想象成人的身高。这些人站成一列,如何求元素「2」的下一个更大元素呢?很简单,从「2」的位置高度向后看,那么他后面可见的第一个人就是「2」的下一个更大元素,因为比「2」小的元素身高不够,「2」看不见,第一个露出来的就是答案,这里向后看也用到了倒序入栈相当于正序出栈的思想)。 - 然后开始存储答案,如果栈为空,说明后面没有更高的温度了,存入
0,否则存储栈顶元素 - i表示答案。 - 将
i入栈。
方法二:暴力法
对于温度列表中的每个元素 temperatures[i],需要找到最小的下标 j,使得 i < j 且 temperatures[i] < temperatures[j]。
由于温度范围在 [30, 100] 之内,因此可以维护一个数组 next 记录每个温度第一次出现的下标。数组 next 中的元素初始化为无穷大,在遍历温度列表的过程中更新 next 的值。
反向遍历温度列表。对于每个元素 temperatures[i],在数组 next 中找到从 temperatures[i] + 1 到 100 中每个温度第一次出现的下标,将其中的最小下标记为 warmerIndex,则 warmerIndex 为下一次温度比当天高的下标。如果 warmerIndex 不为无穷大,则 warmerIndex - i 即为下一次温度比当天高的等待天数,最后令 next[temperatures[i]] = i。
为什么上述做法可以保证正确呢?因为遍历温度列表的方向是反向,当遍历到元素 temperatures[i] 时,只有 temperatures[i] 后面的元素被访问过,即对于任意 t,当 next[t] 不为无穷大时,一定存在 j 使得 temperatures[j] == t 且 i < j。又由于遍历到温度列表中的每个元素时都会更新数组 next 中的对应温度的元素值,因此对于任意 t,当 next[t] 不为无穷大时,令 j = next[t],则 j 是满足 temperatures[j] == t 且 i < j 的最小下标。
🔧 代码实现
1、单调栈
1 | class Solution { |
2、暴力法
1 | class Solution { |
📊 复杂度分析
1、单调栈
- 时间复杂度:,其中 是温度列表的长度。正向遍历温度列表一遍,对于温度列表中的每个下标,最多有一次进栈和出栈的操作。
- 空间复杂度:,其中 是温度列表的长度。需要维护一个单调栈存储温度列表中的下标。
2、暴力法
- 时间复杂度:,其中 是温度列表的长度, 是数组
next的长度,在本题中温度不超过100,所以 的值为100。反向遍历温度列表一遍,对于温度列表中的每个值,都要遍历数组next一遍。 - 空间复杂度:,其中 是数组
next的长度。除了返回值以外,需要维护长度为 的数组next记录每个温度第一次出现的下标位置。
🎯 总结
- 核心思想:掌握单调栈的模板写法。