题目:
给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。
算法:
方法一:前缀和
func largest1BorderedSquare(grid [][]int) int {
n, m := len(grid), len(grid[0])
rs := make([][]int, n)
for i := range rs {
rs[i] = make([]int, m + 1)
}
cs := make([][]int, m)
for i := range cs {
cs[i] = make([]int, n + 1)
}
for i := range grid {
for j := range grid[i] {
rs[i][j + 1] = rs[i][j] + grid[i][j]
cs[j][i + 1] = cs[j][i] + grid[i][j]
}
}
for d := min(m, n); d > 0; d -- {
for i := 0; i <= n - d; i ++ {
for j := 0; j <= m - d; j ++ {
if rs[i][j + d] - rs[i][j] == d &&
cs[j][i + d] - cs[j][i] == d &&
rs[i + d - 1][j + d] - rs[i + d - 1][j] == d &&
cs[j + d - 1][i + d ] - cs[j + d - 1][i] == d {
return d * d
}
}
}
}
return 0
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
方法二:前缀和
func largest1BorderedSquare(grid [][]int) int {
m, n := len(grid), len(grid[0])
// row,和col方向上,最大连续的1的个数
row, col := make([][]int, m + 1), make([][]int, m + 1)
largestEdge := 0
for i := range col {
row[i] = make([]int, n + 1)
col[i] = make([]int, n + 1)
}
for i := range grid {
for j := range grid[i] {
if grid[i][j] == 1 {
row[i + 1][j + 1] = row[i][j + 1] + 1
col[i + 1][j + 1] = col[i + 1][j] + 1
}
edge := min(row[i + 1][j + 1], col[i + 1][j + 1])
for k := edge; k > 0; k -- {
if j - k + 2 > 0 && row[i + 1][j - k + 2] >= k && i - k + 2 > 0 && col[i - k + 2][j + 1] >= k {
if k > largestEdge {
largestEdge = k
break
}
}
}
}
}
return largestEdge * largestEdge
}
func min(a, b int) int {
if a < b {
return a
}
return b
}