概念:
维护栈中元素的单调性,单调增或者单调减。
栈的概念:
栈是一种后进先出的数据结构,类似于杯子,最后放进去的东西总是会先取出来。
什么时候用:
要寻找一个元素的右边或者左边第一个比自己大或者小的元素的位置。单调栈的本质是空间换时间,
如何用?
当要求数组的每个元素的下一个最大元素时,维护单调递减栈,每次遇到栈顶元素<新进栈元素时,栈顶元素出栈,如果出栈了新的栈顶还是小于新进栈元素,则一直循环出栈进栈,新元素进栈,此时出栈的元素的右边第一个最大元素为新进栈元素。如果新进栈元素<栈顶元素时,则直接进栈。例如有数组 [3,5,1,4,8,3]的对应元素的下一个最大元素为[5,8,4,8,-1,-1],-1表示没有。维护单调递减栈 s=[] ,首先3进栈,s=[3],然后新进栈元素为5,比栈顶元素大,5进栈,3出栈,此时s=[5],即3右边第一个比它大的元素为5,然后是1比栈顶5小直接进栈,s=[5,1];然后遇见4,此时1出栈,4进栈,即第一个比1大的元素是4 ,s=[5,4]。
总结:
找第一个/下一个最大元素,维护递减栈;找第一个/下一个最小元素,维护递增栈。
下面是一道简单的题,可以帮助理解
实例:
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] ans = new int[n];
Deque<Integer> st = new ArrayDeque<>();
//定义栈st;
for(int i = n-1; i >= 0;i--){
int t = temperatures[i];
while(!st.isEmpty() && t>= temperatures[st.peek()]){
st.pop();
}
if(!st.isEmpty()){
ans[i] = st.peek() - i;
}
st.push(i);
}
return ans;
}
}