一、前言
单调栈: 实际上也是栈,只是限制多了些,栈内元素是有序的。
单调栈可分为两种: 按照出栈的顺序决定,出栈顺序递减就是递减栈,出栈顺序递增就是递增栈。
- 单调递增栈: 只有比栈顶元素小的数才能入栈,否则需把栈顶先出栈。
- 单调递减栈: 只有比栈顶元素大的数才能入栈,否则需把栈顶先出栈。
# 单调递增栈:
# 栈内顺序:[3, 6, 10],出栈顺序为:[10, 6, 3]
# 单调递减栈:
# 栈内顺序:[10, 6, 3],出栈顺序为:[3, 6, 10]
总结下算法模板:
Stack<Integer> st = new Stack<>();
for (int r = 0; r <= n; ++r) {
// 比较栈顶元素
while (!st.empty() && h < heights[st.peek()]) {
// 出栈操作
}
st.push(r);
}
题目:
题目名 | 难易程度 | 思路 |
---|---|---|
496. 下一个更大元素 I | 简单 | |
739. 每日温度 | 中等 | |
316. 去除重复字母 | 中等 | |
901. 股票价格跨度 | 中等 | |
402. 移掉 K 位数字 | 中等 | |
581. 最短无序连续子数组 | 中等 | |
84. 柱状图中最大的矩形 | 困难 | |
42. 接雨水 | 困难 |
希望学习完这篇文章的你,再遇到这类型时,不再 “纯纯的”,而是觉得这题 “纯纯的”。
二、题目
(1)每日温度
题干分析
这个题目说的是,给你一个不为空的整数数组,数组中的元素表示每天的温度。你要计算出,对于每一天来说,温度升高需要等待的天数。如果对于某一天,未来不存在比它更高的温度,就把它对应的等待天数设置为 0。
比如说,给你的温度数组是:
1, 3, 1, 3, 2, 6
对于每一天来说,温度升高需要等待的天数是:
1, 4, 1, 2, 1, 0
思路解法
public class AlgoCasts {
// Time: O(n^2), Space: O(1)
public int[] dailyTemperaturesBruteForce(int[] T) {
int n = T.length;
int[] result = new int[n];
for (int i = 0; i < n; ++i) {
int j = i + 1;
while (j < n && T[j] <= T[i]) ++j;
if (j < n) result[i] = j - i;
// else result[i] = 0;
}
return result;
}
// Time: O(n), Space: O(n)
public int[] dailyTemperaturesStack(int[] T) {
int n = T.length;
int[] result = new int[n];
Stack<Integer> st = new Stack<>();
for (int i = 0; i < n; ++i) {
while (!st.empty() && T[st.peek()] < T[i]) {
int idx = st.pop();
result[idx] = i - idx;
}
st.push(i);
}
// while (!st.empty()) result[st.pop()] = 0;
return result;
}
// Time: O(n), Space: O(1)
public int[] dailyTemperaturesSkip(int[] T) {
int n = T.length;
int[] result = new int[n];
for (int i = n-2; i >= 0; --i) {
int j = i + 1;
while (T[j] <= T[i] && result[j] != 0) j += result[j];
if (T[j] > T[i]) result[i] = j - i;
// else result[i] = 0;
}
return result;
}
}