一、LeetCode84. 柱状图中最大的矩形
1:题目描述(84. 柱状图中最大的矩形)
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
2:解题思路
解法一:动态规划
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
# 动态规划
res = 0
minleft = [0] * len(heights)
minright = [0] * len(heights)
# 计算每个柱子,左边第一个小于该柱子的高度
minleft[0] = -1 # 进行初始化,防止进入死循环
for l in range(1, len(heights)):
temp = l-1
while temp>=0 and heights[temp] >= heights[l]:
temp = minleft[temp]
minleft[l] = temp
# 计算每个柱子,右边第一个小于该柱子的高度
minright[len(heights)-1] = len(heights)
for r in range(len(heights)-2, -1, -1):
temp = r+1
while temp < len(heights) and heights[temp] >= heights[r]:
temp = minright[temp]
minright[r] = temp
for i in range(len(heights)):
area = heights[i] * (minright[i] - minleft[i] - 1)
res = max(area, res)
return res
解法二:单调栈
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
# 单调栈
# 找每个柱子左右侧的第一个高度值小于该柱子的柱子
# 单调栈:栈顶到栈底:从大到小(每插入一个新的小数值时,都要弹出先前的大数值)
# 栈顶,栈顶的下一个元素,即将入栈的元素:这三个元素组成了最大面积的高度和宽度
# 情况一:当前遍历的元素heights[i]大于栈顶元素的情况
# 情况二:当前遍历的元素heights[i]等于栈顶元素的情况
# 情况三:当前遍历的元素heights[i]小于栈顶元素的情况
# 输入数组首尾各补上一个0
heights.insert(0,0)
heights.append(0)
res = 0
res_stack = [0]
for i in range(1, len(heights)):
# 情况一
if heights[i] > heights[res_stack[-1]]:
res_stack.append(i)
# 情况二
elif heights[i] == heights[res_stack[-1]]:
res_stack.pop()
res_stack.append(i)
# 情况三
else:
# 抛出所有较高的柱子
while len(res_stack)!=0 and heights[i] < heights[res_stack[-1]]:
# 栈顶就是中间的柱子
index = res_stack[-1]
res_stack.pop()
if len(res_stack)!=0:
left_index = res_stack[-1]
right_index = i
width = right_index - left_index - 1
height = heights[index]
res = max(res, width*height)
res_stack.append(i)
return res