简介
- 单调栈即为有序栈,分为单调递增和单调递减。
- 最大好处是时间复杂度是线性的,每个元素遍历一次
实现伪代码
stack<int> st;
for (遍历这个数组)
{
if (栈空 || 栈顶元素大于等于当前比较元素)
{
入栈;
}
else
{
while (栈不为空 && 栈顶元素小于当前元素)
{
栈顶元素出栈;
更新结果;
}
当前数据入栈;
}
}
举例
84. 柱状图中最大的矩形
基本思路
- 遍历每一根柱子,矩形高为当前柱子的高,宽度为左右第一个高度小于当前柱子的柱子距离差。
- 记录每一个矩形大小,对比出最大值。
- 暴力算法时间复杂度O(N^2)
优化思路
- 暴力算法中使用双重循环分别遍历了当前柱子左侧与右侧的柱子,寻找第一个高度小于当前柱子的柱子(左边沿和右边沿)。
- 如果遍历每根柱子时记录下左侧比当前柱子小的柱子,则可以省去一个循环,这一步从O(N)变成O(1)。
- 使用单调栈,若当前的柱子高度大于等于栈顶柱子的高度,就直接将当前柱子入栈。若当前的柱子高度小于栈顶柱子的高度,则当前柱子为当前栈顶柱子A右边沿,A出栈,此后栈顶柱子为A的左边沿。
- 此时以栈顶柱子为高的,左右边沿柱子就确定了,可以计算面积。
- 在原数组左右各加入一个高度为0的柱子,避免无法让所有高度全出栈。
优化后代码
class Solution {
public int largestRectangleArea(int[] heights) {
int[] tmp = new int[heights.length + 2];
System.arraycopy(heights, 0, tmp, 1, heights.length);
int n = tmp.length;
Deque<Integer> stack = new ArrayDeque<>();
int res = 0;
for (int i = 0; i < n; i++) {
while(!stack.isEmpty() && tmp[i] < tmp[stack.peek()]) {
int h = tmp[stack.pop()];
res = Math.max(res, (i - stack.peek() -1) * h);
}
stack.push(i);
}
return res;
}
}
参考
- https://blog.csdn.net/lucky52529/article/details/89155694
- https://blog.csdn.net/Zolewit/article/details/88863970
标签:tmp,柱子,int,栈顶,当前,stack,单调 来源: https://www.cnblogs.com/zccfrancis/p/15965122.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。