Leetcode84 柱状图中最大的矩形 详细的解法

红太狼 2022-10-09 00:55 215阅读 0赞

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

b9dbdc656397e91f5980d3dbe2ef5854.png

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。

8219c6a7bb5daec3e3c87ec973d4c9dc.png

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10
1
2
解题思路

这个问题非常有意思。我们首先可以想到的是暴力破解,我们通过i不断遍历heights,然后在遍历的过程中通过j不断向后寻找最大矩形。

36f5e3a77e23c2a6a57e979da882f3a5.png

例如,我们把i从1开始遍历,j在[i,len(heights)]区间遍历。

6194cf0f736797736aa4c05b9ec43b63.png
接着我们i从2开始遍历,j在[i,len(heights)]区间遍历。

class Solution:
def largestRectangleArea(self, heights):
“””
:type heights: List[int]
:rtype: int
“””
if not heights:
return 0
heights_len = len(heights)
res = 0
i, j = 0, 0
while i < heights_len:
min_h = heights[i]
for j in range(i, heights_len):
min_h = min(min_h, heights[j])
res = max(res, min_h*(j - i + 1))
i += 1

  1. return res

这种解法显然很慢,我们有一种更好的思路就是通过递增栈。所谓的递增栈,就是栈中只存放递增序列。

cc94c218014006e7b2534dafa34f5db0.png
我们首先将2加入到栈中,我们接着访问1,我们发现1比栈顶元素2小,所以我们将栈顶元素2弹出,并且记录此时的面积2。我们发现栈已经空了,所以我们要接着压栈。

1d3f4e5761f82e68a18718c9c14d3f2a.png
接着我们通过不断遍历找到第二个递增栈。

d8cd2f00ba39c864eef1601c55dd2a8a.png

我们接着访问2,我们发现此时2比栈顶元素6小,所以我们弹出栈顶元素6,并且记录此时的面积6*1=6。

9448c9e278d2254d1a2d8a4c253cc52c.png
此时栈中还有元素,我们发现此时2依旧比栈顶元素5小,所以我们需要将栈顶元素5弹出,并且我们记录此时出栈元素构成的最大面积5*2=10。

我们发现此时的2比栈顶元素大了,我们就将2压入栈中,接着将3压入栈中。此时遍历结束,我们发现栈不为空,所以我们需要进行出栈操作,出栈的同时记录出栈元素构成的最大面积即可。

class Solution:
def largestRectangleArea(self, heights):
“””
:type heights: List[int]
:rtype: int
“””
stack = list()
res, i = 0, 0
while i < len(heights):
if not stack or (heights[i] >= heights[stack[-1]]):
stack.append(i)
i += 1
else:
k = stack.pop()
res = max(res, heights[k]*((i - stack[-1] - 1) if stack else i))

  1. while stack:
  2. k = stack.pop()
  3. res = max(res, heights\[k\]\*((i - stack\[-1\] - 1) if stack else i))
  4. return res

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
一个更简洁的写法。

class Solution:
def largestRectangleArea(self, heights):
“””
:type heights: List[int]
:rtype: int
“””
stack = [-1]
res = 0
heights.append(-1)

  1. for idx, val in enumerate(heights):
  2. while heights\[stack\[-1\]\] > val:
  3. h = heights\[stack.pop()\]
  4. res = max(res, h\*(idx - stack\[-1\] -1))
  5. stack.append(idx)
  6. return res

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!
————————————————
版权声明:本文为CSDN博主「coordinate_blog」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq\_17550379/article/details/85093224

发表评论

表情:
评论列表 (有 0 条评论,215人围观)

还没有评论,来说两句吧...

相关阅读