Skip to content

Latest commit

 

History

History
executable file
·
195 lines (183 loc) · 5.84 KB

85. Maximal Rectangle.md

File metadata and controls

executable file
·
195 lines (183 loc) · 5.84 KB

85. Maximal Rectangle

Question

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

Example:

Input:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
Output: 6

Thinking:

  • Method 1: Use the method of Monostack as question 84: 84. Largest Rectangle in Histogram
    • we use a height array to save the historgram.
    • if current value is 1, we increase the value saved in that index.
    • if current value is 0, we set the value to 0.
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
        int res = 0;
        int[] height = new int[matrix[0].length + 1];
        for(int row = 0; row < matrix.length; row++){
            for(int i = 0; i < matrix[0].length; i++){
                if(matrix[row][i] == '1') height[i]++;
                else height[i] = 0;
            }
            Stack<Integer> stack = new Stack<>();
            for(int j = 0; j <= matrix[0].length; j++){
                while(!stack.isEmpty() && height[j] < height[stack.peek()]){
                    int h = height[stack.pop()];
                    int index = stack.isEmpty() ? -1: stack.peek();
                    res = Math.max(res, h * (j - index - 1));
                }
                stack.push(j);
            }
        }
        return res;
    }
}
  • Method 2: dp
    • we define 3 arrays for each row:
      • left(save the first index of 1 in current row, still need to compare with previous value), initial value is 0.
      • right(save the last index of 1 in current row, need to compare with previous value), initialized with len.
      • height(record the height as historgram)
      • area = height * (right - left)
/**
Example:
          0   1   2   3   4
row0    ["1","0","1","0","0"],
row1    ["1","0","1","1","1"],
row2    ["1","1","1","1","1"],
row3    ["1","0","0","1","0"]

height[]: height array saves the historgram for current row.
row0    [1,0,1,0,0],
row1    [2,0,2,1,1],
row2    [3,1,3,2,2],
row3    [4,0,0,3,0]

left[]: left array saves the first index in current row and we need to compare it with the previous row left array.
row0    [0,0,2,0,0],
row1    [0,0,2,2,2],
row2    [0,0,2,2,2],
row3    [0,0,0,3,0]

right[]: right array saves the last index in current row(need to compare it with the previous row right array.)
row0    [1,5,3,5,5],
row1    [1,5,3,5,5],
row2    [1,5,3,5,5],
row3    [1,5,5,4,5]
*/
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
        int res = 0, len = matrix[0].length;
        int[] left = new int[len];
        int[] right = new int[len];
        int[] height = new int[len];
        for(int i = 0; i < len; i++) right[i] = len;
        for(int row = 0; row < matrix.length; row++){
            int cur_left = 0, cur_right = len;
            for(int i = 0; i < len; i++){
                if(matrix[row][i] == '0') height[i] = 0;
                else height[i]++;
            }
            for(int i = 0; i < len; i++){
                if(matrix[row][i] == '1'){
                    left[i] = Math.max(left[i], cur_left);
                }else{
                    cur_left = i + 1;
                    left[i] = 0;
                }
            }
            for(int i = len - 1; i >= 0; i--){
                if(matrix[row][i] == '1'){
                    right[i] = Math.min(right[i], cur_right);
                }else{
                    cur_right = i;
                    right[i] = len;
                }
            }
            for(int i = 0; i < len; i++){
                res = Math.max(res, height[i] * (right[i] - left[i]));
            }
        }
        return res;
    }
}

Second Time

  • Method 1: Stack

     class Solution {
     	public int maximalRectangle(char[][] matrix) {
     		if(matrix.length == 0 || matrix[0].length == 0) return 0;
     		int height = matrix.length, width = matrix[0].length;
     		int[] dp = new int[width];
     		int res = 0;
     		for(int i = 0; i < height; i++){
     			for(int j = 0; j < width; j++){
     				if(matrix[i][j] == '1') dp[j]++;
     				else dp[j] = 0;
     			}
     			Stack<Integer> stack = new Stack<>();
     			for(int c = 0; c <= width; c++){
     				int hh = c == width ? 0: dp[c];
     				while(!stack.isEmpty() && hh < dp[stack.peek()]){
     					int h = dp[stack.pop()];
     					int index = stack.isEmpty() ? -1: stack.peek();
     					int area = h * (c - index - 1);
     					res = Math.max(res, area);
     				}
     				stack.push(c);
     			}
     		}
     		return res;
     	}
     }
  • Method 2: dp

     class Solution {
     	public int maximalRectangle(char[][] matrix) {
     		if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
     		int h = matrix.length, width = matrix[0].length;
     		int[] height = new int[width];
     		int[] left = new int[width];
     		int[] right = new int[width];
     		Arrays.fill(right, width);
     		int res = 0;
     		for(int i = 0; i < h; i++){
     			int curLeft = 0, curRight = width;
     			for(int j = 0; j < width; j++){ // Calculate the height array
     				if(matrix[i][j] == '1') height[j]++;
     				else   height[j] = 0;
     			}
     			for(int j = 0; j < width; j++){
     				if(matrix[i][j] == '1') left[j] = Math.max(curLeft, left[j]);
     				else{
     					left[j] = 0;
     					curLeft = j + 1;
     				}
     			}
     			for(int j = width - 1; j >= 0; j--){
     				if(matrix[i][j] == '1') right[j] = Math.min(curRight, right[j]);
     				else{
     					right[j] = width;
     					curRight = j;
     				}
     			}
     			for(int j = 0; j < width; j++){
     				res = Math.max(res, height[j] * (right[j] - left[j]));
     			}
     		}
     		return res;
     	}
     }

Reference

  1. Leetcode : 85. Maximal Rectangle 讲解