84. Largest Rectangle in Histogram
Solution - Memorization
-
Find the leftmost and rightmost index for each histogram.
-
Use a memory array to ‘jump’ to the previous satisfied neighbour instead of looping through all neighbours.
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
res = 0
l = len(heights)
# Jump for searching
min_h_left, min_h_right = [], []
for i in range(l):
end_h = heights[i]
j = i-1
while j >= 0 and end_h <= heights[j]:
j = min_h_left[j]
min_h_left.append(j)
for i in range(l-1, -1, -1):
end_h = heights[i]
j = i+1
while j < l and end_h <= heights[j]:
j = min_h_right[l-1-j]
min_h_right.append(j)
min_h_right = list(reversed(min_h_right))
for i, start_h in enumerate(heights):
res = max(res, start_h, (min_h_right[i] - min_h_left[i] - 1) * start_h)
return res
Solution - Stack
-
Keep a stack maintaining the indexes of buildings with ascending height
- For each rectangle with the heights of the popped histogram,
its rightmost neighbour is
i
, its leftmost neighbor is the next item in the stack.Because both of them are the immediate histogram with height < current height.
- To deal with the boundary (at index 0), a dummy height 0 and index -1 is provided.
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
res = 0
l = len(heights)
if l == 0:
return 0
heights.append(0)
stack = [-1]
for i, h in enumerate(heights):
while len(stack) != 0 and heights[stack[-1]] > h:
index = stack.pop()
res = max(res, (i - stack[-1] - 1) * heights[index])
stack.append(i)
return res
PREVIOUSSliding Window Maximum