Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
题目描述十分简单,就是求给定0,1数组中全1子矩阵的最大1数目。
在 LeetCode_Largest Rectangle in Histogram我们已经可以对直方图的最大矩形面积进行求解,这道题目只需要转换成直方图的矩形面积问题就非常简单了。
我们使用dp[]数组来记录到第i行为止,第j个位置垂直连续包含多少个1(包括matrxi[i][j])。如:
1 0 1 1 0
1 1 0 1 0
0 1 1 1 1
有如下结果:
第1行: dp[] = {1, 0, 1, 1, 0}
第2行: dp[] = {2, 1, 0, 2, 0}
第3行: dp[] = {0, 2, 1, 3, 0}
显然这里的dp数组就是我Largest Rectangle in Histogram中的height数组,因此直接使用直方图最大矩形面积的求解方法就可以。
这样的算法时间复杂度是O(n^2),空间复杂度O(n)
class Solution {
public:
int maximalRectangle(vector<vector<char> > &matrix) {
if(matrix.size() == 0) return 0;
if(matrix[0].size() == 0) return 0;
vector <int> dp(matrix[0].size(),0);
for(int i=0; i<matrix[0].size(); i++){
if(matrix[0][i]=='1'){
dp[i] = 1;
}
}
int res = largestRectangleArea(dp);
for(int i=1; i<matrix.size(); i++){
for(int j=0; j<matrix[0].size();j++){
if(matrix[i][j] == '1'){
dp[j] = dp[j]+1;
}
else{
dp[j] = 0;
}
}
int cur = largestRectangleArea(dp);
if(cur > res){
res = cur;
}
}
return res;
}
private:
int largestRectangleArea(vector<int> &height) {
if(height.size()==0){
return 0;
}
//Create an empty stack. The stack holds indexes of
//vector <int> height.
//The bars stored in stack are always in increasing order
//of their heights
stack <int> s;
int max_area = 0; //Initialize max area
int tp; //To store top of stack
int area_with_top; //to store area with top bar as the smallest bar
//Run through all bars of given histogram
int i = 0;
while(i < height.size()){
//If this bar is higher than the bar on the stack, push it to stack
if(s.empty() || height[s.top()] <= height[i]){
s.push(i++);
}
//If this bar is lower than top of stack, then calculate area
//with stack top as the smallest (or mimimum height) bar. 'i' is
//'right index' for the top and element before top in stack is
//'left index'
else {
tp = s.top(); //store the top index
s.pop(); //pop the top
//Calculate the area with height[tp] stack as smallest bar
area_with_top = height[tp]*(s.empty()?i:i-s.top()-1);
//update max area, if needed
if(max_area < area_with_top){
max_area = area_with_top;
}
}
}
//Now pop the remaining bars from stack and calculate area with
//elements popped bar as the smallest bar
while(s.empty() == false){
tp = s.top();
s.pop();
area_with_top = height[tp]*(s.empty()?i:i-s.top()-1);
if(max_area<area_with_top){
max_area = area_with_top;
}
}
return max_area;
}
};