Given a 2D grid of 0s and 1s, return the number of elements in the largest square subgrid that has all 1s on its border, or 0 if such a subgrid doesn’t exist in the grid.
Example 1:
Input: grid = [[1,1,1],[1,0,1],[1,1,1]]
Output: 9
Example 2:
Input: grid = [[1,1,0,0]]
Output: 1
Constraints:
- 1 <= grid.length <= 100
- 1 <= grid[0].length <= 100
- grid[i][j] is 0 or 1
先计算每行的 prefix sum 和每列的 prefix sum, 然后遍历 gird 中的所有点, 如果这个点是 1, 那我们就把它作为 top left, 然后顺着对角线往右下角找 bottom right, 对于每个 bottom right 点, 我们可以根据行的 prefix sum 和列的 prefix sum 来快速的检测出这个正方形是不是边上都是 1 的正方形
impl Solution {
pub fn largest1_bordered_square(grid: Vec<Vec<i32>>) -> i32 {
let row_prefixs: Vec<Vec<i32>> = grid
.iter()
.map(|l| {
let mut prefix_sum: Vec<i32> = l
.iter()
.scan(0, |s, v| {
*s += *v;
Some(*s)
})
.collect();
prefix_sum.insert(0, 0);
prefix_sum
})
.collect();
let mut col_prefixs: Vec<Vec<i32>> = vec![vec![0; grid.len() + 1]; grid[0].len()];
for col in 0..grid[0].len() {
for row in 1..grid.len() + 1 {
col_prefixs[col][row] = col_prefixs[col][row - 1] + grid[row - 1][col];
}
}
let mut ans = 0;
for top in 0..grid.len() {
for left in 0..grid[0].len() {
if grid[top][left] == 1 {
for d in 0..grid.len().min(grid[0].len()) {
let bottom = top + d;
let right = left + d;
if bottom == grid.len() || right == grid[0].len() {
break;
}
if row_prefixs[top][right + 1] - row_prefixs[top][left]
!= (right - left + 1) as i32
{
continue;
}
if row_prefixs[bottom][right + 1] - row_prefixs[bottom][left]
!= (right - left + 1) as i32
{
continue;
}
if col_prefixs[left][bottom + 1] - col_prefixs[left][top]
!= (bottom - top + 1) as i32
{
continue;
}
if col_prefixs[right][bottom + 1] - col_prefixs[right][top]
!= (bottom - top + 1) as i32
{
continue;
}
ans = ans.max((d + 1) * (d + 1));
}
}
}
}
ans as i32
}
}