Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
O(N^3)
class Solution {
public:
int maximalRectangle(vector<vector<char> > &matrix) {
//check constraint
int x = matrix.size();
if(0 == x) return 0;
int y = matrix[0].size();
if(0 == y) return 0;
vector<vector<int> > result(x, vector<int>(y));
for(int i = 0; i < x; ++i)
for(int j = 0; j < y; ++j)
result[i][j] = '0' == matrix[i][j]? 0: 1;
int ret = 0;
//transform the matrix line by line. O(N^2)
//matrix[i][j] is number of consecutive 1s counting upward
for(int i = 1; i < x; ++i)
for(int j = 0; j < y; ++j)
result[i][j] += ((0 == result[i][j])? 0: result[i-1][j]);
//for each line
for(int i = 0; i < x; ++i)
{
int maxHeight = result[i][0];
//for each column, keep the min height, calculate the sum
for(int start = 0; start < y; ++start)
{
int maxHeight = result[i][start];
for(int end = start; end < y; ++end)
{
//maxHeight = min(maxHeight, matrix[i][end]);
maxHeight = min(maxHeight, result[i][end]);
ret = max(ret, maxHeight*(end - start + 1));
}
}
}
return ret;
}
};
O(N^2)
class Solution {
public:
int maximalRectangle(vector<vector<char> > &matrix) {
int x = matrix.size();
if(0 == x) return 0;
int y = matrix[0].size();
if(0 == y) return 0;
vector<vector<int> > result(x, vector<int>(y));
for(int i = 0; i < x; ++i)
for(int j = 0; j < y; ++j)
result[i][j] = '0' == matrix[i][j]? 0: 1;
for(int i = 1; i < x; ++i)
for(int j = 0; j < y; ++j)
result[i][j] += 0 == result[i][j]? 0: result[i-1][j];
int ret = 0;
for(int i = 0; i < x; ++i)
ret = max(ret, maxArea(result[i]));
return ret;
}
int maxArea(vector<int>& line)
{
stack<int> st;
vector<int> leftLimit(line.size());
for(int i = 0; i < line.size(); ++i)
{
while(!st.empty())
{
if(line[st.top()] >= line[i])
st.pop();
else
break;
}
leftLimit[i] = st.empty()? -1: st.top();
st.push(i);
}
while(!st.empty()) st.pop();
vector<int> rightLimit(line.size());
for(int i = line.size() - 1; i >= 0; --i)
{
while(!st.empty())
{
if(line[st.top()] >= line[i])
st.pop();
else
break;
}
rightLimit[i] = st.empty()? line.size(): st.top();
st.push(i);
}
int ret = 0;
for(int i = 0; i < line.size(); ++i)
ret = max(ret, line[i]*(rightLimit[i] - leftLimit[i] - 1));
return ret;
}
};