84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例: 输入: [2,1,5,6,2,3] 输出: 10 我们首先从左往右对数组进行遍历,借助单调栈求出了每根柱子的左边界,随后从右往左对数组进行遍历,借助单调栈求出了每根柱子的右边界。 class Solution: def largestRectangleArea(self, heights: List[int]) -> int: n = len(heights) left, right = [0] * n, [0] * n mono_stack = list() for i in range(n): while mono_stack and heights[mono_stack[-1]] >= heights[i]: mono_stack.pop() left[i] = mono_stack[-1] if mono_stack else -1 mono_stack.append(i) mono_stack = list() for i in range(n - 1, -1, -1): while mono_stack and heights[mono_stack[-1]] >= heights[i]: mono_stack.pop() right[i] = mono_stack[-1] if mono_stack else n mono_stack.append(i) ans = max((right[i] - left[i] - 1) * heights[i] for i in range(n)) if n > 0 else 0 return ans 优化:解决右边界优化问题 class Solution: def largestRectangleArea(self, heights: List[int]) -> int: n = len(heights) left, right = [0] * n, [n] * n mono_stack = list() for i in range(n): while mono_stack and heights[mono_stack[-1]] >= heights[i]: right[mono_stack[-1]] = i mono_stack.pop() left[i] = mono_stack[-1] if mono_stack else -1 mono_stack.append(i) ans = max((right[i] - left[i] - 1) * heights[i] for i in range(n)) if n > 0 else 0 return ans
42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。 示例: 输入: [0,1,0,2,1,0,1,3,2,1,2,1] 输出: 6 class Solution(object): def trap(self, height): n = len(height) # 同时从左往右和从右往左计算有效面积 s1, s2 = 0, 0 max1, max2 = 0, 0 for i in range(n): if height[i] > max1: max1 = height[i] if height[n - i - 1] > max2: max2 = height[n - i - 1] s1 += max1 s2 += max2 # 积水面积 = S1 + S2 - 矩形面积 - 柱子面积;max1或者max2都表示最大的高度 res = s1 + s2 - max1 * len(height) - sum(height) return res
85. 最大矩形 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 示例: 输入: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] 输出: 6 class Solution: def maximalRectangle(self, matrix: List[List[str]]) -> int: if not matrix: return 0 # 单调栈的应用 2 def getLargestRectLayer(heights): ret = 0 stack = [] heights = [0] + heights + [0] for i in range(len(heights)): while stack and heights[stack[-1]] > heights[i]: tmp = stack.pop() ret = max(ret, (i - stack[-1] - 1) * heights[tmp]) stack.append(i) return ret def getHeights(array, heights): for i in range(len(heights)): if array[i] == "1": heights[i] += 1 else: heights[i] = 0 return heights # 对于每一层 获取heights数组即可 ret = 0 m = len(matrix) for i in range(m): if i == 0: heights = list(map(int, matrix[0])) else: heights = getHeights(matrix[i], heights) retLayer = getLargestRectLayer(heights) ret = max(ret, retLayer) return ret