思路:
动态规划问题
1.设二维数组dp[m][n],其中dp[i][j]表示以坐标(i,j)为正方形右下角元素时的最大正方形的边长。
2.当前点的最大正方形边长为上,左,左上三个点最大正方形边长的最小值+1,也就是从这个点往这三个方向进行延伸,延伸的长度为上,左,左上三个点最大正方形边长的最小值+1。
即核心递推式为:dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1;
3.得到动态规划方程:
如果 matrix[i][j] == 1
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1;
否则
dp[i][j] = 0;
并用一个变量max_width记录下遍历过程中的最大正方形边长,最终返回max_width*max_width为最大正方形面积。
max_width = max(dp[i][j],max_width);
时间复杂度:O(mn)
空间复杂度:O(mn)
m,n为输入矩阵的行列数。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty())
return 0;
int m = matrix.size();
int n = matrix[0].size();
int max_width = 0;
vector<vector<int>> dp(m, vector<int>(n, 0));
for (int i = 0; i < m; ++i) {
dp[i][0] = matrix[i][0]-'0';
max_width = max(max_width, dp[i][0]);
}
for (int j = 1; j < n; ++j) {
dp[0][j] = matrix[0][j] - '0';
max_width = max(max_width, dp[0][j]);
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (matrix[i][j] == '0')
dp[i][j] = 0;
else
{
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1]))+1;
max_width = max(dp[i][j],max_width);
}
}
}
return max_width*max_width;
}
};