Leetcode1139 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的正方形,初一上手感觉没什么头绪,但联想到之前做过的求最大实心正方形的题目就能感觉到此题的关键在于一个方向中1堆积的数量。
我的解法就是构建两个参数矩阵,分别存每个格点向右向下的1的个数。这样只要对每个点所能延伸的最大正方形进行列举就能找到这个最大的正方形。
以其中一个输入为例:
输入为:
1 1 1
1 1 0
1 1 1
0 1 1
1 1 1
这样构建每个点向右所能延伸的长度的矩形,如下:
3 2 1
2 1 0
3 2 1
0 2 1
3 2 1
向下延伸同理。
此时对于(0,0)这个点来说,向右向下最大延伸长度都为3, 从3逐渐减小,查看是否存在相应的边框正方形即可。
比如当长度为3时,(0,0)向右的顶点为(0,2),而(0,2)这个点的向下延伸为1,小于3,则不成立。
当长度为2时,可以发现这样的正方形是存在的,此时更新结果边长。
每个点都这样经过一轮之后就得到结果了,当然有很多不必要的检查可以直接跳过,比如剩下可能最大的正方形长度已经小于结果值了等。
Code:
class state{//用一个数据结构把两张表合并了 public: int right_1; int down_1; state(int x,int y):right_1(x),down_1(y){} state():right_1(0),down_1(0){} int getmin(){ if(right_1<down_1) return right_1; return down_1; } }; class Solution { public: int largest1BorderedSquare(vector<vector<int>>& grid) { int height = grid.size(); int width = grid[0].size(); int res = 0; vector<vector<state>> state_dict(height,vector<state>(width,state(0,0))); for(int y = 0; y<height; ++y){ for(int x = 0; x<width; ++x){//首先更新数据表 int cur = y; if(y-1 > -1 && state_dict[y-1][x].down_1 != 0){//可以直接得到 state_dict[y][x].down_1 = state_dict[y-1][x].down_1-1; }else{ while(cur<height && grid[cur][x] == 1){ state_dict[y][x].down_1 += 1; ++cur; } } cur = x; if(x-1 > -1 && state_dict[y][x-1].right_1 != 0){ state_dict[y][x].right_1 = state_dict[y][x-1].right_1-1; }else{ while(cur<width && grid[y][cur] == 1){ state_dict[y][x].right_1 += 1; ++cur; } } } } for(int y = 0; y<height; ++y){ if(height-y <= res){//一些边界检查 break; } for(int x = 0; x<width; ++x){ if(width - x<= res){ break; } int maxrange = state_dict[y][x].getmin(); if(maxrange<res){ continue; } for(int range = maxrange; range > res; --range){//判断正方形是否存在 if(state_dict[y][x+range-1].down_1 >= range && state_dict[y+range-1][x].right_1 >= range){ res = range; } } } } return res*res; } };