棧-最大面積問題
阿新 • • 發佈:2020-07-30
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] fori 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