【LeetCode笔记】85. 最大矩形(Java、单调栈)

题目描述

思路 && 代码

  • 一行抽象出一个【柱状图】,分别套到84题的函数里即可
  • 时空复杂度:O( n 2 n^2 n2)、O(n)
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if(matrix == null || matrix.length == 0) {
            return 0;
        }

        // 看成【对每层,进行柱状图最大面积判断】即可(相当于固定底)
        int max = 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] == '1') {
                    heights[j]++;
                }
                else {
                    heights[j] = 0;
                }
            }
            max = Math.max(max, largestRectangleArea(heights));
        }
        return max;
    }

    // 84. 求柱状图最大矩阵面积
    public int largestRectangleArea(int[] heights) {
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        int[] newHeights = new int[heights.length + 2];
        for(int i = 1; i < heights.length + 1; i++) {
            newHeights[i] = heights[i - 1];
        }
        for(int i = 0; i < newHeights.length; i++) {
            while(!stack.isEmpty() && newHeights[stack.peek()] > newHeights[i]) {
                int index = stack.pop();
                int l = stack.peek();
                int r = i;
                res = Math.max(res, (r - l - 1) * newHeights[index]);
            }
            stack.push(i);
        }
        return res;
    }
}

二刷

  • 思路还是记得的
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if(matrix == null || matrix.length == 0) return 0;

        int[] heights = new int[matrix[0].length];
        int res = 0;
        // 逐行转换
        for(int i = 0; i < matrix.length; i++) {
            // 当前行的逐列维护
            for(int j = 0; j < matrix[0].length; j++) {
                if(matrix[i][j] == '1') {
                    heights[j]++;
                }
                else {
                    heights[j] = 0;
                }
            }
            res = Math.max(res, largestRectangleArea(heights));
        }
        return res;
    }
    
    public int largestRectangleArea(int[] heights) {
        int[] newHeights = new int[heights.length + 2];
        for(int i = 1; i <= heights.length; i++) {
            newHeights[i] = heights[i - 1];
        }

        Deque<Integer> stack = new ArrayDeque<>();
        int max = 0;
        for(int i = 0; i < newHeights.length; i++) {
            while(!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) {
                int now = stack.poll();
                int left = stack.peek(); 
                int right = i; 
                max = Math.max(max, (right - left - 1) * newHeights[now]);
            }
            stack.push(i);
        }
        return max;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值