• 最大的矩形面积 Maximal Rectangle


    2018-09-15 10:23:44

    一、Largest Rectangle in Histogram

    在求解最大的矩形面积之前,我们先讨论一条最大直方图面积的问题。

    问题描述:

    问题求解:

    解法一、朴素解法,O(n ^ 2)。

    解决的思路就是遍历一遍,如果当前的数比后一个数要小,那么当前的额数字肯定不可能是最大面积的右边界,遍历下一个数;

    如果当前数比后一个大,那么假设当前的为右边界,向左进行遍历,计算面积最大值。

        public int largestRectangleArea(int[] heights) {
            if (heights.length == 0) return 0;
            int res = 0;
            for (int i = 0; i < heights.length; i++) {
                if (i == heights.length - 1 || heights[i] > heights[i + 1]) {
                    int minHeight = heights[i];
                    for (int j = i; j >= 0; j--) {
                        minHeight = Math.min(heights[j], minHeight);
                        res = Math.max(res, minHeight * (i - j + 1));
                    }
                }
            }
            return res;
        }
    

    解法二、使用堆栈,时间复杂度O(n)。

    如何更快的解决这个问题呢?这里需要从另一个角度来考虑这个问题,其实解法一也是一种类似DP的解法,它的核心思路就是固定最后一个数,来获得以当前数为结尾的最大矩形面积。其实还有另一个角度来思考,就是以每个数作为高度能获得的最大面积是多少?其实这个问题就是需要找当前数左右第一个比其低的数,然后就可以得出以当前数字为高度的最大矩形面积,最后我们只需要遍历比较一遍就可以得到最大的结果。

        public int largestRectangleArea(int[] nums) {
            int n = nums.length;
            int[] l = new int[n];
            int[] r = new int[n];
            Stack<Integer> stack = new Stack<>();
            for (int i = 0; i < nums.length; i++) {
                while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) stack.pop();
                l[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
                stack.push(i);
            }
            stack.clear();
            for (int i = nums.length - 1; i >= 0; i--) {
                while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) stack.pop();
                r[i] = stack.isEmpty() ? nums.length - 1 : stack.peek() - 1;
                stack.push(i);
            }
            int res = 0;
            for (int i = 0; i < n; i++) {
                res = Math.max(res, nums[i] * (r[i] - l[i] + 1));
            }
            return res;
        }
    

    二、Maximal Rectangle

    问题描述:

    问题求解:

    有个上一个问题的铺垫,这个问题就很好解决了,针对每一行,可以先求出其高度,然后再对每一行求最大最方图的面积,取max即可。

    使用一个height的二维数组进行高度的保存,可以将时间复杂度降到O(mn)

        public int maximalRectangle(char[][] matrix) {
            if (matrix.length == 0 || matrix[0].length == 0) return 0;
            int m = matrix.length;
            int n = matrix[0].length;
            int[][] height = new int[m][n];
            for (int i = 0; i < n; i++) if (matrix[0][i] == '1') height[0][i] = 1;
            for (int i = 1; i < m; i++) {
                for (int j = 0;j < n; j++) {
                    if (matrix[i][j] == '0') height[i][j] = 0;
                    else height[i][j] = 1 + height[i - 1][j];
                }
            }
            int res = 0;
            for (int i = 0; i < m; i++) {
                res = Math.max(res, helper(height[i]));
            }
            return res;
        }
    
        private int helper(int[] nums) {
            int n = nums.length;
            int[] l = new int[n];
            int[] r = new int[n];
            Stack<Integer> stack = new Stack<>();
            for (int i = 0; i < nums.length; i++) {
                while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) stack.pop();
                l[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
                stack.push(i);
            }
            stack.clear();
            for (int i = nums.length - 1; i >= 0; i--) {
                while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) stack.pop();
                r[i] = stack.isEmpty() ? nums.length - 1 : stack.peek() - 1;
                stack.push(i);
            }
            int res = 0;
            for (int i = 0; i < n; i++) {
                res = Math.max(res, nums[i] * (r[i] - l[i] + 1));
            }
            return res;
        }
    
  • 相关阅读:
    55.跳跃游戏
    Solution -「洛谷 P4007」小 Y 和恐怖的奴隶主
    Solution -「HDU 3507」Print Article
    Solution -「CF 888E」Maximum Subsequence
    Solution -「CF 959E」Mahmoud and Ehab and the xor-MST
    Ds100p -「数据结构百题」91~100
    Ds100p -「数据结构百题」81~90
    Ds100p -「数据结构百题」71~80
    Ds100p -「数据结构百题」61~70
    Ds100p -「数据结构百题」51~60
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/9650229.html
Copyright © 2020-2023  润新知