Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
--------------------------------------------
方法1:O(m * n) 解法来自google,借用了上一题Largest Rectangle Area的代码
将每一行都看做x轴,在每一个列上的连续1的个数则为当前列的y值,计算出当前行的最大矩形面积
class Solution {
public:
// from the question Largest Rectangle Area
int largestRectangleArea(vector<int> &height) {
stack<int> st;
int largest = 0;
height.push_back(0);
for (int i = 0; i < height.size(); i++) {
if (st.empty() || height[i] >= height[st.top()]) {
st.push(i);
}else {
int topBar = st.top();
st.pop();
if (st.empty()) {
largest = max(largest,height[topBar] * i);
}else {
largest = max(largest,height[topBar] * (i - st.top() - 1));
}
i--;
}
}
return largest;
}
int maximalRectangle(vector<vector<char> > &matrix) {
if (matrix.size() == 0) return 0;
vector<int> heights(matrix[0].size(),0);
int largest = 0;
for (int row = 0; row < matrix.size(); row++) {
for (int col = 0; col < matrix[0].size(); col++) {
if (matrix[row][col] == '1') {
heights[col]++;
}else {
heights[col] = 0;
}
}
largest = max(largest, largestRectangleArea(heights));
}
return largest;
}
};
方法2:O(m * n * m)
dp[i][j]存的是以(i,j)为起点往右,在该行上连续的1的个数
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int m = matrix.size();
if (m == 0) return 0;
int n = matrix[0].size();
vector<vector<int>> dp(m,vector<int>(n + 1,0));
for (int i = 0; i < m; i++) {
for (int j = n - 1; j >= 0; j--) {
if (matrix[i][j] == '1') {
dp[i][j] = dp[i][j + 1] + 1;
}
}
}
int largest = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int width = dp[i][j];
for (int k = i; k < m && width > 0; k++) {
width = min(dp[k][j],width);
largest = max(largest,width * (k - i + 1));
}
}
}
return largest;
}
};
方法3:COME_BACK
height[i]是在(i, j)上1的高度,如果matrix[i][j] = 0,则height[i] = 0
left[i]是底边包含(i, j),高度为height[i]矩阵的最左边的index,right[i]类似
(找个例子,走一边就信服了)
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int m = matrix.size();
if (m == 0) return 0;
int n = matrix[0].size();
vector<int> left(n,0);
vector<int> right(n,n - 1);
vector<int> height(n,0);
int largest = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '1') {
height[j]++;
}else {
height[j] = 0;
}
}
int furLeft = 0;
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '1') {
left[j] = max(furLeft,left[j]);
}else {
furLeft = j + 1;
left[j] = 0;
}
}
int furRight = n - 1;
for (int j = n - 1; j >= 0; j--) {
if (matrix[i][j] == '1') {
right[j] = min(furRight,right[j]);
}else {
furRight = j - 1;
right[j] = n - 1;
}
}
for (int j = 0; j < n; j++) {
largest = max(largest,height[j] * (right[j] - left[j] + 1));
}
}
return largest;
}
};

No comments:
Post a Comment