想用动态规划,逻辑有漏洞,过不了。dp[i]记录的是以heights[i]柱子为结尾的矩形的宽和高。并不是以heights[i]为高的矩形。
错误代码:
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
hlen = len(heights)
dp = [[0,0]] * hlen # 每个dp[i]记录的是以heights[i]柱子为结尾的矩形的宽和高
dp[0] = [1, heights[0]]
res = dp[0][0] * dp[0][1] # 最大面积
for i in range(1, hlen):
width = (dp[i-1][0] + 1)
height = (min(dp[i-1][1], heights[i]))
combination = width * height # 宽+1 * 最矮的柱子高度 = 融合的面积
if 1*heights[i] > combination: # 自己独美
dp[i] = [1, heights[i]]
else: dp[i] = [width, height]
res = max(res, combination, heights[i])
return res
参考链接:暴力解法、栈(单调栈、哨兵技巧)里面有具体的图形解释。
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
heights = [0] + heights + [0] # 加哨兵
stack = [0] # 用单调栈的方法,并放入左边第一个哨兵
res = 0
for i in range(1, len(heights)): # 按列计算,遍历,计算以某个柱子为高的最大矩形面积
while heights[i] < heights[stack[-1]]: # 只要新来的柱子i比栈中stack[-1]的矮,就能计算以【此时的stack[-1]这个柱子的高度】为【矩形的高】的最大面积
j = stack.pop()
height = heights[j] # 记录要计算的柱子的高
width = i - stack[-1] - 1 # 计算向右[i]和向左[stack[-1]]延伸的宽度,此时的stack[-1]的高可能和之前pop()的高相同,或者小于。小于就是说stack[-1]到了这个矩形的最左边,-1是减去第i柱子的宽度;等于也没关系,等下一个while就能计算到。
res = max(res, height * width)
stack.append(i) # 大于等于就直接入栈
return res