题目:
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 0Return 4.
思路:
这是一道比较明显的动态规划题目(一旦能够进入动态规划的正确轨道,那么感觉拿下这道题目就八九不离十了^_^)。我们定义dp[i][j]表示以(i-1, j-1)为右下边界的最大正方形的边长,那么其值有两种情况:
1)如果matrix[i - 1][j - 1] == 1,那么状态转移方程为:dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;
2)如果matrix[i - 1][j - 1] == 0,那么dp[i][j] = 0。
这种基本实现的时间复杂度是O(m*n),空间复杂度也是O(m*n),其中m和n分别是matrix的长和宽。不过注意到上面的状态转移方程中,dp[i][j]只和它临近的常数个状态有关,所以采用滚动数组,本算法的空间复杂度还可以进一步压缩到O(n)。我前面的动态规划题目中给出了类似的解决方法,这里就不再赘述了。
代码:
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if(matrix.size() == 0 || matrix[0].size() == 0) {
return 0;
}
int row_num = matrix.size(), col_num = matrix[0].size();
int max = 0;
vector<vector<int>> dp(row_num + 1, vector<int>(col_num + 1, 0));
for(int i = 1; i <= row_num; ++i) {
for(int j = 1; j <= col_num; ++j) {
if(matrix[i - 1][j - 1] == '1') {
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i-1][j], dp[i][j - 1])) + 1;
if(dp[i][j] > max) {
max = dp[i][j];
}
}
else {
dp[i][j] = 0;
}
}
}
return max * max;
}
};