【LeetCode】柱状图中最大的矩形、最大矩形(神之转化)

【LeetCode】柱状图中最大的矩形、最大矩形

柱状图中最大的矩形★★★

LeetCode84. 柱状图中最大的矩形

题目】给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

在这里插入图片描述

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]

在这里插入图片描述

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例

输入: [2,1,5,6,2,3]
输出: 10

解题思路

方法一:暴力法

对于每个柱状图,以它为高的矩形的宽可由下求得:ri - le - 1

  • 向左遍历直至heights[le] < heights[i]
  • 向右遍历直至heights[ri] < heights[i]

然后更新其面积为area = Math.max(area, heights[i] * len)

class Solution {
    
    
    public int largestRectangleArea(int[] heights) {
    
    
        int area = 0, n = heights.length;
        int le = 0, ri = 0;
        for(int i = 0; i < n; i++) {
    
    
            le = ri = i;
            while(le >= 0 && heights[le] >= heights[i]) le--;
            while(ri < n  && heights[ri] >= heights[i]) ri++;
            int len = ri - le - 1;
            area = Math.max(area, heights[i] * len);
        }
        return area;
    }
}

方法二:单调栈

单调递增栈中保存对应柱状图的下标

顺序遍历数组

  • 若栈不为空且heights[i] < height[stack.peek()](小于栈顶元素),则栈顶对应的柱状图的高度h可计算,出栈一个元素,左边边界为栈顶元素,右边边界为heights[i],此时宽度为i - stack.peek() - 1
    -更新面积为area = Math.max(area, h * (i - stack.peek() - 1))
  • 将下标i入栈
class Solution {
    
    
    public int largestRectangleArea(int[] heights) {
    
    
        int n = heights.length;
        int[] temp = new int[n + 2];
        //左右添加两个高为0的柱状图方便计算
        System.arraycopy(heights, 0, temp, 1, n);
        Stack<Integer> stack = new Stack<>();
        int area = 0;
        for(int i = 0; i < temp.length; i++) {
    
    
            while(!stack.isEmpty() && temp[i] < temp[stack.peek()]) {
    
    
                int h = temp[stack.pop()];
                area = Math.max(area, h * (i - stack.peek() - 1));
            }
            stack.push(i);
        }
        return area;
    }
}

最大矩形★★★

LeetCode85. 最大矩形

题目】给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例

在这里插入图片描述

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

解题思路

仔细观察示例中图,可按层遍历,看其元素将其是否为1来改变柱状图的高度,初始柱状图高度都为0,对于每一层元素

  • 若当前值为1,则柱体高度加1
  • 若当前值为0,则柱体高度为0

最大矩形可转化为求每一层柱状图中最大的矩形

class Solution {
    
    
    public int maximalRectangle(char[][] matrix) {
    
    
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
        int m = matrix.length, n = matrix[0].length;
        int[] heights = new int[n + 2];  //左右各添加一个高为0的柱状图
        int res = 0;
        for(int i = 0; i < m; i++) {
    
    
            //将每一层转化为柱状图
            for(int j = 0; j < n; j++) {
    
    
                if(matrix[i][j] == '1') {
    
    
                    heights[j + 1] += 1;
                }else {
    
    
                    heights[j + 1] = 0;
                }
            }
            //调用柱状图中最大的矩形代码并更新最大面积
            res = Math.max(res, maxAreaRectangle(heights));
        }
        return res;
    }
    
    //柱状图中最大的矩形代码
    private int maxAreaRectangle(int[] heights) {
    
    
        int area = 0;
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < heights.length; i++) {
    
    
            while(!stack.isEmpty() && heights[i] < heights[stack.peek()]) {
    
    
                int h = heights[stack.pop()];
                area = Math.max(area, h * (i - stack.peek() - 1));
            }
            stack.push(i);
        }
        return area;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44368437/article/details/112483648