今天的学习重点是
单调栈!!!
先浅浅讲一下 单调栈 的作用:
针对于某序列中每个元素,可以很快的找到接下来第一个比该元素大(或小)的元素位置。(同理:也可以找到左边的最近的第一个比该元素大(或小)的元素位置。)
经典代码片段:
for (int i = 1; i <= n; ++i)
{
while (!S.empty() && V[S.top()] < V[i])
{
ans[S.top()] = i;
S.pop();
}
S.push(i);
}
84. 柱状图中最大的矩形
(1)题目描述
题目链接如下:
84. 柱状图中最大的矩形https://leetcode.cn/problems/largest-rectangle-in-histogram/description/
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4] 输出: 4
提示:
1 <= heights.length <=105
0 <= heights[i] <= 104
做题分析:
用自己的话解释题意:
找到这个柱状图中所能找到的最大矩形面积。
开始思考解决方法:
首先我们先研究一个思想。
我们的最终答案一定会是某一个小柱形的高度*该高度所能达到的最大长度
那我们就可以极大地减少计算。
因为我们此时已知了高度,只需要得到宽度即可
那么如何找到我们每个高度的最大宽度。
根据前面我们 对单调栈的作用的了解。
单调栈恰好满足了我们的需求。
我们可以找到每个高度的右边的第一个比该高度小的值。
再反过来寻找左边第一个比该高度小的值。
那大概的算法实现就是
预处理出 l 和 r 数组,其中 l[i] 代表位置 i 左边最近一个比其小的位置(初始值为 −1),r[i] 代表位置 i 右边最近一个比其小的位置(初始值为 n),那么 r[i]−l[i]−1 则是以heights[i] 作为矩形高度时所能取得的最大宽度。
代码如下:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int l[100001],r[100001];
stack<int>s1;
for(int i=0;i<heights.size();i++){
r[i]=heights.size();
while(!s1.empty()&&heights[s1.top()]>heights[i]){
r[s1.top()]=i;
s1.pop();
}
s1.push(i);
}
stack<int>s2;
for(int i=heights.size()-1;i>=0;i--){
l[i]=-1;
while(!s2.empty()&&heights[s2.top()]>heights[i]){
l[s2.top()]=i;
s2.pop();
}
s2.push(i);
}
int ans=0;
for(int i=0;i<heights.size();i++){
//cout<<l[i]<<" "<<r[i]<<endl;
ans=max(ans,heights[i]*(r[i]-l[i]-1));
}
return ans;
}
};
二、总结及计划
学到了单调栈,很值得认真思考的数据结构。