📅  最后修改于: 2023-12-03 15:13:07.895000             🧑  作者: Mango
在一个 $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
记录最大的边长。