85. Maximal Rectangle

Problem statement:

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.

Solution one:

This is 2D dimension of 84. Largest Rectangle in Histogram, we could write a single function and call this function after updating the height of each row.

For the height in each row

height[j] = (matrix[i][j] == '1' ? height[j] + 1 : 0);

Since height only depends on it`s value and height[i - 1][j], we just one one dimension and update it in each row. This is a dynamic programming philosophy.

The time complexity is O(n * n).

class Solution {
public:
    int maximalRectangle(vector<vector<char>> &matrix) {
        if(matrix.empty()){
            return 0;
        }
        int row = matrix.size();
        int col = matrix[0].size();
        int max_area = 0;
        vector<int> heights(col, 0);
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                heights[j] = (matrix[i][j] == '1' ? heights[j] + 1 : 0);
            }
            max_area = max(max_area, largestRectangleArea(heights));
        }
        return max_area;
    }
    
private:
    int largestRectangleArea(vector<int>& heights) {
        int max_area = 0;
        for(int i = 0; i < heights.size(); i++){
            if(i + 1 < heights.size() && heights[i] <= heights[i + 1]){
                continue;
            } else {
                // find a local maximum value
                // loop back to update max area
                int min_height = INT_MAX;
                int cur_area = 0;
                // loop back to find the update the max area
                for(int j = i; j >= 0; j--){
                    min_height = min(min_height, heights[j]);
                    max_area = max(max_area, min_height * (i - j + 1));
                }
            }
            
        }
        return max_area;
    }
};

Solution two:
This solution is top ratted in leetcode discussion section. It also uses dynamic programming, keeps three array, left[n], right[n], height[n] to record the most left boundary, right boundary, and height of each element in a row. The max area based on current element is (right - left) * height.

The time complexity is O(n * n).

class Solution {
public:
    int maximalRectangle(vector<vector<char>> &matrix) {
        if(matrix.empty()){
            return 0;
        }
        int row = matrix.size();
        int col = matrix[0].size();
        vector<int> left(col, 0);
        vector<int> right(col, col); 
        vector<int> height(col, 0);
        int max_area = 0;
        
        for(int i = 0; i < row; i++){
            // update the left boundary
            int cur_left = 0;
            for(int j = 0; j < col; j++){
                if(matrix[i][j] == '1'){
                    left[j] = max(left[j], cur_left);
                } else {
                    left[j] = 0;
                    cur_left = j + 1;
                }
            }
            // update the right boundary
            int cur_right = col;
            for(int j = col - 1; j >= 0; j--){
                if(matrix[i][j] == '1'){
                    right[j] = min(right[j], cur_right);
                } else {
                    right[j] = col;
                    cur_right = j;
                }
            }
            // update the height and max area
            for(int j = 0; j < col; j++){
                height[j] = (matrix[i][j] == '1' ? height[j] + 1 : 0);
                max_area = max(max_area, (right[j] - left[j]) * height[j]);
            }
        }
        return max_area;
    }
};
原文地址:https://www.cnblogs.com/wdw828/p/6848463.html