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; } };