难度困难
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4] 输出: 4
中心扩散,找到当前以 hight[i] 为高,长度最长,然后算 面积。
是以i 为中心,向左找第一个小于 heights[i] 的位置 left_i;向右找第一个小于于 heights[i] 的位置 right_i,即最大面积为 heights[i] * (right_i - left_i -1),如下图所示:
所以,我们的问题就变成如何找 right_i 和 left_i?
class Solution { public: int largestRectangleArea(vector<int>& heights) { int max_res = 0; int n = heights.size(); for (int i = 0; i < n;i++) { int left_i = i; while (left_i >= 0 && heights[left_i] >= heights[i]) left_i--; int right_i = i; while (right_i <= n-1 && heights[right_i] >= heights[i]) right_i++; max_res = max(max_res,heights[i] * (right_i-left_i-1)); //cout << heights[i] << " " << left_i << " " << right_i << endl; } return max_res; } };
2 3 4 1 为例子,
234 入栈,到1 时,无法入栈。 需要将栈内大于1的元素弹出,此时,以右边界就找到了,就是1所在的索引,4的左边界就是把4弹出来,剩下的 top 就是3 所在的索引,继续弹,只到弹完,就相当于遍历了以 1为右边界,所有的面积。
class Solution { public: int largestRectangleArea(vector<int>& heights) { stack<int> stk; int res = 0; int top = 0; heights.push_back(-1); stk.push(-1); for(int i =0;i < heights.size();i++) { while(stk.top()!=-1 && heights[stk.top()] > heights[i]) { top = stk.top(); stk.pop(); res = max(res, heights[top] *(i-stk.top()-1)); } stk.push(i); } return res; } };