- Maximal Square
Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing all 1’s and return its area.
Example
Example 1:
Input:
[
[1, 0, 1, 0, 0],
[1, 0, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 0, 0, 1, 0]
]
Output: 4
Example 2:
Input:
[
[0, 0, 0],
[1, 1, 1]
]
Output: 1
思路:
DP。注意这题跟LintCode 510: Maximal Rectangle 看起来很像,但那题是求矩形,正解是单调递增栈。这题可能也可以用单调递增栈做,下次再试。
解法1:
用了3重循环。复杂度太高。
class Solution {
public:
/**
* @param matrix: a matrix of 0 and 1
* @return: an integer
*/
int maxSquare(vector<vector<int>> &matrix) {
int nRow = matrix.size();
int nCol = matrix[0].size();
if (nRow == 0) return 0;
vector<vector<int>> dp(nRow, vector<int>(nCol, 0));
int maxLen = 0;
for (int i = 0; i < nRow; ++i) {
if (matrix[i][0] == 1) {
dp[i][0] = 1;
maxLen = 1;
}
}
for (int j = 0; j < nCol; ++j) {
if (matrix[0][j] == 1) {
dp[0][j] = 1;
maxLen = 1;
}
}
for (int i = 1; i < nRow; ++i) {
for (int j = 1; j < nCol; ++j) {
if (matrix[i][j] == 0) continue;
bool qualify = true;
int len = dp[i - 1][j - 1];
for (int k = j - 1; k >= j - len; --k) {
if (matrix[i][k] == 0) {
qualify = false;
break;
} else {
for (int k = i - 1; k >= i - len; --k) {
if (matrix[k][j] == 0) {
qualify = false;
break;
}
}
}
}
if (qualify) {
dp[i][j] = dp[i - 1][j - 1] + 1;
maxLen = max(maxLen, dp[i][j]);
}
}
}
return maxLen * maxLen;
}
};
解法2:
采用 dp[i][j] = min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1;
class Solution {
public:
/**
* @param matrix: a matrix of 0 and 1
* @return: an integer
*/
int maxSquare(vector<vector<int>> &matrix) {
int nRow = matrix.size();
int nCol = matrix[0].size();
if (nRow == 0) return 0;
vector<vector<int>> dp(nRow, vector<int>(nCol, 0));
int maxLen = 0;
for (int i = 0; i < nRow; ++i) {
if (matrix[i][0] == 1) {
dp[i][0] = 1;
maxLen = 1;
}
}
for (int j = 0; j < nCol; ++j) {
if (matrix[0][j] == 1) {
dp[0][j] = 1;
maxLen = 1;
}
}
for (int i = 1; i < nRow; ++i) {
for (int j = 1; j < nCol; ++j) {
if (matrix[i][j] == 0) continue;
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1;
maxLen = max(maxLen, dp[i][j]);
}
}
return maxLen * maxLen;
}
};
采用滚动数组优化: 空间复杂度优化到O(n)。
class Solution {
public:
/**
* @param matrix: a matrix of 0 and 1
* @return: an integer
*/
int maxSquare(vector<vector<int>> &matrix) {
int m = matrix.size();
if (m == 0) return 0;
int n = matrix[0].size();
//dp[i][j]: the len of the max square that has right-bottom corner at matrix[i][j]
vector<vector<int>> dp(2, vector<int>(n + 1, 0));
int maxLen = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (matrix[i - 1][j - 1]) {
dp[i % 2][j] = min(dp[(i - 1) % 2][j - 1], min(dp[(i - 1) % 2][j], dp[i % 2][j - 1])) + 1;
maxLen = max(maxLen, dp[i % 2][j]);
} else {
dp[i % 2][j] = 0; //注意!如果采用滚动数组,这一行必须加上,不然,第i%2行这里可能没有更新,会用之前(i-2)%2行的内容。
}
}
}
return maxLen * maxLen;
}
};
注意:这里是求最大正方形,可以用DP。如果是求最大矩形,要用单调栈的方法解决。