力扣LCR 039. 柱状图中最大的矩形
思路
用到了单调栈。由于最大矩形它的高一定是height数组中的其中一个值,那么我们就可以遍历数组height的值再乘上它的宽的最大值WidthMax(宽的最大值后面会讲),然后取最大值就是答案,也就是ans=max(ans,WidthMax*height[x])。
那么如何求高为height[x]的宽的最大值WidthMax呢?
解题过程
如图,以黄色块为高所能撑起的最大范围即为红色部分,(数组heigh中的每个值都有可能是黄色块,所以后面要遍历一下)那么问题就转变为:
1.求从x开始的左边找第一个高度小于heigh[x]的长方形的下标l
2.同理,求从x的右边第一个小于heigh[x]的长方形的下标r
3.矩形的宽的最大值为WidhMax = r -l -1
那么问题又转变为如何求上面的l和r?
对于求r,此问题不就是已知数组的下标,求该下标开始从右边开始找第一个更小值吗?此时就可以用单调栈的思想来预处理每个点的右边界的值了,该过程与力扣中https://leetcode.cn/problems/next-greater-element-i/description/这道题相似,不懂单调栈的可以先做那道题
那么l也同理,从左边开始找第一个更小值的下标
那么r[x]和l[x]就求出来了,
最后遍历每个小长方形,求(height[x]*(r[x]-l[x]-1))的最大值就是答案了
时间复杂度: 𝑂(𝑛)
空间复杂度: 𝑂(𝑛)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
//选定一个下标,从这个下标两边分别找第一个比它矮的下标(理解为找左边的第一个更小数,右边的第一个更小数),然后r-l-1个这样的矩形的和即为答案的可能之一
const int N = 1e5+50;
int l[N], r[N], s[N],top = -1;
//预处理每个点的两边第一次碰到更矮的下标
for(int i = 0; i < heights.size(); i++){
int num = heights[i];
while(top>=0&&heights[s[top]]>=num){
top--;
}
if(top>=0)
l[i] = s[top];
else l[i] = -1;
s[++top]=i;
}
top = -1;
for(int i = heights.size()-1; i >= 0; i--){
int num = heights[i];
while(top>=0 && heights[s[top]] >= num)
top--;
if(top>=0) r[i] = s[top];
else r[i] = heights.size();
s[++top] = i;
}
int ans = 0;
for(int i = 0; i < heights.size(); i++){
ans = max(ans,(r[i]-l[i]-1)*heights[i]);
}
return ans;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理