题目要求 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.
输入一个二维char数组,其中1代表一个小正方形,求找到数组中最大的矩形面积。
思路一:用二维数组存储临时值## dp的一个思路就是通过存储换效率。也就是说,我将前序遍历过程中的一些有效值存储下来,以供后序遍历参考。从而省去了许多重复遍历,提高效率。这里我使用两个二维int数组来分别记录到matrix[i][j]为止的最大长度和最大高度。如果matrix[i][j]不是最左侧和最上侧的点,还需要判断其所能构成的最大矩形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public int maximalRectangle (char [][] matrix) { if (matrix.length==0 || matrix[0 ].length==0 ) return 0 ; int row = matrix.length; int column = matrix[0 ].length; int [][] maxRow = new int [row][column]; int [][] maxColumn = new int [row][column]; int maximal = 0 ; for (int i = 0 ; i<row ; i++){ for (int j = 0 ; j<column ; j++){ if (matrix[i][j]=='1' ){ if (i==0 && j==0 ){ maximal = maxRow[i][j] = maxColumn[i][j] = 1 ; }else if (i==0 ){ maxRow[i][j] = maxRow[i][j-1 ] + 1 ; maxColumn[i][j] = 1 ; maximal = Math.max(maxRow[i][j], maximal); }else if (j==0 ){ maxColumn[i][j] = maxColumn[i-1 ][j]+1 ; maxRow[i][j] = 1 ; maximal = Math.max(maxColumn[i][j], maximal); }else { maxRow[i][j] = maxRow[i][j-1 ] + 1 ; maxColumn[i][j] = maxColumn[i-1 ][j]+1 ; int tempMaxColumn = maxRow[i][j]; for (int k = 1 ; k <= maxColumn[i][j] ; k++){ tempMaxColumn = Math.min(maxRow[i-k+1 ][j], tempMaxColumn); if (tempMaxColumn==1 ){ maximal = Math.max(maximal, maxColumn[i][j]); break ; } maximal = Math.max(maximal, tempMaxColumn * k); } } } } } return maximal; }
在该算法上可以实现的简单优化,是将初始的char[][]数组作为记录maxRow的值,再new一个int[]数组记录当前行maxColumn的值,从而减少了一些存储空间的消耗。核心思路不变,在这里就不贴上代码了。
思路二:栈 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public int maximalRectangle2 (char [][] matrix) { if (matrix==null ||matrix.length==0 ||matrix[0 ].length==0 ) return 0 ; int cLen = matrix[0 ].length; int rLen = matrix.length; int [] h = new int [cLen+1 ]; h[cLen]=0 ; int max = 0 ; for (int row=0 ;row<rLen;row++) { Stack<Integer> s = new Stack <Integer>(); for (int i=0 ;i<cLen+1 ;i++) { if (i<cLen) if (matrix[row][i]=='1' ) h[i]+=1 ; else h[i]=0 ; if (s.isEmpty()||h[s.peek()]<=h[i]) s.push(i); else { while (!s.isEmpty()&&h[i]<h[s.peek()]){ int top = s.pop(); int area = h[top]*(s.isEmpty()?i:(i-s.peek()-1 )); if (area>max) max = area; } s.push(i); } } } return max; }