Leetcode221. Maximal Square
Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.
Example:
Input:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Output: 4
Dynamic Programming
Can be considered a square of the number 3 is a square of 2 stacked obtained, which is the core of the state transition equation solving the problem.
First, the definition states:
With dp[i][j]
expressed matrix[i][j]
as the maximum length of the bottom right side of the square.
Second, the state transition equation:
Left, top, top left to take the smallest of the three, plus 1.
- Figure 1: is limited to the upper left of the 0
- Figure 2: is limited to the upper side 0
- Figure 3: is limited to the left of the 0
- Digital said: this is the largest side the lower right corner of the square long
- Yellow indicates:? Lower right corner of the grid as a square area
which is:dp[i][j] = Min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1
Third, the initialization and output
Initializing a first row and first column of dp[i][j] = matrix[i][j] - 0
output d[i,j]
. However, in order to avoid side determination process, the left most plus one f[i][0] = 0
, plus one line on the left edge f[0][j] = 0
.
public int maximalSquare(char[][] matrix) {
int rows = matrix.length;
if (rows == 0) {
return 0;
}
int cols = matrix[0].length;
int[][] dp = new int[rows + 1][cols + 1];
int maxSide = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= cols; j++) {
//因为多申请了一行一列,所以这里下标要减 1
if (matrix[i - 1][j - 1] == '0') {
dp[i][j] = 0;
} else {
dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i][j - 1], dp[i - 1][j - 1])) + 1;
maxSide = Math.max(dp[i][j], maxSide);
}
}
}
return maxSide * maxSide;
}
State compression
Because when updating the current row, only use the information of the previous row, before the row will not need again, so we can use one-dimensional array, no two-dimensional matrix.
public int maximalSquare(char[][] matrix) {
int rows = matrix.length;
if (rows == 0) {
return 0;
}
int cols = matrix[0].length;
int[] dp = new int[cols + 1];
int maxSide = 0;
int pre = 0;//保存左上角的值
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= cols; j++) {
int temp = dp[j];
if (matrix[i - 1][j - 1] == '0') {
dp[j] = 0;
} else {
dp[j] = Math.min(dp[j - 1], Math.min(dp[j], pre)) + 1;
maxSide = Math.max(dp[j], maxSide);
}
pre = temp;
}
}
return maxSide * maxSide;
}