1.题目
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.题解
暴力(C++过不了)
为什么要写下暴力法,是因为其他方法不过就是在暴力法的基础上运用一些存储记录的方法,以空间换时间罢了!
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
int size = heights.size();
if(size == 0) return 0;
int res = 0;
for(int i = 0; i < size; i++)
{
int L = i;
int cur = heights[i];
while( L > 0 && heights[ L - 1 ] >= cur)
L--;
int R = i;
while(R < size - 1 && heights[R + 1] >= cur)
R++;
res= max(res,(R - L + 1)*cur);
}
return res;
}
};
单调栈
思路:
我们发现在暴力求解中,我们要做的就是寻找每个柱体不能再向左或向右拓展时,最大的面积,暴力求法中,我们用线性时间求得。
那么我们能否通过单调栈来再优化查找边界的时间。
优化:
单调递增栈,当前的高度严格小于栈顶元素的高度时出栈。计算面积。
思路参考https://leetcode-cn.com/problems/largest-rectangle-in-histogram/solution/84-by-ikaruga/
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
int ans = 0;
vector<int> st;
heights.insert(heights.begin(), 0); //首尾加0,方便处理
heights.push_back(0);
for (int i = 0; i < heights.size(); i++)
{
while (!st.empty() && heights[st.back()] > heights[i])
{
int cur = st.back();
st.pop_back();
int left = st.back() + 1;
int right = i - 1;
ans = max(ans, (right - left + 1) * heights[cur]);
}
st.push_back(i);
}
return ans;
}
};