因为如果有两个相邻的 j 值对应的高度不满足 < 关系,那么后者会「挡住」前者,前者就不可能作为答案了。
也就是前面的元素和后面的元素小于当前元素(pop出来的元素)那么当前高度没办法扩展到后面和前面。
这道题其实就是去找当前位置元素左右两边第一个小于自己本身高度位置元素,然后通过位置元素相减与当前高度乘积得到当前的面积,如果位置元素相减大于1那么证明中间有多个元素,这些元素是pop出去的,所以都比当前元素大,以当前高度计算面积是没问题的。
需要再数组元素前面加上[0],在后面也加上[0] 因为如果当元素小于三个,或者元素一直递增,也可以保证栈中元素可以pop。
其中递归栈尤其是单调递减,求面积的问题时,需要在末尾加一个元素[0],同时要么在头部加一个[0],要么在循环内判断栈为空时将sidx设为1。来保证头部和尾部元素可以被操作到。蓄水不用考虑这些是因为头尾不会蓄水。
ps.当遇到题目与元素大小有关系时,考虑递归栈,考虑出栈入栈的意义。
单调栈性质:
- 单调栈里的元素具有单调性。
- 递增(减)栈中可以找到元素左右两侧比自身小(大)的第一个元素。
class Solution: def largestRectangleArea(self, height: List[int]) -> int: stack=[] maxvalue=0 if len(height)==1: return height[0] height=height+[0] for i in range(len(height)): while stack and height[stack[-1]]>=height[i]: s=stack[-1] stack=stack[:-1] if not stack: sidx=-1 else: sidx=stack[-1] maxvalue=max(maxvalue,(height[s]*(i-sidx-1))) stack.append(i) return maxvalue
通过枚举法,分别枚举他的宽度,两个循环。判断其中最小的高度即为可以求面积的高度。超时
class Solution: def largestRectangleArea(self, height: List[int]) -> int: h=height[0] maxvalue=0 for i in range(len(height)): h=height[i] for j in range(i,len(height)): h=min(h,height[j]) maxvalue=max(maxvalue,h*(j-i+1)) return maxvalue
通过枚举高度,然后分别寻找该元素左右第一个低于它的值,这样才可以开始算面积。
注意需要预判,left-1,right+1是否大于当前值,如果不大于则不改变left right 值。超时
class Solution: def largestRectangleArea(self, height: List[int]) -> int: h=height[0] maxvalue=0 for i in range(len(height)): left=i right=i while left>0 and height[left-1]>=height[i]: left-=1 while right<len(height)-1 and height[right+1]>=height[i]: right+=1 print(maxvalue) maxvalue=max(maxvalue,(right-left+1)*height[i]) return maxvalue