算法知识:判别是否需要使用单调栈,如果需要找到左边或者右边第一个比当前位置的数大或者小,则可以考虑使用单调栈
一、题目描述
给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:
输入: temperatures = [30,60,90]
输出: [1,1,0]
提示:
- 1 <= temperatures.length <= 105
- 30 <= temperatures[i] <= 100
二、思路讲解及代码实现
1、暴力
直接暴力的解法是超时的,于是用一个highTem数组来保存之后出现的较高温度是多少,能够减少向后遍历的查找次数。
(因为30<=temperatures[i]<=100,所以,可以用一个长度为71的数组来保存每个温度第一次出现的索引,也能够提升查找的效率。这里就不展开了。)
class Solution { public int[] dailyTemperatures(int[] temperatures) { int len = temperatures.length; int []answer = new int[len]; //所求结果 int []highTem = new int[len]; //highTem[i]表示第i天之后的更高温度是多少 for(int i=len-2; i>=0; i--) { if(answer[i+1] == 0) { //说明后面没有比temperatures[i+1]更高的温度 if(temperatures[i] >= temperatures[i+1]){ answer[i] = 0; } else { answer[i] = 1; highTem[i] = temperatures[i+1]; } } else { if(temperatures[i] < temperatures[i+1]) { answer[i] = 1; highTem[i] = temperatures[i+1]; } else { //去找高温 for(int j=i; j<len; j++) { if(highTem[j] > temperatures[i]) { answer[i] = j-i + answer[j]; highTem[i] = highTem[j]; break; } } } } } return answer; } }
2、单调栈
判别是否需要使用单调栈,如果需要找到左边或者右边第一个比当前位置的数大或者小,则可以考虑使用单调栈
维护一个栈,里面存放温度对应的索引(因为题目中求的是天数,不是温度)。如果栈为空或者栈顶温度大于当前温度,直接入栈;如果栈顶温度小于当前温度,说明当前温度即为栈顶温度要找的温度,出栈后继续比较栈顶温度。
class Solution { public int[] dailyTemperatures(int[] temperatures) { int len = temperatures.length; int []answer = new int[len]; //所求结果 Stack<Integer> stack = new Stack<>(); for(int i=0; i<len; i++) { //一直要把小于当前温度的都出栈,因为当前温度就是他们要找的温度 while(!stack.isEmpty() && temperatures[stack.peek()]<temperatures[i]) { int index = stack.pop(); answer[index] = i - index; } stack.add(i); } return answer; } }