我们在来看一道DP问题,
原题是这样的:
Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
来求出,这个 0
1
组成的矩形里面的最大的由1
组成的正方形的面积。
图示给出的,里面显然最大的面积是4
一般自己看到这种题目的时候,第一感觉是暴力破解,当然最后肯定是不能通过的,既然leetcode把题目归类到了DP问题,那么肯定是需要写出类状态转移方程的。
dp[i][j] = ??
先来分析一下,矩形的第一行,毫无疑问, dp[0][i] = matrix[0][i]
,因为他只有一行,如果是1的话,只能自己和自己组成正方形,面积就是1;
那么,最左边的一列呢。
dp[j][0] = matrix[j][0],
原因如上。。。。。
比较复杂一点的是 i > 0 && j > 0
我们又该如何分析呢?
思路是 如果一个 dp[i][j] == '1' 而且 i > 0 j > 0
, 那么他的状态就需要由 dp[i - 1][j - 1], dp[i][j - 1], dp[i][j - 1]来共同决定。仔细想一下。不就是dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j])) + 1;
吗?
那么按照这种想法写出代码即可AC。 have a good time.
// let's solve the problem using DP
public static int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0) {
return 0;
}
int max = Integer.MIN_VALUE;
int rows = matrix.length;
int cols = matrix[0].length;
int[][] dp = new int[rows][cols];
// topRow
for (int i = 0; i < cols; i++) {
dp[0][i] = matrix[0][i] - '0';
max = Math.max(max, dp[0][i]);
}
//leftCol
for (int j = 0; j < rows; j++) {
dp[j][0] = matrix[j][0] - '0';
max = Math.max(max, dp[j][0]);
}
// i > 0 && j > 0
for (int i = 1; i < rows; i++) {
for (int j = 1; j < cols; j++) {
if (matrix[i][j] == '1') {
dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j])) + 1;
max = Math.max(max, dp[i][j]);
}
}
}
return max*max;
}