LeetCode 85. 最大矩形(Hard)/ 223. (需要算重叠部分的)矩形面积(Medium)/ 1139. 最大的以 1 为边界的正方形(Medium)/ 数学相关问题!!!

在这里插入图片描述
在这里插入图片描述
题目链接

题解

  1. Python3 前缀和+单调栈计算最大矩形

思路

在这里插入图片描述

代码

class Solution:
    ### 0121 单调栈(84 ms,20.1 MB)
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        if not matrix: return 0

        res = 0
        m, n = len(matrix), len(matrix[0])

        # 每一行最后多加一个0,初始化0表示右边界的1
        heights = [0] * (n + 1)

        # 根据 行 来遍历,并更新最大矩阵
        for i in range(m):
            # 累积每一行上方 1 的数量,若出现0则中断重新累积
            for j in range(n): # 注意:由于使用了matrix,所以这里只需要n,而非n+1!
                heights[j] = heights[j] + 1 if matrix[i][j] == '1' else 0

            # 每行定义一个单调栈,初始化-1表示左边界的1
            stack = [-1]
            # 注意:由于需要使用heights,所以这里相当于是n+1!
            for k, num in enumerate(heights):
                # 只要有比当前列高的列,就出栈(保证递增)
                while heights[stack[-1]] > num:
                    cur_h = heights[stack.pop()] # 注意:pop已经出栈!
                    cur_w = k - stack[-1] - 1
                    res = max(res, cur_h * cur_w)
                
                # 将本列加入栈中
                stack.append(k)

        return res

223. (需要算重叠部分的)矩形面积(Medium)

在这里插入图片描述

class Solution:
    def computeArea(self, ax1: int, ay1: int, ax2: int, ay2: int, bx1: int, by1: int, bx2: int, by2: int) -> int:
        # 计算2个矩形的面积
        s1 = (ax2 - ax1) * (ay2 - ay1)
        s2 = (bx2 - bx1) * (by2 - by1)
        
        # 计算重叠部分的面积
        a = max(min(ax2, bx2) - max(ax1, bx1), 0) # 重叠部分的长:若为负数,说明未重叠,直接置0
        b = max(min(ay2, by2) - max(ay1, by1), 0) # 重叠部分的宽:若为负数,说明未重叠,直接置0
        
        return s1 + s2 - a * b

1139. 最大的以 1 为边界的正方形

在这里插入图片描述

class Solution:
    # 动态规划
    def largest1BorderedSquare(self, grid):

        m, n = len(grid), len(grid[0])
        left = [[0] * (n + 1) for _ in range(m + 1)]
        up = [[0] * (n + 1) for _ in range(m + 1)]
        maxBorder = 0

        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if grid[i - 1][j - 1]:
                    # 只需两个边即可确定正方形
                    left[i][j] = left[i][j - 1] + 1
                    up[i][j] = up[i - 1][j] + 1
                    
                    # 合法正方形的边长的最大值为left[i][j], up[i][j]二者的最小值
                    border = min(left[i][j], up[i][j])
                    # 从border开始,从大到小进行枚举(遍历),直到枚举到一个合法的正方形即可
                    while left[i - border + 1][j] < border or up[i][j - border + 1] < border:
                        border -= 1
                    
                    maxBorder = max(maxBorder, border)

        return maxBorder ** 2

在这里插入图片描述

数学问题!!!

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值