题意:Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.
解法1 ,使用84题的解法,O(m*n)
一行一行处理即可。把当前行及上面的行处理成一个条形图,调用84题解法即可。
int largestRectangleArea(vector<int>& heights) {
stack<int> stk;
int i = 0;
int max_area = 0;
while(i < heights.size()){
if(stk.empty() || heights[stk.top()] <= heights[i])
stk.push(i++);
else{
int tp = stk.top();
stk.pop();
int area = heights[tp] * (stk.empty() ? i : i - stk.top() - 1);
if(area > max_area) max_area = area;
}
}
while(!stk.empty()){
int tp = stk.top();
stk.pop();
int area = heights[tp] * (stk.empty() ? i : i - stk.top() - 1);
if(area > max_area) max_area = area;
}
return max_area;
}
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.empty()) return 0;
int m = matrix.size();
int n = matrix[0].size();
int max_area = 0;
vector<int> histogram;
for(int i = 0; i < m; ++i){
if(i == 0){
for(int j = 0; j < n; ++j)
if(matrix[i][j] == '0') histogram.push_back(0);
else histogram.push_back(1);
}
else{
for(int j = 0; j < n; ++j)
if(matrix[i][j] == '0') histogram[j] = 0;
else histogram[j]++;
}
int area = largestRectangleArea(histogram);
if(area > max_area) max_area = area;
}
return max_area;
}
解法2,DP,
一行一行处理
对于每一行,left从左到右处理,right从右到左处理,
left(i,j) = max( left(i-1,j), cur_left)
right(i,j) = min(right(i-1,j), cur_right)
matrix(i,j) == 1, height(i,j) = height(i-1,j) + 1
matrix(i,j) == 0, height(i,j) = 0area(i,j) = ( right(i,j) - left(i,j) ) * height(i,j)
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.empty()) return 0;
int m = matrix.size();
int n = matrix[0].size();
int max_area = 0;
int left[n], right[n], height[n];
fill_n(left, n, 0);
fill_n(right, n, n);
fill_n(height, n, 0);
for(int i = 0; i < m; ++i){
int cur_left = 0;
int cur_right = n;
for(int j = 0; j < n; ++j)
if(matrix[i][j] == '1') left[j] = max(left[j], cur_left);
else{
cur_left = j + 1;
left[j] = 0;
}
for(int j = n - 1; j >= 0; --j)
if(matrix[i][j] == '1') right[j] = min(right[j], cur_right);
else{
cur_right = j;
right[j] = n;
}
for(int j = 0; j < n; ++j)
if(matrix[i][j] == '1') height[j] = height[j] + 1;
else height[j] = 0;
for(int j = 0; j < n; ++j)
if((right[j] - left[j]) * height[j] > max_area)
max_area = (right[j] - left[j]) * height[j];
}
return max_area;
}
};