- 最大的以 1 为边界的正方形
给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。
示例 1:
输入:grid = [[1,1,1],[1,0,1],[1,1,1]]
输出:9
示例 2:
输入:grid = [[1,1,0,0]]
输出:1
提示:
1 <= grid.length <= 100
1 <= grid[0].length <= 100
grid[i][j] 为 0 或 1
思路:
这种题一般都有个预处理,把表格中每个数以它截至的最大长度或(和)宽度先求出来;
再想想就有思路了;
class Solution {
public:
void Init(vector<vector<int>>& grid)
{
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0) {
heights[i][j] = grid[i][j];
} else if (grid[i][j] == 0) {
heights[i][j] = 0;
} else {
heights[i][j] = 1 + heights[i - 1][j];
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (i == 0) {
widths[j][i] = grid[j][i];
} else if (grid[j][i] == 0) {
widths[j][i] = 0;
} else {
widths[j][i] = 1 + widths[j][i - 1];
}
}
}
}
int GetMaxLen(int row, int col, int maxLen)
{
int out = 1;
for (int i = maxLen; i > 1; i--) { // key2:贪心,优先找大的正方形
if (widths[row - i + 1][col] < i) { // key2:右上角的最大宽度需要大于i
continue;
}
if (heights[row][col - i + 1] < i) { // key2:左下角的最大高度需要大于i
continue;
}
out = i;
break;
}
return out;
}
int largest1BorderedSquare(vector<vector<int>>& grid) {
m = grid.size();
n = grid[0].size();
heights = vector<vector<int>>(m, vector<int>(n, 0));
widths = vector<vector<int>>(m, vector<int>(n, 0));
Init(grid); // key1:预处理
int out = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) {
continue;
}
int maxLen = min(heights[i][j], widths[i][j]);
if (maxLen <= out) { // 剪枝
continue;
}
out = max(out, GetMaxLen(i, j, maxLen)); // 寻找以(i,j)为右下角的最大正方形
}
}
return out * out;
}
int m;
int n;
vector<vector<int>> heights;
vector<vector<int>> widths;
};