题干:
请根据每日
气温
列表temperatures
,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用0
来代替。示例:
输入:temperatures
= [73,74,75,71,69,72,76,73] 输出: [1,1,4,2,1,1,0,0]
public class 每日温度 {
public static void main(String[] args) {
int[] temperatures = {30,40,50,60};
int[] ans = dailyTemperatures(temperatures);
for (int i : ans) {
System.out.print(i+" ");
}
}
//双循环暴力
/*public static int[] dailyTemperatures(int[] temperatures) {
int[] ans = new int[temperatures.length];
for(int i=0;i<temperatures.length;i++){
for(int j=i+1;j<temperatures.length;j++){
if(temperatures[j]>temperatures[i]) {
ans[i] = j-i;
break;
}
}
}
return ans;
}*/
//单调栈
public static int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] dist = new int[n];
Stack<Integer> index = new Stack<>();
for(int curIndex = 0 ;curIndex < n ; curIndex ++){
while(!index.isEmpty()&&temperatures[curIndex ]>temperatures[index.peek()]){
int preIndex = index.pop();
dist[preIndex] = curIndex -preIndex;
}
index.push(curIndex);
}
return dist;
}
}
首先想到的是双循环来暴力破解,但是时间复杂度太高。
后面学习到了可以用单调栈,即栈中存放当前遍历数组的下标,当栈为空时,直接把当前下标压栈,当栈不为空时,判断数组中当前下标的值temperatures[curIndex]与数组中下标为栈中最高点的值即temperatures[index.peek()]两者的大小,若前者大,则把栈中下标弹出记为preIndex,preIndex与curIndex的差值就是答案数组dist中的值。
若在遍历过程中,若持续遇到前者小于后者的情况,则持续将当前坐标压栈;若持续遇到前者大于后者的情况,则持续出栈。
ps:单调栈是说栈里面的元素从栈底到栈顶是单调递增或者单调递减的(类似于汉诺塔)