主页 > 其他  > 

【力扣Hot100】栈2

【力扣Hot100】栈2
5. 柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

! assets.leetcode /uploads/2021/01/04/histogram.jpg

输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10

示例 2:

! assets.leetcode /uploads/2021/01/04/histogram-1.jpg

输入: heights = [2,4] 输出: 4

提示:

1 <= heights.length <=1050 <= heights[i] <= 104

题解

别人说的:

单调增栈:

进栈前弹出的都是左边比自己大的→确定左边界;出栈时必定是右边第一次遇到比自己小的→确定右边界

思路:

对于每一个柱状图,我们要求它的高度向左最远能到哪里,向右最远能到哪里。

也就是找左边第一个比它小的数,以及右边第一个比它小的数。

找一系列数中第一个比自己小/大的数→单调栈问题。

所以可以建两个栈,一个存左边第一个比自己小的数,一个存右边第一个比自己小的数。(单调递增栈)

代码如下:

class Solution { public: int largestRectangleArea(vector<int>& heights) { int n = heights.size(); stack<int> stk; vector<int> left(n), right(n); int ans = 0; for(int i = 0; i < n; i ++ ) { while(stk.size() && heights[i] <= heights[stk.top()]) { stk.pop(); } left[i] = stk.empty() ? -1 : stk.top(); stk.push(i); } stk = stack<int>(); for(int i = n - 1; i >= 0; i -- ) { while(stk.size() && heights[i] <= heights[stk.top()]) { stk.pop(); } right[i] = stk.empty() ? n : stk.top(); stk.push(i); } for(int i = 0; i < n; i ++ ) { ans = max(ans, (right[i] - left[i] - 1) * heights[i]); } return ans; } };

还可以优化。

当一个数出栈时,它是第一次遇到比它小的数,也就是它的右边界。

如果一个数没出栈,说明它的右边没有比它小的数,它的右边界是n。

所以可以优化(但是时间空间复杂度都没变hhh),代码如下:

class Solution { public: int largestRectangleArea(vector<int>& heights) { int n = heights.size(); stack<int> stk; vector<int> left(n), right(n, n); int ans = 0; for(int i = 0; i < n; i ++ ) { while(stk.size() && heights[i] <= heights[stk.top()]) { right[stk.top()] = i; stk.pop(); } left[i] = stk.empty() ? -1 : stk.top(); stk.push(i); } for(int i = 0; i < n; i ++ ) { ans = max(ans, (right[i] - left[i] - 1) * heights[i]); } return ans; } };
标签:

【力扣Hot100】栈2由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【力扣Hot100】栈2