【題目】
Given n non-negative integers representingthe histogram's bar height where the width of each bar is 1, find the area oflargest rectangle in the histogram.
Above is a histogram where width of eachbar is 1, given height = [2,1,5,6,2,3].
The largest rectangle is shown in theshaded area, which has area = 10 unit.
For example,
Given heights = [2,1,5,6,2,3],
return 10.
【思路】
用棧來類比,遍曆heights數組,並比較與棧頂元素stack[-1]的大小:
l 大於棧頂元素,就push進去;
l 等於棧頂元素,則忽略
l 小於棧頂元素,持續彈棧,並記錄這個高度的最大面積,直至棧為空白。然後將彈出的數全部替換為降序點的值,即做到了整體依然是有序非降的。
整個過程中,即把所有的局部最大矩陣計算過了,又在寬度範圍內保留了全部的情境。
寬度=當前索引-前索引
例,2,1,5,6,3的類比過程。
先加入一個0,方便最後可以全部彈棧出來。變成:2,1,5,6,2,3.
u 2進棧,stack = [2],maxArea = 0;
u 1比棧頂元素stack[-1]小,2出棧,maxArea = 2*1 =2;2被替換為1進棧,1繼續進棧,stack = [1,1] ,maxArea =2;
u 5比棧頂元素stack[-1]大,5進棧,棧為stack = [1,1,5] ,maxArea =2;
u 6比棧頂元素stack[-1]大,6進棧,棧為stack = [1,1,5,6] ,maxArea =2;
u 2比棧頂元素stack[-1]小,是一個降序點;此時棧長為4,開始彈棧,6出棧,maxArea =6*1=6(當前height*1(4-數字6在棧中的下標));接著判斷,2比棧頂元素5小,5出棧maxArea =5*2=6(當前height = 5,width =4-2=2(4-數字5在棧中的下標));下一個1比,2小,不需出棧。然後將彈出5、6的空位壓棧為2,2繼續入棧,stack = [1,1,2,2,2],maxArea = 10;
u 3比棧頂元素2大,入棧,stack = [1,1,2,2,2,3],maxArea = 10;
u 最後判斷每個點作為起始點的最大面積,max(height[i]*(size-i))=max{3*1, 2*2, 2*3, 2*4, 1*5, 1*6}= 8 < 10。遍曆結束。整個過程中max的area為10.
【Python實現】
方法一:暴力演算法,全部遍曆(TLE)
class Solution:
""":type heights: List[int]
:rtype: int
"""
def largestRectangleArea(self, height):
maxArea=0
for i in range(len(height)):
min = height[i]
for j in range(i, len(height)):
if height[j] < min:
min = height[j]
if min*(j-i+1) > maxArea:
maxArea = min*(j-i+1)
return maxArea
if __name__ == '__main__':
S= Solution()
heights = [2,1,5,6,2,3]
maxarea = S.largestRectangleArea(heights)
print(maxarea)
方法二:棧類比
class Solution:
""":type heights: List[int]
:rtype: int
"""
def largestRectangleArea(self, heights):
maxArea = 0
stack = []
i = 0
while i < len(heights):
if len(stack) == 0 or stack[-1] <= heights[i]:
stack.append(heights[i])
else:
count = 0
while len(stack) > 0 andstack[-1] > heights[i]:#height[i]小於棧頂元素
count += 1
maxArea = max(maxArea,stack[-1]*count)
stack.pop()#棧頂元素出棧
while count > 0:#將當前height入棧
count -= 1
stack.append(heights[i])
stack.append(heights[i])
i += 1
count = 1
while len(stack) != 0:
maxArea = max(maxArea, stack[-1]*count)
stack.pop()
count += 1
return maxArea
if __name__ == '__main__':
S= Solution()
heights = [2,1,5,6,2,3]
maxarea = S.largestRectangleArea(heights)
print(maxarea)