Given a 2D matrix of 0s and 1s, find maximum size rectangle of all 1s in this matrix.
Brute force solution is very inefficient.
A better solution is to convert this problem to multiple different Largest Rectangle in Histogram calculations and
uses dynamic programming to avoid constructing each new histogram from scratch.
Algorithm: O(m * n) runtime, O(min(m, n)) space
1. construct a 1D histogram array of length min(m, n), with all heights initialized to 0.
2. for each new row/col, construct a new histogram by the following rule.
a. if a cell is 0, then its corresponding histogram height is 0.
b. if a cell is 1, add 1 to the previous corrsponding histogram height.
3. calculate the max rectangle area in each new histogram and return the max of all these max rectangle areas.
1 import java.util.Stack; 2 3 public class MaxRectangle { 4 public static int getMaxRecArea(int[][] matrix) { 5 if(matrix == null || matrix.length == 0 || matrix[0].length == 0) { 6 return 0; 7 } 8 int max = 0; 9 int histogramLen = Math.min(matrix.length, matrix[0].length); 10 int histogramIter = Math.max(matrix.length, matrix[0].length); 11 int[] heights = new int[histogramLen]; 12 for(int i = 0; i < histogramIter; i++){ 13 for(int j = 0; j < histogramLen; j++) { 14 int currCell = histogramLen == matrix[0].length ? matrix[i][j] : matrix[j][i]; 15 if(currCell != 0) { 16 heights[j] += currCell; 17 } 18 else { 19 heights[j] = 0; 20 } 21 } 22 max = Math.max(max, largestRectangleArea(heights)); 23 } 24 return max; 25 } 26 public static int largestRectangleArea(int[] height) { 27 if(height == null || height.length == 0){ 28 return 0; 29 } 30 Stack<Integer> idxStack = new Stack<Integer>(); 31 int currIdx = 0; int area = 0; int maxArea = 0; 32 while(currIdx < height.length){ 33 if(idxStack.isEmpty() || height[currIdx] >= height[idxStack.peek()]){ 34 idxStack.push(currIdx); 35 currIdx++; 36 } 37 else{ 38 int top = idxStack.pop(); 39 int leftBoundIdx = idxStack.isEmpty() == true ? -1 : idxStack.peek(); 40 int rightBoundIdx = currIdx - 1; 41 area = height[top] * (rightBoundIdx - leftBoundIdx); 42 maxArea = Math.max(maxArea, area); 43 } 44 } 45 while(!idxStack.isEmpty()){ 46 int top = idxStack.pop(); 47 int leftBoundIdx = idxStack.isEmpty() == true ? -1 : idxStack.peek(); 48 int rightBoundIdx = currIdx - 1; 49 area = height[top] * (rightBoundIdx - leftBoundIdx); 50 maxArea = Math.max(maxArea, area); 51 } 52 return maxArea; 53 } 54 public static void main(String[] args) { 55 int[][] matrix1 = {{1,1,0,0,1}, {0,1,0,0,1},{0,0,1,1,1},{0,0,1,1,1},{0,0,0,0,1}}; 56 int[][] matrix2 = {{1,0,0,1,1,1},{1,0,1,1,0,1},{0,1,1,1,1,1},{0,0,1,1,1,1}}; 57 System.out.println(getMaxRecArea(matrix1)); 58 System.out.println(getMaxRecArea(matrix2)); 59 } 60 }
Related Problems