[LeetCode]85. Maximal Rectangle

来源:互联网 发布:农村淘宝网app下载 编辑:程序博客网 时间:2024/05/29 14:36

https://leetcode.com/problems/maximal-rectangle/

找一个01矩阵中的最大矩形面积


本题较难,应结合Largest Rectangle in Histogram来看,得到解法一

解法一:

把每一行看作直方图的x坐标轴,向上连续的1的个数就是直方图的高,可以解出每一行所代表直方图中矩形的最大面积,最终找到最大面积

public class Solution {    public int maximalRectangle(char[][] matrix) {        if (matrix == null || matrix.length == 0) {            return 0;        }        int res = 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] += 1;                }            }            res = Math.max(res, max(heights));        }        return res;    }    private int max(int[] heights) {        Stack<Integer> stack = new Stack();        int res = 0;        for (int i = 0; i <=heights.length; i++) {            int tmp = i == heights.length ? 0 : heights[i];            while (!stack.isEmpty() && tmp <= heights[stack.peek()]) {                int h = heights[stack.pop()];                int j = stack.isEmpty() ? -1 : stack.peek();                res = Math.max(res, h * (i - j - 1));            }            stack.push(i);        }        return res;    }}





解法二:

对于每一层i,记录每个点matrix[i][j]正上面字符1的连续高度height[j];从左到右,记录高度为height[j]的矩形左边的起始位置left[j];从右到左,记录高度为height[j]的矩形右边的结束为止;那么matrix[i][j]这个点处的最大矩形面积就是(right[j]-left[j])*height[j]。

public class Solution {    public int maximalRectangle(char[][] matrix) {        if (matrix == null || matrix.length == 0) {            return 0;        }        int row = matrix.length;        int col = matrix[0].length;        int res = 0;        int[] heights = new int[col];        int[] left = new int[col];        int[] right = new int[col];        Arrays.fill(right, col);        for (int i = 0; i < row; i++) {            int cur_left = 0;            int cur_right = col;            for (int j = 0; j < col; j++) {                if (matrix[i][j] == '1') {                    heights[j]++;                } else {                    heights[j] = 0;                }            }            for (int j = 0; j < col; j++) {                if (matrix[i][j] == '1') {                    left[j] = Math.max(left[j], cur_left);                } else {                    left[j] = 0;                    cur_left = j + 1;                }            }            for (int j = col - 1; j >= 0; j--) {                if (matrix[i][j] == '1') {                    right[j] = Math.min(cur_right, right[j]);                } else {                    right[j] = col;                    cur_right = j;                }            }            for (int j = 0; j < col; j++) {                res = Math.max(res, heights[j] * (right[j] - left[j]));            }        }        return res;    }}


0 0