[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

最大的以 1 为边界的正方形。

给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/largest-1-bordered-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是前缀和。

这道题一开始我以为是跟 221 题类似的二维动态规划题,但是后来发觉不是,还是只能用前缀和的思路做。具体的做法是我先创建两个二维数组,分别记录每个 row 和每个 col 的前缀和,这样我就可以在 O(1) 的时间内知道某一段长度内是否都是 1。

因为能组成的最大的正方形的边长应该是 input 矩形较短的那一条边,设这个长度为 d。那么我们可以从 d 到 0 一点点去测试,看看哪个边长能被满足。因为 d 是从大到小遍历的,所以找到第一个满足条件的 d 就可以返回了。

时间O(m * n * d)

空间O(mn)

Java实现

 1 class Solution {
 2     public int largest1BorderedSquare(int[][] grid) {
 3         int m = grid.length;
 4         int n = grid[0].length;
 5         int[][] rs = new int[m][n + 1];
 6         int[][] cs = new int[n][m + 1];
 7         for (int i = 0; i < m; i++) {
 8             for (int j = 0; j < n; j++) {
 9                 rs[i][j + 1] = rs[i][j] + grid[i][j]; // 每行的前缀和
10                 cs[j][i + 1] = cs[j][i] + grid[i][j]; // 每列的前缀和
11             }
12         }
13 
14         for (int d = Math.min(m, n); d > 0; d--) // 从大到小枚举正方形边长 d
15             for (int i = 0; i <= m - d; i++)
16                 for (int j = 0; j <= n - d; j++) // 枚举正方形左上角坐标 (i,j)
17                     if (rs[i][j + d] - rs[i][j] == d && // 上边
18                             cs[j][i + d] - cs[j][i] == d && // 左边 
19                             rs[i + d - 1][j + d] - rs[i + d - 1][j] == d && // 下边
20                             cs[j + d - 1][i + d] - cs[j + d - 1][i] == d) // 右边
21                         return d * d;
22         return 0;
23     }
24 }

 

LeetCode 题目总结

posted @ 2023-02-17 09:01  CNoodle  阅读(53)  评论(0编辑  收藏  举报