整体来看,就是一个二维dp,是这类矩阵问题的一个常用状态设置方法:dp(i,j)
d
p
(
i
,
j
)
的含义是以(i,j)
(
i
,
j
)
为右下角的最大正方形边长
然后递推方程,我们一定是看 dp(i−1,j)
d
p
(
i
−
1
,
j
)
、dp(i,j−1)
d
p
(
i
,
j
−
1
)
以及dp(i−1,j−1)
d
p
(
i
−
1
,
j
−
1
)
了
通过观察矩阵形状,我们不难发现当 dp(i,j−1)≠dp(i−1,j)
d
p
(
i
,
j
−
1
)
≠
d
p
(
i
−
1
,
j
)
时,小的那个正方形决定了(i,j)
(
i
,
j
)
为右下角这个正方形的边长,这时
dp(i,j)=min(dp(i,j−1),dp(i−1,j))+1
d
p
(
i
,
j
)
=
min
(
d
p
(
i
,
j
−
1
)
,
d
p
(
i
−
1
,
j
)
)
+
1
而当 dp(i,j−1)=dp(i−1,j)
d
p
(
i
,
j
−
1
)
=
d
p
(
i
−
1
,
j
)
时,左上角的位置是否为0决定了当前正方形的边长,这时可以用个小trick,不用真去看左上角为0
0
还是1,可以通过dp(i−1,j−1)
d
p
(
i
−
1
,
j
−
1
)
去判断一下(这个小trick意义不大,就是递推形式上更像dp,2333),即
dp(i,j)=dp(i,j−1)+1,ifdp(i−1,j−1)≤dp(i,j−1)dp(i,j)=dp(i,j−1),Otherwise
d
p
(
i
,
j
)
=
d
p
(
i
,
j
−
1
)
+
1
,
i
f
d
p
(
i
−
1
,
j
−
1
)
≤
d
p
(
i
,
j
−
1
)
d
p
(
i
,
j
)
=
d
p
(
i
,
j
−
1
)
,
O
t
h
e
r
w
i
s
e
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.size() == 0)
return0;
int n = matrix.size(), m = matrix[0].size();
vector<vector<int>> a(n, vector<int>(m, 0));
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (matrix[i][j] == '0'){
a[i][j] = 0;
}
else{
if (j == 0){
a[i][j] = 1;
}
else{
a[i][j] += a[i][j - 1] + 1;
}
}
}
}
int ans = 0;
for (int j = 0; j < m; j++){
deque<pair<int, int> > q;
int len = 1;
for (int i = 0; i < n; i++){
while (q.size() && q.back().first > a[i][j]){
q.pop_back();
}
q.push_back(make_pair(a[i][j], i));
if (q.front().first < len){
len = i - q.front().second + 1;
q.pop_front();
}
else {
ans = max(ans, len);
len++;
}
}
}
return ans * ans;
}
};
dp实现
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.size() == 0)
return0;
int n = matrix.size(), m = matrix[0].size();
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
int ans = 0;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (matrix[i-1][j-1] == '0'){
continue;
}
if (dp[i-1][j] == dp[i][j-1]){
dp[i][j] = dp[i-1][j];
if (dp[i-1][j-1] >= dp[i-1][j]){
dp[i][j]++;
}
}
else{
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1;
}
ans = max(ans, dp[i][j]);
}
}
return ans * ans;
}
};