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

题目描述

Leetcode 84 给定 n 个正整数的列表,表示矩形的高度,表示直方图。每一个给出的矩形宽度是 1,找到在直方图里最大的矩形面积。

如图中给出的直方图,宽度是 1,给出的高度是 [2,1,5,6,2,3].

可以在直方图中找出最大的隐藏面积,答案是 10.

Input: [2,1,5,6,2,3]
Output: 10

题目分析

解法一:

最后矩形的最大面积,肯定是以某个矩形为最矮高度,向左向右可扩展的最大面积。

举例子来说,假设以 6 为当前直方图中的最矮高度,分别向左和向右扩展,但发现没有找到比自己还高的。那么以 6 为最矮高度的矩形面积是 6.

如果以 2 以当前直方图中的最矮高度,向左向右扩展后,发现左面高度为5, 6 的矩形和右面为 3 的矩形,都比自己高。那么以 2 为最矮高度的矩形面积是 2 + 2+ 2 + 2 = 8.

所以,依次以每个位置的矩形为最矮位置,然后依次拓展就能找到最大的矩形面积了。

class Solution:
    def largestRectangleArea_old(self, heights: List[int]) -> int:
        """
        O(n^2) -> 超时了,无法提交成功
        :param heights:
        :return:

         思路:最后形成最大的矩形面积,肯定是以给定的数组中某个位置连续矩形的最矮位置。
         从 index=0 的位置开始,假定它是这样的位置,然后向左向右开始扫描,找出其连续的矩形
         面积,然后依次比较这些找到的矩形面积。
        """
        max_area = 0
        index = 0
        list_length = len(heights)
        while index < list_length:
            area = heights[index]
            left_index = index - 1
            while left_index > -1:
                if heights[left_index] >= heights[index]:
                    area += heights[index]
                    left_index -= 1
                else:
                    break

            right_index = index + 1
            while right_index < list_length:
                if heights[right_index] >= heights[index]:
                    area += heights[index]
                    right_index += 1
                else:
                    break
            max_area = max_area if max_area > area else area
            index += 1

        return max_area

但可以发现,依次遍历每个矩形的位置,时间复杂度为 O(n^2).

解法二:

如解法 1 提到的,最大的矩形面积其实就是以某个矩形为最矮位置可扩展的最大面积。这里使用的数据结构是单调递增栈,用于保存局部矩形的峰值。

单调栈就是在栈里的元素,按照一定的规则进行排序。在本题里,栈里记录的是给定的矩形高度的位置。依次去循环 heights 里的元素,如果比栈顶的元素的大,那么就将元素入栈。如果比栈顶元素的小,就需要出栈,计算以当前栈顶元素形成的矩形面积,直到遇到和要入栈元素一样高的位置再停止。

需要注意的地方是:

  • 给定的元素可能是一直递增的,所以需要给 heights 末尾添加一个元素 0,用于计算之前的面积。
  • 需要考虑出栈后,站内元素为 0 的情况,这时需要计算,最低矩形高度可以形成的连续矩形面积的情况。例如 [2,1,2] 这种情况。
class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        # add 0 to query the last local peak area
        # if the last height is still the highest
        heights.append(0)
        # definite a stack to record the heights position
        # to get the local peak area
        heights_position = []
        max_area = 0
        #
        index = 0
        while index < len(heights):
            if len(heights_position) == 0 or heights[heights_position[-1]] <= heights[index]:
                heights_position.append(index)
                index += 1
            else:
                popped_position = heights_position.pop()
                # get the continuous area of the smallest rectangle
                # index represents the the number of elements has been processed
                if len(heights_position) == 0:
                    max_area = max(max_area, index * heights[popped_position])
                # Get maximum area of rectangle in monotonically increasing
                else:
                    # index need to reduce 1 because the we add a 0
                    #  to the end of heights array.
                    max_area = max(max_area,
                                   (index - 1 - heights_position[-1]) * heights[popped_position])
        return max_area

对于解法 2 来说,每个元素最多会入栈和出栈一次,所以时间复杂度为 O(2n) 也就是 O(n).

原文地址:https://www.cnblogs.com/michael9/p/12100953.html

时间: 2024-10-09 20:18:40

Leetcode 84 求直方图中矩形的最大面积的相关文章

[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] 输出:

[LeetCode] 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

寻找直方图中面积最大的矩形

Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectang

计算直方图中最大矩形面积

题目是计算直方图中的最大矩形面积,下面是我的做法,我在网上也看到有人说可以通过栈的方式来解决,因为时间问题,并没有马上尝试,下回有时间在尝试下吧!! 还有这题有变式:计算矩阵中最大的矩形面积,其中矩阵中元素只能为1和0,代码下次补发吧!! 代码如下: #include<iostream>using namespace std; int maxSquare(const int pos,const int n,const int height[]){ if(n==1) return height[

LeetCode 210. Course Schedule II(拓扑排序-求有向图中是否存在环)

和LeetCode 207. Course Schedule(拓扑排序-求有向图中是否存在环)类似. 注意到,在for (auto p: prerequistites)中特判了输入中可能出现的平行边或自环. 代码: class Solution { public: vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) { // [0, {1, 2, 3}], me

leetcode——Longest Substring Without Repeating Characters 求链表中无重复字符的最大字串长度(AC)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

直方图中最大矩形面积

注意:本文并未对原文完整翻译,而是结合原文并根据本人理解写出,因此部分内容为完整翻译,部分内容为个人理解所写. Largest Rectangle in Histogram 直方图中最大矩形面积 一个直方图是由许多矩形组成,在给定的直方图中找出最大的矩形面积.为了简化问题,假定所有矩形宽度都为1个单位. 例如,下面的直方图中有7个矩形,高度分别是(6,2,5,4,5,2,6).最大的矩形面积是12(如下图所示,最大矩形面积用红色方框标出) 下面给出的解决方法时间复杂度为O(n).矩形面积的计算公

AcWing:131. 直方图中最大的矩形(贪心 + 单调栈)

直方图是由在公共基线处对齐的一系列矩形组成的多边形. 矩形具有相等的宽度,但可以具有不同的高度. 例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1: 通常,直方图用于表示离散分布,例如,文本中字符的频率. 现在,请你计算在公共基线处对齐的直方图中最大矩形的面积. 图例右图显示了所描绘直方图的最大对齐矩形. 输入格式 输入包含几个测试用例. 每个测试用例占据一行,用以描述一个直方图,并以整数n开始,表示组成直方图的矩形数目. 然后跟随n个整数h1,…,hn

LeetCode 207. Course Schedule(拓扑排序-求有向图中是否存在环)

求有向图中是否有环. 法一:拓扑排序 用一个队列维护所有入度为0的节点,每次弹出一个节点v,查看从v可达的所有节点u; 将u的入读减一,若u的入度此时为0, 则将u加入队列. 在队列为空时,检查所有节点的入度,若所有节点入度都为0, 则存在这样的一个拓扑排序 -- 有向图中不存在环. 代码: class Solution { public: bool canFinish(int numCourses, vector<pair<int, int>>& prerequisite