问题背景
给定一个整数数组 t e m p e r a t u r e s temperatures temperatures,表示每天的温度,返回一个数组 a n s w e r answer answer,其中 a n s w e r [ i ] answer[i] answer[i] 是指对于第 i i i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 0 0 来代替。
数据约束
- 1 ≤ t e m p e r a t u r e s . l e n g t h ≤ 1 0 5 1 \le temperatures.length \le 10 ^ 5 1≤temperatures.length≤105
- 30 ≤ t e m p e r a t u r e s [ i ] ≤ 100 30 \le temperatures[i] \le 100 30≤temperatures[i]≤100
解题过程
单调栈模板题,可以大概地抽象为,为数组中每个位置上的元素找到之后第一个大于它的值,直接记住要比用的时候再推导更高效。
有两种思路,从右往左遍历,栈中记录的是所有的候选项,如果出现新加入的元素不小于栈顶的元素,那么栈中的元素应当按序出栈;从左往右遍历,栈中记录的是所有尚未确定结果的位置,如果刚刚访问到的元素满足题目条件,那么记录结果,将栈顶元素出栈,将新的元素入栈。
具体实现
从右往左
java
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
// 队列和栈都是用双端队列来模拟
Deque<Integer> stack = new ArrayDeque<>();
for(int i = n - 1; i >= 0; i--) {
int cur = temperatures[i];
// 如果栈非空且当前元素大于栈顶元素,那么栈顶元素依次出栈
while(!stack.isEmpty() && cur >= temperatures[stack.peek()]) {
stack.pop();
}
if(!stack.isEmpty()) {
res[i] = stack.peek() - i;
}
// 栈中记录的是元素的下标
stack.push(i);
}
return res;
}
}
从左往右
java
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
// 队列和栈都是用双端队列来模拟
Deque<Integer> stack = new ArrayDeque<>();
for(int i = 0; i < n; i++) {
int cur = temperatures[i];
// 如果栈非空且当前元素符合大于栈顶元素这个条件,那么记录结果
while(!stack.isEmpty() && cur > temperatures[stack.peek()]) {
int top = stack.pop();
res[top] = i - top;
}
// 栈中记录的是下标
stack.push(i);
}
return res;
}
}