LeetCode每日一题(1139. Largest 1-Bordered Square)

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
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值