LeetCode_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.

题目描述十分简单,就是求给定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;
    } 
};


你可能感兴趣的:(LeetCode_Maximal Rectangle)