[LeetCode] 84. 柱状图中最大的矩形

题目链接 : https://leetcode-cn.com/problems/largest-rectangle-in-histogram/

题目描述:

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

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

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

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

示例:

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

思路:

首先,想找到第i位置最大面积是什么?

是以i为中心,向左找第一个小于heights[i]的位置left_i;向右找第一个小于于heights[i]的位置right_i,即最大面积为heights[i] * (right_i - left_i -1),如下图所示:

所以,我们的问题就变成如何找right_ileft_i?

最简单的思路就是,就是暴力法,直接分别在i左右移动

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        res = 0
        n = len(heights)
        for i in range(n):
            left_i = i
            right_i = i
            while left_i >= 0 and heights[left_i] >= heights[i]:
                left_i -= 1
            while right_i < n and heights[right_i] >= heights[i]:
                right_i += 1
            res = max(res, (right_i - left_i - 1) * heights[i])
        return res

但是,这是一个时间复杂度为\(O(n^2)\),超时

接下来想办法优化.

思路一:

当我们找i左边第一个小于heights[i]如果heights[i-1] >= heights[i]其实就是和heights[i-1]左边第一个小于heights[i-1]一样.依次类推,右边同理.

思路二:栈

利用单调栈,我写过关于它一篇文章

维护一个单调递增的栈,就可以找到left_iright_i

代码:

思路一:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        if not heights:
            return 0
        n = len(heights)
        left_i = [0] * n
        right_i = [0] * n
        left_i[0] = -1
        right_i[-1] = n
        for i in range(1, n):
            tmp = i - 1
            while tmp >= 0 and heights[tmp] >= heights[i]:
                tmp = left_i[tmp]
            left_i[i] = tmp
        for i in range(n - 2, -1, -1):
            tmp = i + 1
            while tmp < n and heights[tmp] >= heights[i]:
                tmp = right_i[tmp]
            right_i[i] = tmp
        # print(left_i)
        # print(right_i)
        res = 0
        for i in range(n):
            res = max(res, (right_i[i] - left_i[i] - 1) * heights[i])
        return res

java

class Solution {
    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) return 0;
        int n = heights.length;
        int[] left_i = new int[n];
        int[] right_i = new int[n];
        left_i[0] = -1;
        right_i[n - 1] = n;
        int res = 0;
        for (int i = 1; i < n; i++) {
            int tmp = i - 1;
            while (tmp >= 0 && heights[tmp] >= heights[i]) tmp = left_i[tmp];
            left_i[i] = tmp;
        }
        for (int i = n - 2; i >= 0; i--) {
            int tmp = i + 1;
            while (tmp < n && heights[tmp] >= heights[i]) tmp = right_i[tmp];
            right_i[i] = tmp;
        }
        for (int i = 0; i < n; i++) res = Math.max(res, (right_i[i] - left_i[i] - 1) * heights[i]);
        return res;
    }
}

思路二:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        stack = []
        heights = [0] + heights + [0]
        res = 0
        for i in range(len(heights)):
            #print(stack)
            while stack and heights[stack[-1]] > heights[i]:
                tmp = stack.pop()
                res = max(res, (i - stack[-1] - 1) * heights[tmp])
            stack.append(i)
        return res

java

class Solution {
    public int largestRectangleArea(int[] heights) {
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        int[] new_heights = new int[heights.length + 2];
        for (int i = 1; i < heights.length + 1; i++) new_heights[i] = heights[i - 1];
        //System.out.println(Arrays.toString(new_heights));
        for (int i = 0; i < new_heights.length; i++) {
            //System.out.println(stack.toString());
            while (!stack.isEmpty() && new_heights[stack.peek()] > new_heights[i]) {
                int cur = stack.pop();
                res = Math.max(res, (i - stack.peek() - 1) * new_heights[cur]);
            }
            stack.push(i);
        }
        return res;
    }
}

原文地址:https://www.cnblogs.com/powercai/p/10987169.html

时间: 2024-10-11 17:39:51

[LeetCode] 84. 柱状图中最大的矩形的相关文章

Leetcode 84 求直方图中矩形的最大面积

题目描述 Leetcode 84 给定 n 个正整数的列表,表示矩形的高度,表示直方图.每一个给出的矩形宽度是 1,找到在直方图里最大的矩形面积. 如图中给出的直方图,宽度是 1,给出的高度是 [2,1,5,6,2,3]. 可以在直方图中找出最大的隐藏面积,答案是 10. Input: [2,1,5,6,2,3] Output: 10 题目分析 解法一: 最后矩形的最大面积,肯定是以某个矩形为最矮高度,向左向右可扩展的最大面积. 举例子来说,假设以 6 为当前直方图中的最矮高度,分别向左和向右扩

【leetcode】柱状图中最大的矩形(第二遍)

题目链接 [题解] 考虑每个柱子为最高柱子对答案的贡献,就是看这个柱子往左能domain多少个单位 往右能domain多少个单位. 遇到比它小的为止 遍历所有的柱子为最高柱子的情况. 就能够覆盖到所有的矩形了. 也即枚举一个位置然后如果比它高就一直扩展,往左往右各做一次就好. 这样的时间复杂度是O(N^2)的 我们可以维护一个单调递增的队列. 这个队列里面第i个元素和第i-1个元素 假设他们原来在数组里的位置是 ii和jj 显然min(ii+1,jj)..jj这一段里面的柱子都是比i元素也即在原

Leetcode84. 柱状图中最大的矩形(单调栈)

84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足弹出栈顶,顺便利用此栈顶和当前位置计算栈顶能覆盖的长度 用来计算.仅需一次单调栈 原文地址:https://www.cnblogs.com/y2823774827y/p/11261446.html

[leetcode]85. Maximal Rectangle 最大矩形

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. Example: Input: [ ["1","0","1","0","0"], ["1","0","1",&qu

84. Largest Rectangle in Histogram *HARD* -- 求柱状图中的最大矩形面积

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The largest

leetCode 84.Largest Rectangle in Histogram (最大矩形直方图) 解题思路和方法

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The largest

leetcode || 84、Largest Rectangle in Histogram

problem: Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The

LeetCode84:柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]. 首先定义: 对柱形图中的一个矩形i来说,我们计算以heights[i]为高的矩形的最大面积时,以i为起点,向左找到第一个小于heights[i]的矩形j,向右找到第一个小于heights[i]的矩形k.(j,k)区间,也即[j+1,k-1]所围成的以heights[i]的

LeetCode 223 Rectangle Area(矩形面积)

翻译 找到在二维平面中两个相交矩形的总面积. 每一个矩形都定义了其左下角和右上角的坐标. (矩形例如以下图) 如果,总占地面积永远不会超过int的最大值. 原文 分析 这题前天试过,写了一堆推断.终究还是无果-- 贴几个别人的解决方式-- int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) { int64_t xmin1 = min( A, C ); int64_t xmax1 = max( A, C )