题意
题解
暴力
若矩阵中存在值为 1 1 1 的点,看做边长为 r r r 的正方形的右下顶点,向下、右、右下方合法位置增 1 1 1;遍历全部元素后,值为 4 4 4 的点即为合法正方形的右下顶点,将所有右下顶点位置赋 1 1 1,代表存在以当前位置为右下顶点的,边长为 r + 1 r+1 r+1 的正方形,其余赋 0 0 0;重复第一步直到不存在可新增边长的正方形。
class Solution {
public:
int di[4] = {0, 0, 1, 1};
int dj[4] = {0, 1, 1, 0};
int n, m;
vector<vector<int>> mat1, mat2;
int solve(){
bool f;
int r = 1;
do{
f = 0;
mat2.assign(n, vector<int> (m, 0));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(mat1[i][j] == 1){
for(int k = 0; k < 4; k++){
int ni = i + di[k], nj = j + dj[k];
if(ni >= 0 && ni < n && nj >= 0 && nj < m){
mat2[ni][nj]++;
}
}
}
}
}
mat1.assign(n, vector<int> (m, 0));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(mat2[i][j] == 4){
// 存在边长更大的正方形
f = 1;
mat1[i][j] = 1;
}
}
}
++r;
}while(f);
--r;
return r * r;
}
int maximalSquare(vector<vector<char>>& matrix) {
if(matrix.size() == 0) return 0;
n = matrix.size(), m = matrix[0].size();
bool f = 0;
mat1.resize(n, vector<int> (m, 0));
for(int i = 0; i < n ; i++){
for(int j = 0; j < m; j++){
if(matrix[i][j] == '1') mat1[i][j] = 1, f = 1;
}
}
if(!f) return 0;
int res = solve();
return res;
}
};
DP
按照暴力的思路, d p [ i ] [ j ] dp[i][j] dp[i][j] 代表位置 ( i , j ) (i,j) (i,j) 为右下顶点的正方形的最大边长
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + 1 dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1 dp[i][j]=min(dp[i−1][j−1],dp[i−1][j],dp[i][j−1])+1
class Solution {
public:
int n, m;
vector<vector<int>> dp;
int maximalSquare(vector<vector<char>>& matrix) {
if((n = matrix.size()) == 0 || (m = matrix[0].size()) == 0) return 0;
int res = 0;
dp.resize(n, vector<int> (m, 0));
for(int i = 0; i < m; i++){
if(matrix[0][i] == '1') res = dp[0][i] = 1;
}
for(int i = 0; i < n; i++){
if(matrix[i][0] == '1') res = dp[i][0] = 1;
}
for(int i = 1; i < n ; i++){
for(int j = 1; j < m; j++){
if(matrix[i][j] == '1'){
dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
res = max(res, dp[i][j]);
}
}
}
return res * res;
}
};