LeetCode第84题:柱状图中最大的矩形

题目详述

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

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

在这里插入图片描述
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
在这里插入图片描述
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

解法一

暴力法。时间复杂度:O(n^3),空间复杂度:O(1)

class Solution {
    public int largestRectangleArea(int[] heights) {
        int maxArea = 0;
        for (int i = 0; i < heights.length; i++) {
            for (int j = i; j < heights.length; j++) {
                int minHeight = Integer.MAX_VALUE;
                for (int n = i; n <= j; n++)
                    minHeight = Math.min(minHeight, heights[n]);
                maxArea = Math.max(maxArea, minHeight * (j - i + 1));
            }
        }
        return maxArea;
    }
}

解法二

暴力优化法。时间复杂度O(n^2),空间复杂度O(1)

class Solution {
    public int largestRectangleArea(int[] heights) {
        int maxArea = 0;
        for (int i = 0; i < heights.length; i++) {
            int minHeight = Integer.MAX_VALUE;
            for (int j = i; j < heights.length; j++) {
                minHeight = Math.min(minHeight, heights[j]);
                maxArea = Math.max(maxArea, minHeight * (j - i + 1));
            }
        }
        return maxArea;
    }
}

解法三

栈。 时间复杂度O(n),空间复杂度(n)
注意:

  1. 栈内存储的是下标,下标所代表的柱状高度始终是从小到大,若大于栈顶元素则入栈,小于栈顶元素则确定了最大矩形面积的高(当前矩形高度)和右边界,左边界则是栈顶元素的下一个元素。
  2. 所有高度下标均入栈后,再逐一出栈。
手跑程序:假设heights[6,7,5,2,4,5,9,3]
i = 0
push(0)
i = 1, 6 >= 7 不成立
push(1)
i= 2,  7 >= 5 pop(1) maxArea = 7 * (2 - 0 -1) = 7
		 6 >= 5 pop(0) maxArea = 6 * (2- (-1) - 1) = 12
push(2)
i = 3, 5 >=2 pop(2) maxArea = 5 * (3 - (-1) - 1) = 15
push(3)
i = 4, 2 >=4 不成立
push(4)
i = 5, 4 >= 5 不成立
push(5)
i = 6, 5 >= 9 不成立
push(6)
i = 7, 9 >=3 pop(6) maxArea = 9 * (7 - 5 - 1) = 9
		 5 >=3 pop(5) maxArea = 5 * (7 - 4 - 1) = 10
		 4 >= 3 pop(4) maxArea = 4 * (7 - 3 - 1)= 12
		 2 >= 3 不成立
push(7)
i = 8, 跳出for循环,进入while循环
maxArea = 3 * (8 - 3 - 1) = 12
maxArea = 2 * (8 - (-1) - 1) = 16
所以面积最大值是16
class Solution {
    public int largestRectangleArea(int[] heights) {
        int maxArea = 0;
        Stack<Integer> stack = new Stack<>();
        stack.push(-1);
        for (int i = 0; i < heights.length; i++) {
            while (stack.peek() != -1 && heights[stack.peek()] >= heights[i]) 
                maxArea = Math.max(maxArea, 
                    heights[stack.pop()] * (i - stack.peek() - 1));
            stack.push(i);
        }
        while (stack.peek() != -1)
            maxArea = Math.max(maxArea, heights[stack.pop()] * (heights.length - stack.peek() -1));
        return maxArea;
    }
}
发布了40 篇原创文章 · 获赞 0 · 访问量 651

猜你喜欢

转载自blog.csdn.net/weixin_42610002/article/details/104264896