解法一: 时间复杂度 O(nm logm),空间O(m)
将二维化为一维。累计1的高度,在每次累计时,求最值。
转化为一维后。用两个数组,分别存放当下标为j时,大于等于当前高度的最左的下标值,以及
大于等于当前高度的最右的下标值。
/**
* @author johnsondu
* @problem Maximal Square
* @time O(nm logm)
* @space O(n)
* @url https://leetcode.com/problems/maximal-square/
* @strategy dynamic programs.
* @status Accepted, runtime beats 18.90% of cpp submissions. 16ms
* @time 15:25, Nov 4th 2015
*/
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int row = matrix.size();
if(row < 1) return 0;
int col = matrix[0].size();
int ans = 0;
vector<int> dp(col+2, 0);
vector<int> lidx(col+1, 0);
vector<int> ridx(col+1, 0);
dp[0] = -1;
dp[col + 1] = col+1;
for(int i = 0; i < row; i ++) {
// 将二维,转化为一维,每次累计高度。转换成
// hdu 1506的做法。
for(int j = 0; j < col; j ++) {
if(matrix[i][j] == '1') dp[j+1] = dp[j+1] + 1;
else dp[j+1] = 0;
}
for(int j = 1; j <= col; j ++) lidx[j] = ridx[j] = j;
// 找到当前每个下标的至少和当前高度持平的最左下标值
for(int j = 1; j <= col; j ++) {
// 如果当前高度小于等于t时的当前高度,那么
// 当前高度一定也小于等于下标t的最左的大于等于下标t的高度。
int t = j-1;
while(dp[j] <= dp[t] && t > 0) {
t = lidx[t];
}
lidx[j] = t;
}
// 找到当前每个下标的至少和当前高度持平的最右下标值
for(int j = col; j > 0; j --) {
// 同理
int t = j+1;
while(dp[j] <= dp[t] && t <= col) {
t = ridx[t];
}
ridx[j] = t;
}
// 求最大值
for(int j = 1; j <= col; j ++) {
ans = max(ans, min(ridx[j] - lidx[j] - 1, dp[j]));
}
}
return ans * ans;
}
};解法二: 时间复杂度O(nm), 空间复杂度O(nm)
解法如下:
1) Construct a sum matrix S[R][C] for the given M[R][C].
a) Copy first row and first columns as it is from M[][] to S[][]
b) For other entries, use following expressions to construct S[][]
If M[i][j] is 1 then
S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1
Else /*If M[i][j] is 0*/
S[i][j] = 0
2) Find the maximum entry in S[R][C]
3) Using the value and coordinates of maximum entry in S[i], print
sub-matrix of M[][]/**
* @author johnsondu
* @problem Maximal Square
* @time O(nm)
* @space O(nm)
* @url https://leetcode.com/problems/maximal-square/
* @strategy dynamic programs.
* @status Accepted, runtime beats 30.20% of cpp submissions. 12ms
* @time 15:55, Nov 4th 2015
*/
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int row = matrix.size();
if(row < 1) return 0;
int col = matrix[0].size();
int ans = 0;
vector<vector<int>> dp(row, vector<int>(col, 0));
for(int i = 0; i < row; i ++)
if(matrix[i][0] == '1') dp[i][0] = 1;
for(int i = 0; i < col; i ++)
if(matrix[0][i] == '1') dp[0][i] = 1;
for(int i = 1; i < row; i ++)
for(int j = 1; j < col; j ++) {
if(matrix[i][j] == '1')
dp[i][j] = min(min(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1;
else dp[i][j] = 0;
}
for(int i = 0; i < row; i ++)
for(int j = 0; j < col; j ++)
ans = max(ans, dp[i][j]);
return ans * ans;
}
};
本文介绍了两种解决最大正方形问题的方法,一种时间复杂度为O(nmlogm),空间复杂度为O(m),另一种时间复杂度为O(nm),空间复杂度为O(nm)。方法一通过一维化和寻找最左最右下标实现,方法二使用动态规划构建求解矩阵。
471

被折叠的 条评论
为什么被折叠?



