代码随想录算法训练营第六十天 |84. 柱状图中最大的矩形

60 阅读2分钟

84. 柱状图中最大的矩形

代码随想录文章讲解

先计算左右第一个比当前高度小的index的list

 class Solution:
     def largestRectangleArea(self, heights: List[int]) -> int:
         size = len(heights)
         # 两个DP数列储存的均是下标index
         min_left_index = [0] * size
         min_right_index = [0] * size
         result = 0
 ​
         # 记录每个柱子的左侧第一个矮一级的柱子的下标
         min_left_index[0] = -1  # 初始化防止while死循环
         for i in range(1, size):
             # 以当前柱子为主心骨,向左迭代寻找次级柱子
             temp = i - 1
             while temp >= 0 and heights[temp] >= heights[i]:
                 # 当左侧的柱子持续较高时,尝试这个高柱子自己的次级柱子(DP
                 temp = min_left_index[temp]
             # 当找到左侧矮一级的目标柱子时
             min_left_index[i] = temp
         
         # 记录每个柱子的右侧第一个矮一级的柱子的下标
         min_right_index[size-1] = size  # 初始化防止while死循环
         for i in range(size-2, -1, -1):
             # 以当前柱子为主心骨,向右迭代寻找次级柱子
             temp = i + 1
             while temp < size and heights[temp] >= heights[i]:
                 # 当右侧的柱子持续较高时,尝试这个高柱子自己的次级柱子(DP
                 temp = min_right_index[temp]
             # 当找到右侧矮一级的目标柱子时
             min_right_index[i] = temp
         
         for i in range(size):
             area = heights[i] * (min_right_index[i] - min_left_index[i] - 1)
             result = max(area, result)
         
         return resul

单调栈

  • 此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度
  • 本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!
  • 高度就是栈顶的高度,宽度=right_index - left_index - 1
  • 注意头和尾的高度都能计算面积
 # Time complexity: O(N)
 # Space complexity: O(N)
 class Solution:
     def largestRectangleArea(self, heights: List[int]) -> int:
         heights.insert(0, 0)
         heights.append(0)
         stack = [0]
         result = 0
         for i in range(1, len(heights)):
             while stack and heights[i] < heights[stack[-1]]:
                 mid_height = heights[stack.pop()]
                 area = (i - stack[-1] - 1) * mid_height
                 result = max(area, result)
             stack.append(i)
         return result