85. 最大矩形

题目描述

给了只包含0和1的矩阵,问只包含1的最大矩形的面积?

f1-转化为逐列求面积+单调栈

基本分析

  1. 怎么优化暴力枚举的想法?对每一行,可以与处理出包括自己的左边最长的1的个数,写在left矩阵中
  2. 逐列的考虑以上数组,就是n个lc_84对应的问题,找以i列为第i列为底的最大矩形面积

代码

以列为第的版本

class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:


        def f(ls):
            m = len(ls)
            up, down = [-1] * m, [m] * m

            st = []
            for i in range(m):
                while st and ls[st[-1]] > ls[i]:
                    cur = st.pop()
                    down[cur] = i
                st.append(i)
            
            st = []
            for i in range(m-1, -1, -1):
                while st and ls[st[-1]] > ls[i]:
                    cur = st.pop()
                    up[cur] = i
                st.append(i)
            
            ans = 0
            for i in range(m):
                ans = max(ans, ls[i] * (down[i] - up[i] - 1))
            return ans
        
        m, n = len(matrix), len(matrix[0])
        left = [[0] * n for _ in range(m)]

        for i in range(m):
            for j in range(n):
                if matrix[i][j] == '1':
                    if j == 0:
                        # 包括自己的
                        left[i][j] = 1
                    else:
                        left[i][j] = left[i][j-1] + 1

        ans = 0
        for j in range(n):
            ls = [left[i][j] for i in range(m)]
            ans = max(ans, f(ls))
        return ans

以行为底的版本

class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:

        def f(ls):
            n = len(ls)
            l, r = [-1] * n, [n] * n
            
            st = []
            for i in range(n):
                while st and ls[st[-1]] > ls[i]:
                    cur = st.pop()
                    r[cur] = i
                st.append(i)
            
            st = []
            for i in range(n-1, -1, -1):
                while st and ls[st[-1]] > ls[i]:
                    cur = st.pop()
                    l[cur] = i
                st.append(i)
            
            ans = 0
            for i in range(n):
                ans = max(ans, ls[i] * (r[i] - l[i] - 1))
            return ans
        
        m, n = len(matrix), len(matrix[0])
        
        heights = [[0] * n for _ in range(m)]
        # 找i行为第的最大高度
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == '1':
                    if i == 0:
                        heights[i][j] = 1
                    else:
                        heights[i][j] = heights[i-1][j] + 1
        ans = 0
        for i in range(m):
            ans = max(ans, f(heights[i]))
        return ans

总结

  1. 怎么与处理出left矩阵?对每一行,计算连续的1的个数,包括i点
  2. 怎么计算答案?遍历所有列,每次的输入就是第i列为底的数组,按照84的做法求面积。
posted @ 2023-03-20 21:10  zhangk1988  阅读(14)  评论(0)    收藏  举报