Leetcode 84 柱状图中最大的矩阵
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
输入: [2,1,5,6,2,3]
输出: 10
题解: 题目的意思可以简化为找到一组子数组[i,j],
使得min(a[i],...a[j])*(j-i+1)最大。
关键问题是如何快速找到m[j]=min(a[i],...a[j])。
m[i]=heights[i]开始,更新,时间复杂度是O(n2)。
但是超时了。。。需要进一步优化。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n= heights.size();
int ans= 0;
int m[n+1];
for(int i=0;i<n;i++){
m[i]=heights[i];
ans = max(ans,heights[i]);
for(int j=i+1;j<n;j++){
m[j]=min(m[j-1],heights[j]);
ans =max(ans,(j-i+1)*m[j]);
}
}
return ans;
}
};
参考题解的思路:
类似接雨水那题的思路,我们可以根据heights[i]的高度找出他的左右边界。
可以画一些具体情况出来:
- 当我们从左到右,新的柱子比前面的低时,新柱子就是前面柱子的右边界;
左边界就是它左边比它低的那个柱子的位置;width就是 新柱子的位置i - 前一个比它低的柱子位置j -1;(两边不取)
遍历从左到右,判断从右到左,符合栈的数据结构;
如果栈为空,表示当前柱子左边没有比它更小的,左边界就是0。
- 当遍历完一遍之后,栈里面剩下的就是单调递增的位置。
此时每个柱子的右边没有比它更低的了,所以右边界就是n。
左边界同上。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n= heights.size();
if(n==1)
return heights[0];
int res = 0;
stack<int> stk;
for(int i=0;i<n;i++){
while(!stk.empty()&&heights[stk.top()]>heights[i]){
int len = heights[stk.top()];
stk.pop();
int width=i;
if(!stk.empty()){
width = i -stk.top()-1;
}
res=max(res,len*width);
}
stk.push(i);
}
while(!stk.empty()){
int len = heights[stk.top()];
stk.pop();
int width = n;
if(!stk.empty()){
width= n- stk.top()-1;
}
res=max(res,len*width);
}
return res;
}
};