zoukankan      html  css  js  c++  java
  • Leetcode 84 求直方图中矩形的最大面积

    题目描述

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

    img

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

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

    img

    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).

  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/michael9/p/12100953.html
Copyright © 2011-2022 走看看