柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
方法一: 暴力遍历法,暴力循环每个柱子,然后在该位置向左遍历找到第一个小于当前高度的柱子,向右找到第一个小于当前高度的柱子,计算面积。时间复杂度O(N2)
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
# #方法1,暴力法,超时
res, n = 0, len(heights)
if n == 1:
return heights[0]
for i in range(n):
p1 = p2 = i
while p1 > -1 and heights[i] <= heights[p1]:
p1 -= 1
while p2 < n and heights[i] <= heights[p2]:
p2 += 1
max_s = (p2 - p1 - 1) * heights[i]
res = max(res, max_s)
return res
方法二:辅助栈,遍历每个柱子,并维护一个单调递增的栈,比较每一个柱子和栈顶元素的大小,如果大于栈顶元素,就将栈顶元素出栈,这样的好处就是如果当前元素小于等于栈顶元素时,会将
#栈
stack, n = [], len(heights)
if n == 0:
return 0
left = [0] * n
right = [0] * n
res = 0
for i in range(n):
while stack and heights[stack[-1]] >= heights[i]:
stack.pop()
left[i] = -1 if not stack else stack[-1]
stack.append(i)
stack = []
for i in range(n-1, -1, -1):
while stack and heights[stack[-1]] >= heights[i]:
stack.pop()
right[i] = n if not stack else stack[-1]
stack.append(i)
res = max((right[i] - left[i] - 1) * heights[i] for i in range(n))
return res
方法3: 栈优化
#优化后的栈
stack, n = [], len(heights)
if n == 0:
return 0
left = [0] * n
right = [n] * n
res = 0
for i in range(n):
while stack and heights[stack[-1]] >= heights[i]:
right[stack[-1]] = i
stack.pop()
left[i] = stack[-1] if stack else -1
stack.append(i)
res = max((right[i] - left[i] - 1) * heights[i] for i in range(n))
return res