2023年2月8日23点23分 代码随想录一刷 完结撒花 开心子
题目列表
代码随想录地址:https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.html
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4
提示:
柱子彼此相邻,宽度都为1,高度各不相同。对于当前考察的柱子来说,它所能勾勒出的矩形面积是由其左边柱子和右边柱子的高度共同决定的。
如果其左边柱子的高度大于等于当前柱子的高度,则可以向左侧扩张,直到左边柱子高度小于当前柱子高度或左边再无其它柱子;同样的,如果其右边柱子的高度大于等于当前柱子的高度,则可以向右侧扩张,直到右边柱子高度小于等于当前柱子高度或右边再无其它柱子。
这时,就可以计算出以当前柱子高度为高,左右柱子间距离为宽的矩形面积。
作者:hardcore-aryabhata
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/solution/dong-hua-yan-shi-dan-diao-zhan-84zhu-zhu-03w3/
就是说,对于每个柱子,找到其最远能扩张的左柱子,和最远能扩张的右柱子,然后以当前柱子为高,左到右为宽,求得面积。
栈头(元素从栈头弹出)到栈底的顺序为从大到小。
栈顶元素是高度最大的元素,栈顶的下一个元素是左边能扩展到的下一个元素,当前元素是右边能扩展到的下一个元素。
三种情况:
栈顶元素一直是最高的元素。
就求面积并更新max面积。考虑出栈嘻嘻。
将当前元素入栈。
将当前元素入栈。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int sum = 0;
for (int i = 0; i < heights.size(); i++) {
int left = i;
int right = i;
for (; left >= 0; left--) {
if (heights[left] < heights[i]) break;
}
for (; right < heights.size(); right++) {
if (heights[right] < heights[i]) break;
}
int w = right - left - 1;
int h = heights[i];
sum = max(sum, w * h);
}
return sum;
}
};
/*
* @lc app=leetcode.cn id=84 lang=cpp
*
* [84] 柱状图中最大的矩形
*/
// @lc code=start
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
//数组头部和尾部都加入0是为了处理原始height的第一个元素和最后一个元素作为高的情况
heights.insert(heights.begin(), 0);
heights.push_back(0);
int res = 0;
stack<int> st;
st.push(0);//初始插入第一个元素的下标
for(int i = 1; i < heights.size(); i++)
{
//三种情况
if(heights[i] > heights[st.top()])
st.push(i);
else if(heights[i] == heights[st.top()])
{//此处写与不写都是一样的,因为在后面处理的时候只处理当前元素小于栈顶元素的情况
st.pop();
st.push(i);
}
else
{
while(!st.empty() && heights[i] < heights[st.top()])
{
int mid = st.top();
st.pop();
int high = heights[mid];
int length = i - st.top() - 1;
res = max(res, high * length);
}
st.push(i);
}
}
return res;
}
};
// @lc code=end