写代码的第四十二天
最后一天单调栈啊啊啊啊啊啊啊啊
42. 接雨水
思路
本题需要找到当前这个位置左侧的最大值和右侧的最大值,在这两个最大值选最小的那个然后减去当前位置的值,这个值代表高度,那么深度是之前高度所代表的下标进行相减,用高乘深度,每个点的这些值加起来就得到最后的最大容量。
正确代码:
class Solution:
def trap(self, height: List[int]) -> int:
result = 0
stack = [0]
for i in range(len(height)):
if height[i] < height[stack[-1]]:
stack.append(i)
elif height[i] == height[stack[-1]]:
stack.pop()
stack.append(i)
else:
while len(stack) != 0 and height[i] > height[stack[-1]]:
mid = height[stack[-1]]
stack.pop()
if not stack:
break
right_height = height[i]
left_height = height[stack[-1]]
h = min(right_height,left_height) - mid
w = i - stack[-1] - 1
result += h * w
stack.append(i)
return result
84.柱状图中最大的矩形
思路
本题和上一题差不多,只是这个题要找每个柱子左右侧的第一个高度值小于该柱子的柱子。每插入一个新的小数值时,都要弹出先前的大数值,所以这里和上一题是相反的。栈顶,栈顶的下一个元素,即将入栈的元素:这三个元素组成了最大面积的高度和宽度。需要注意的是本题的柱子在最开始的那位和最后面的那位也是可以用的,上一题是不能用的,所以在上一题的基础上做一些修改即可。
# 单调栈
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
heights.insert(0, 0)
heights.append(0)
stack = [0]
result = 0
for i in range(len(heights)):
if heights[i] > heights[stack[-1]]:
stack.append(i)
elif heights[i] == heights[stack[-1]]:
stack.pop()
stack.append(i)
else:
while stack and heights[i] < heights[stack[-1]]:
mid_index = stack[-1]
stack.pop()
if stack:
left_index = stack[-1]
right_index = i
width = right_index - left_index - 1
height = heights[mid_index]
result = max(result, width * height)
stack.append(i)
return result