通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。
单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是只需要遍历一次。
1、单调栈里存放的元素是什么?
单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
2、单调栈里元素是递增呢? 还是递减呢?
注意一下顺序为 从栈头到栈底的顺序
构建一个从顶部到底部单调递增的栈。
1、新元素比栈顶小,直接插入
2、新元素比栈顶大,栈出栈,直至满足1
请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
- var dailyTemperatures = function (temperatures) {
- const n = temperatures.length;
- const res = Array(n).fill(0);
- const stack = []; // 递增栈:用于存储元素右面第一个比他大的元素下标
- stack.push(0);
- for(let i=1;i
- while(temperatures[i]>temperatures[stack[stack.length-1]]&&stack.length){
- let top=stack.pop()
- res[top]=(i-top)
- }
- stack.push(i)
- }
- return res
- };
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:

- 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
- 输出:6
- 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
- //单调栈 js数组作为栈
- var trap = function(height) {
- const len = height.length;
- if(len <= 2) return 0; // 可以不加
- const st = [];// 存着下标,计算的时候用下标对应的柱子高度
- st.push(0);
- let sum = 0;
- for(let i = 1; i < len; i++){
- if(height[i] < height[st[st.length - 1]]){ // 情况一
- st.push(i);
- }
- if (height[i] == height[st[st.length - 1]]) { // 情况二
- st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。
- st.push(i);
- } else { // 情况三
- while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while
- let mid = st[st.length - 1];
- st.pop();
- if (st.length !== 0) {
- let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid];
- let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度
- sum += h * w;
- }
- }
- st.push(i);
- }
- }
- return sum;
- };
思路
首先套路固定
1、定义stack
2、遍历元素
3、遇见不同单调性的元素考虑运用栈顶元素和栈顶距离最新端的长度
难点
单调性:考虑什么样的元素与结果有关,出现这样的元素时需要维护单调性。