[leetcode] 85. 最大矩形

Posted ACBingo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[leetcode] 85. 最大矩形相关的知识,希望对你有一定的参考价值。

85. 最大矩形

解法1:

一个思路就是这个可以看作84. 柱状图中最大的矩形的扩展,这道题的二维矩阵每一层向上都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图,对每个直方图都调用 84. 柱状图中最大的矩形 中的方法,就可以得到最大的矩形面积。

class Solution {
    public int maximalRectangle(char[][] matrix) {
        int m = matrix.length;
        if (m == 0) return 0;
        int n = matrix[0].length;
        if (n == 0) return 0;

        int[] height = new int[n];
        int ans = 0;

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == \'0\') height[j] = 0;
                else if (matrix[i][j] == \'1\') height[j] += 1;
            }
            ans = Math.max(largestRectangleArea(height), ans);
        }
        return ans;
    }

    public int largestRectangleArea(int[] heights) {
        if (heights.length == 0) return 0;
        Stack<Integer> stack = new Stack<>();

        int max = 0;
        for (int i = 0; i < heights.length; i++) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                int tmp = stack.pop();
                // 把当前的tmp木板作为最短木板,看能组成的最大面积是多少
                max = Math.max(max, heights[tmp] * (stack.empty() ? i : i - stack.peek() - 1));
            }
            stack.push(i);
        }

        int tmp = 0;
        int len = heights.length;
        while (!stack.isEmpty()) {
            tmp = stack.pop();
            max = Math.max(max, heights[tmp] * (stack.empty() ? len : len - stack.peek() - 1));
        }

        return max;
    }
}

解法2:

另外一个思路就是,想办法如何很方便的表示出一个矩形。比如说,对于以(i,j)点为右下角的矩形。

大家可以先想暴力思路,实际上大部分的优化思路,都是以暴力思路基础而来的。
暴力思路:枚举(i,j)为一个矩形的右下角,然后以(i,j)为起点,向左、向上看,能组成的最大矩形是什么。时间复杂度为O(n^4)。
仔细观察一下,其实在向左、向上看,能组成的最大矩形是什么这个过程中,是存在重复计算的。也就是说当我们算完点(i,j)后,(i+1,j)点,我们或许只需要看第i+1行就可以了。

所以,我们可否用动态规划来做呢?

有个思路很巧妙:
height数组和上面一样,height表示高,这里的left数组表示左边界是1的位置,right数组表示右边界是1的位置,那么对于任意一行的第j个位置,矩形为(right[j] - left[j]) * height[j]

具体参考:算法学习之动态规划 85. Maximal Rectangle

文章里讲的方法我大概是懂了,其核心思路是从第一行开始一行一行地处理,然后其left与right数组巧妙的保存了上层的状态,使得其能表示出矩阵左边界或者右边界的位置,进而就很方便的表示出了一个矩形了

但是,我觉得我是想不出来这个思路的- -。。非常的巧妙啊

以上是关于[leetcode] 85. 最大矩形的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 85 最大矩形

LeetCode(85):最大矩形

LeetCode85. 最大矩形

LeetCode 85 | 如何从矩阵当中找到数字围成的最大矩形的面积?

LeetCode 85最大矩形

Leetcode No.85 最大矩形(单调栈)