最大正方形
分析
首先说一个暴力解法,首先做一个前缀和然后枚举这个这个正方行的边长。这个解法的复杂度大概是:
∑
i
=
1
n
∑
j
=
1
m
∑
k
=
1
n
1
k
=
>
m
n
∗
l
n
n
\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{k=1}^{n}\frac{1}{k} => mn*lnn
i=1∑nj=1∑mk=1∑nk1=>mn∗lnn
希望我没有算错。这个复杂度有点拉跨,其实考虑dp
dp[i][j]表示已(i,j)为右下角的最大边长,
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
−
1
]
[
j
−
1
]
)
+
1
dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
dp[i][j]=min(dp[i−1][j],dp[i][j−1],dp[i−1][j−1])+1
首先是从这三个方向转移过来应该是没啥疑问,但是为啥去最小呢?其实这里的原因也很显而易见,就是短板效应。我懒得画图了,懂得都懂。
但是这里面有个比较恶心的就是边界问题,为了避免这个问题把数组加一维度
class Solution {
public:
int dp[2000][2000];
int maximalSquare(vector<vector<char>>& matrix) {
if (!matrix.size())return 0;
memset(dp, 0, sizeof(dp));
int n = matrix.size();
int m = matrix[0].size();
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == '1') {
dp[i + 1][j + 1] = min({ dp[i][j],dp[i][j + 1],dp[i + 1][j] }) + 1;
ans = max(ans, dp[i + 1][j + 1]);
}
}
}
return ans * ans;
}
};