1. 柱状图中的最大矩形:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。
思路:从左到右遍历高度,将高度存入栈中,如果当前高度小于栈顶元素,可计算出该栈顶元素所能取得的最大面积,并将该栈顶元素弹出,继续比较下一个栈顶元素与当前高度,直至栈顶元素小于当前高度。当前元素小于栈顶元素时,直接将该高度入栈。遍历完所有元素后,依次弹出栈顶元素,计算该高度对应的面积。
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
if not heights:
return 0
stack = [] # 用来存储高度
max_val = 0
for i,h in enumerate(heights):
if not stack: # 如果栈为空,将高度入栈
stack.append([h,i])
continue
elif h < stack[-1][0]: # 如果当前高度小于栈顶元素
while h < stack[-1][0]:
pop_h = stack.pop() # 计算栈顶高度所能取得的最大面积
if not stack: # 如果当前栈中只有一个元素,则该元素的宽为i
max_val = max(max_val,i*pop_h[0])
break
else: # 如果栈中还有元素,则宽为新栈顶元素的坐标到i
max_val = max(max_val,(i-stack[-1][1]-1)*pop_h[0])
stack.append([h,i])
while stack:
pop_h = stack.pop() # 对栈中剩余的高度计算面积
if stack:
max_val = max(max_val,(len(heights)-stack[-1][1]-1)*pop_h[0])
# 当栈中还有元素时,则宽为新栈顶元素的坐标到最后(整个数组的长度)
else:
max_val = max(max_val,len(heights)*pop_h[0])
# 当栈中没有元素时,说明该高度为整个数组中的最小值。则宽为整个数组的长度
return max_val
2. 矩阵中的最大矩形:给定一个仅包含 0
和 1
、大小为 rows x cols
的二维二进制矩阵,找出只包含 1
的最大矩形,并返回其面积。
思路:该问题可转换为问题1,从上到下遍历矩阵的每一行,这样便可以利用问题1求解。如由上述矩阵可得到4个高度分别为:[1,0,1,0,0]、[2,0,2,1,1]、[3,1,3,2,3]、[4,0,0,3,0]的问题1。
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
def largestRectangleArea(heights):
if not heights:
return 0
stack = [] # 用来存储高度
max_val = 0
for i,h in enumerate(heights):
if not stack: # 如果栈为空,将高度入栈
stack.append([h,i])
continue
elif h < stack[-1][0]: # 如果当前高度小于栈顶元素
while h < stack[-1][0]:
pop_h = stack.pop() # 计算栈顶高度所能取得的最大面积
if not stack: # 如果当前栈中只有一个元素,则该元素的宽为i
max_val = max(max_val,i*pop_h[0])
break
else: # 如果栈中还有元素,则宽为新栈顶元素的坐标到i
max_val = max(max_val,(i-stack[-1][1]-1)*pop_h[0])
stack.append([h,i])
while stack:
pop_h = stack.pop() # 对栈中剩余的高度计算面积
if stack:
max_val = max(max_val,(len(heights)-stack[-1][1]-1)*pop_h[0])
# 当栈中还有元素时,则宽为新栈顶元素的坐标到最后(整个数组的长度)
else:
max_val = max(max_val,len(heights)*pop_h[0])
# 当栈中没有元素时,说明该高度为整个数组中的最小值。则宽为整个数组的长度
return max_val
if not matrix:
return 0
res = 0
heights = [0] * len(matrix[0])
for row in matrix:
for i,v in enumerate(row):
if v == '1':
heights[i] += int(v)
else:
heights[i] = 0
ans = largestRectangleArea(heights)
res = max(res,ans)
return res
3. 矩阵中的最大正方形:在一个由 '0'
和 '1'
组成的二维矩阵内,找到只包含 '1'
的最大正方形,并返回其面积。
思路:利用动态规划的思想,如果矩阵中该位置的值为1,则该位置所能求得的最大正方形边长为:min(左上,左,上) + 1。如果矩阵中该位置的值为0,则该位置所能求得的最大正方形边长即为0。
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
n = len(matrix)
m = len(matrix[0])
res = 0
dp_table = [[0 for _ in range(m)] for _ in range(n)]
for i in range(n):
for j in range(m):
if matrix[i][j] == '1':
if (i-1) >= 0 and (j-1) >= 0 and dp_table[i-1][j-1]:
dp_table[i][j] = \
min(dp_table[i-1][j-1],dp_table[i-1][j],dp_table[i][j-1]) + 1
else:
dp_table[i][j] = 1
res = max(res,dp_table[i][j])
else:
pass
return res**2