leetcode85 - Maximal Rectangle - hard
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
Iterative的largest rectangle in histogram.
思路:一层一层遍历,到i层时,第i层是1的位置可以向上延伸所有连续的1作为一个直方条条,按这样的规律可以把matrix[0:i][:]看做一个直方图,然后去统计当前情况下的最大rectangle,得到答案后去打擂台。所有层遍历完了,答案就出来了。
直方图的储存:用int[] heights[colLength]来储存,更新的方法是,扫matrix里新的一行时,如果看到’0’就清空heights[j],如果看到’1’就让heights[j]++。
解释计算直方图里的清空操作:直方条的定义是底部非空向上生长。因为histogram问题里能用stack解决的原因就是,所有直方图最底部开始都是非空的,那么算面积是可以只在意顶上高到哪里,不用担心底部有没有悬空,从而记录高度即可。如果你把matrix的局部转化成直方图的时候看到上面有1但底部是0,那这一列都不合格直方条的定义了。上面的1不用担心,你之前遍历到前面那行的时候算过了。
相关题目:Largest Rectangle in Histogram。 https://www.cnblogs.com/jasminemzy/p/9764297.html
实现:
class Solution { public int maximalRectangle(char[][] matrix) { // invalid input. if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return 0; } int ans = 0; int[] heights = new int[matrix[0].length]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { if (matrix[i][j] == '0') { heights[j] = 0; } else { heights[j]++; } } ans = Math.max(ans, maxRecInHistogram(heights)); } return ans; } private int maxRecInHistogram(int[] heights) { int ans = 0; Stack<Integer> stack = new Stack<>(); for (int i = 0; i <= heights.length; i++) { while (!stack.isEmpty() && (i == heights.length || heights[i] < heights[stack.peek()])) { int height = heights[stack.pop()]; int width = stack.isEmpty() ? i : i - stack.peek() - 1; ans = Math.max(ans, height * width); } stack.push(i); } return ans; } }