题目

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
数据范围
1 <= temperatures.length <= 105
30 <= temperatures[i] <= 100
测试用例
示例1
java
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例2
java
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例3
java
输入: temperatures = [30,60,90]
输出: [1,1,0]
题解1(博主题解,时空On)
java
import java.util.Deque;
import java.util.LinkedList;
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
// 创建一个单调栈,栈里的元素是整型数组 int[]
// 约定:int[0] 存温度值,int[1] 存该温度对应的下标(第几天)
Deque<int[]> deque = new LinkedList<>();
int len = temperatures.length;
// 结果数组,Java 默认会将里面所有元素初始化为 0
int res[] = new int[len];
// 循环开始前,先把第 0 天的数据打包压入栈中作为初始参照物
deque.push(new int[]{temperatures[0], 0});
// 因为第 0 天已经处理了,所以从第 1 天开始遍历
for (int i = 1; i < len; i++) {
// 当栈不为空,且【今天的温度】大于【栈顶存的过去的温度】时
// deque.peek()[0] 取出的就是栈顶那个 int[] 里的温度值
while (!deque.isEmpty() && temperatures[i] > deque.peek()[0]) {
// 获取栈顶元素(但不从栈里踢出去)
int t[] = deque.peek();
// t[1] 是过去那一天的下标,i 是今天的下标
// i - t[1] 就是这两天之间相隔的天数(也就是等待的天数)
res[t[1]] = i - t[1];
// 既然过去的那一天已经等到了更高的温度,就把它从栈里踢出去
deque.poll();
}
// 无论刚才有没有发生出栈操作,今天的数据都要打包进栈,等着未来的某一天来清算
deque.push(new int[]{temperatures[i], i});
}
// 遍历结束后,还在栈里的那些天数,意味着直到最后也没等到升温。
// 因为 res 数组默认全是 0,所以不需要管它们了,直接返回结果即可。
return res;
}
}
题解2(官解,时空同上)
java
import java.util.Deque;
import java.util.LinkedList;
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int length = temperatures.length;
int[] ans = new int[length];
// 创建一个单调栈,栈里【只存下标】(Integer 类型)
Deque<Integer> stack = new LinkedList<Integer>();
// 直接从第 0 天开始统一遍历,不需要在循环外提前处理第 0 天
for (int i = 0; i < length; i++) {
// 记录当天的温度
int temperature = temperatures[i];
// 当栈不为空,且【今天的温度】大于【栈顶下标所对应的历史温度】时
// temperatures[stack.peek()]:通过栈顶存的下标,去原数组里查到当时的温度
while (!stack.isEmpty() && temperature > temperatures[stack.peek()]) {
// pop() 方法会直接把栈顶的下标弹出来,并赋值给 prevIndex
// 这里一步到位,代替了你代码里的 peek() + poll() 两步操作
int prevIndex = stack.pop();
// 计算天数差,存入结果数组对应的位置
ans[prevIndex] = i - prevIndex;
}
// 今天还没找到更高的温度(或者已经把历史比它低的都清算了)
// 把今天的下标压入栈中,等待未来的某一天
stack.push(i);
}
return ans;
}
}
思路
这道题就是一道很简单的栈应用问题了,由于数据范围是10的五次方,用暴力必然TLE,所以我们需要考虑到使用栈一次处理,这道题的栈应用方法很简单没有什么说的,博主的方法栈存的是int数组,既存数据又存下标,其实没必要这样,直接只存下标就行了,就是官解的写法。