📜  2D网格中正方形的最大周长(1)

📅  最后修改于: 2023-12-03 15:13:07.895000             🧑  作者: Mango

2D网格中正方形的最大周长

介绍

在一个 $n \times n$ 的网格中,找到一个最大的正方形,其周长为 $4k$,其中 $k$ 为整数。

例如,在以下的网格中,最大的周长为 8:

1 1 0 0
1 1 1 0
1 1 0 1
0 0 1 0
解题思路

首先可以直接暴力枚举所有的正方形,然后对于每一个正方形都判定其是否为有效的正方形。有效的正方形的定义是其四个角都是 1,而正方形中间的所有点也都为 1。

对于每个有效的正方形,计算其周长并更新最大周长即可。时间复杂度为 $O(n^6)$,无法通过大多数的数据。

考虑优化,对于一个网格上的每一个点,可以二分一个最大的正方形边长 $l$,使得以该点为正方形左下角的正方形的最大边长为 $l$。每次更新答案时,找到所有不同位置的左下角的正方形的有效最长边长即可。这样做的时间复杂度为 $O(n^3 \log n)$。

代码实现

下面是 Python 3 代码实现:

class Solution:
    def largest1BorderedSquare(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        dp = [[[0, 0] for _ in range(n)] for _ in range(m)]
        res = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    if i == 0 and j == 0:
                        dp[i][j] = [1, 1]
                    elif i == 0:
                        dp[i][j] = [1, dp[i][j-1][1] + 1]
                    elif j == 0:
                        dp[i][j] = [dp[i-1][j][0] + 1, 1]
                    else:
                        dp[i][j] = [dp[i-1][j][0] + 1, dp[i][j-1][1] + 1]
                    for k in range(min(dp[i][j]), 0, -1):
                        if (dp[i-k+1][j][1] >= k and dp[i][j-k+1][0] >= k):
                            res = max(res, k)
        return res * res

代码中,变量 dp[i][j] 表示以网格 $(i, j)$ 为右下角的可行正方形的最大长度。变量 res 记录最大的边长。