我们用DP[i][j][k]来表示以matrix[i][j]为左上顶点的长度为k的区域是否是square,我们可以得到递推公式:
- DP[i][j][k] = true, if DP[i][j][k - 1], DP[i - 1][j][k - 1], DP[i][j - 1][k - 1], DP[i - 1][j - 1][k - 1]均为true
- 否则,DP[i][j][k] = false
假设输入matrix为m * n,时间复杂度O(m * n * min(m , n)),空间复杂度O(m * n * min(m , n)),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int maximalSquare(vector<vector<char>>& matrix) { | |
int m = matrix.size(), n = m? matrix[0].size(): 0, k = min(m, n), res = 0; | |
if(!m || !n)return 0; | |
vector<vector<bool>> dp(m * n, vector<bool>(k + 1, false)); | |
for(int i = 0; i < m * n; ++i) | |
{ | |
dp[i][1] = matrix[i / n][i % n] == '1'; | |
if(dp[i][1])res = max(res, 1); | |
} | |
for(int i = 2; i <= k; ++i) | |
{ | |
for(int a = 0; a <= m - i; ++a) | |
{ | |
for(int b = 0; b <= n - i; ++b) | |
{ | |
int idx = a * n + b; | |
dp[idx][i] = dp[idx][i - 1] && dp[idx + 1][i - 1] && dp[idx + n][i - 1] && dp[idx + 1 + n][i - 1]; | |
if(dp[idx][i])res = max(res, i); | |
} | |
} | |
} | |
return res * res; | |
} | |
}; |
但是很明显这个DP方程效率并不高,如果改变用DP[i][j] = k代表以matrix[i][j]作为右下顶点的square的最大长度为k,我们可以得到效率更高的DP方程,递推公式如下:
- if matrix[i][j] == '1' && DP[i - 1][j] > 0 && DP[i - 1][j - 1] > 0 && DP[i ][j - 1] > 0, DP[i][j] = min(DP[i - 1][j], DP[i - 1][j - 1], DP[i ][j - 1] )
- else if matrix[i][j] == '1', DP[i][j] = 1
- else DP[i][j] = 0
这个地推公式画个图很好理解,就不分析了。时间复杂度O(n * m),空间复杂度O(m * n),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int maximalSquare(vector<vector<char>>& matrix) { | |
int m = matrix.size(), n = m? matrix[0].size(): 0, maxSquare = 0; | |
vector<vector<int>> dp(m, vector<int>(n, 0)); | |
for(int i = 0; i < m; ++i) | |
{ | |
for(int j = 0; j < n; ++j) | |
{ | |
if(matrix[i][j] == '1') | |
{ | |
if(!i || !j) | |
dp[i][j] = 1; | |
else | |
{ | |
if(dp[i - 1][j] > 0 && dp[i][j - 1] > 0 && dp[i - 1][j - 1] > 0) | |
dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1; | |
else | |
dp[i][j] = 1; | |
} | |
maxSquare = max(maxSquare, dp[i][j] * dp[i][j]); | |
} | |
} | |
} | |
return maxSquare; | |
} | |
}; |
空间可以优化到O(n),代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int maximalSquare(vector<vector<char>>& matrix) { | |
int m = matrix.size(), n = m? matrix[0].size(): 0, maxSquare = 0; | |
vector<int> dp(n, 0); | |
for(int i = 0; i < m; ++i) | |
{ | |
int cache = 0; | |
for(int j = 0; j < n; ++j) | |
{ | |
int temp = dp[j]; | |
if(matrix[i][j] == '1') | |
{ | |
if(!i || !j) | |
dp[j] = 1; | |
else | |
{ | |
if(dp[j] > 0 && dp[j - 1] > 0 && cache > 0) | |
dp[j] = min(min(dp[j], dp[j - 1]), cache) + 1; | |
else | |
dp[j] = 1; | |
} | |
maxSquare = max(maxSquare, dp[j] * dp[j]); | |
} | |
else | |
dp[j] = 0; | |
cache = temp; | |
} | |
} | |
return maxSquare; | |
} | |
}; |
No comments:
Post a Comment