- Maximal Rectangle
Given a 2D boolean matrix filled with False and True, find the largest rectangle containing all True and return its area.
Example
Given a matrix:
[
[1, 1, 0, 0, 1],
[0, 1, 0, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1]
]
return 6.
解法1:单调栈+矩阵累加和
构造一个新的矩阵height,值为matrix逐行累加。height的第一行即为matrix第一行,接下来如果height上下两行都>0 (下面一行最多为1,但上面一行可能>1),则将上行的值累加到下行。否则直接将matrix的对应行当下行。
接下来对height的每行求maximalRectangle(),然后求最大值即可。即这题是最大直方图矩形的变种。
代码如下:
class Solution {
public:
/**
* @param matrix: a boolean 2D matrix
* @return: an integer
*/
int maximalRectangle(vector<vector<bool>> &matrix) {
int m = matrix.size();
if (m == 0) return 0;
int n = matrix[0].size();
vector<vector<int>> height(m, vector<int>(n, 0));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if ((i > 0) && (matrix[i][j] > 0) && (height[i - 1][j] > 0)){
height[i][j] = height[i - 1][j] + matrix[i][j];
} else {
height[i][j] = matrix[i][j];
}
}
}
int maxArea = 0;
for (int i = 0; i < m; ++i) {
maxArea = max(maxArea, maximalRectangle(height[i]));
}
return maxArea;
}
private:
int maximalRectangle(vector<int> &nums) {
int len = nums.size();
if (len == 0) return 0;
int maxArea = 0;
vector<int> nums2 = nums;
nums2.push_back(-1);
stack<int> monoIncStack;
for (int i = 0; i <= len; ++i) {
while (!monoIncStack.empty() && (nums2[i] < nums[monoIncStack.top()])) {
int top = monoIncStack.top();
monoIncStack.pop();
int h = nums2[top];
int w = monoIncStack.empty() ? i : i - monoIncStack.top() - 1; //not w = i - top - 1
maxArea = max(maxArea, h * w);
}
monoIncStack.push(i);
}
return maxArea;
}
};
2刷:2维数组可以简化为1维数组
class Solution {
public:
/**
* @param matrix: a boolean 2D matrix
* @return: an integer
*/
int maximalRectangle(vector<vector<bool>> &matrix) {
int m = matrix.size();
if (m == 0) return 0;
int n = matrix[0].size();
int maxArea = 0;
vector<int> height(n, 0);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if ((i > 0) && (matrix[i][j] > 0) && (height[j] > 0)){
height[j] += matrix[i][j];
} else {
height[j] = matrix[i][j];
}
}
maxArea = max(maxArea, maximalRectangle(height));
}
return maxArea;
}
private:
int maximalRectangle(vector<int> &nums) {
int len = nums.size();
if (len == 0) return 0;
int maxArea = 0;
vector<int> nums2 = nums;
nums2.push_back(-1);
stack<int> monoIncStack;
for (int i = 0; i <= len; ++i) {
while (!monoIncStack.empty() && (nums2[i] < nums[monoIncStack.top()])) {
int top = monoIncStack.top();
monoIncStack.pop();
int h = nums2[top];
int w = monoIncStack.empty() ? i : i - monoIncStack.top() - 1; //not w = i - top - 1
maxArea = max(maxArea, h * w);
}
monoIncStack.push(i);
}
return maxArea;
}
};
注意,这题不要跟Leetcode 221 Maximal square 混淆。那题是求最大正方形,这题是求最大矩形。
Leetcode 221 那题要用DP做。
Leetcode 221 Maximal Square
Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.
Example:
Input:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Output: 4
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if(matrix.size() == 0) return 0;
int row = matrix.size();
int col = matrix[0].size();
vector<vector<int>> dp(row+1, vector<int>(col+1, 0));
int maxLen = 0;
for(int i =1; i<=row; i++) {
for(int j =1; j<= col; j++) {
if(matrix[i-1][j-1] == '1') {
dp[i][j] = min(min(dp[i-1][j-1], dp[i-1][j]), dp[i][j-1])+1 ;
maxLen = max(maxLen, dp[i][j]);
}
}
}
return maxLen*maxLen;
}
};