85. Maximal Rectangle
by Botao Xiao
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) ```Java /** 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”]
- we define 3 arrays for each row:
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; } } ```
Reference
Subscribe via RSS