一、题目描述
题目链接:https://leetcode-cn.com/problems/largest-1-bordered-square/
二、题目分析
本题可以使用动态规划的方法解决。
我们可以定义两个二维数组dp_up,dp_left,代表当前位置向左延申的最大长度,向上延申的最大长度,建立好这两个数组之后,我们对于每一个grid为1的位置i,j进行如下操作:
1、去dp_up和dp_left的较小值作为可能的最大正方形边len。
2、判断dp_up[i-len+1][j],dp_left[i][j-len+1]是否大于等于len,若小于构不成正方形,将len减一,重复本次操作直到符合要求。
3、通过上一步操作我们得到了当前i,j位置能构成的最大正方形,遍历每一个位置,找到最大值。
三、代码
public int largest1BorderedSquare(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp_up = new int[m][n];
int[][] dp_left = new int[m][n];
for (int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++) {
if (i == 0) {
dp_up[i][j] = grid[i][j];
} else {
dp_up[i][j] = grid[i][j] == 1?(dp_up[i-1][j] + 1):0;
}
if (j == 0) {
dp_left[i][j] = grid[i][j];
} else {
dp_left[i][j] = grid[i][j] == 1?(dp_left[i][j-1] + 1):0;
}
}
}
int max = 0;
for (int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++ ) {
if (grid[i][j] == 1) {
int len = Math.min(dp_up[i][j],dp_left[i][j]);
while(dp_up[i][j - len + 1] < len || dp_left[i - len + 1][j] < len){
len--;
}
max = Math.max(max,len*len);
}
}
}
return max;
}