LeetCode 84
The idea is somewhat similar to Longest Valid Parentheses, in which:
- Maintain a stack which stores the indices
- Calculate the target function each time an element pops out from the stack
- Take care of the corner case with
-1
when we don’t have the leftmost element
Maintain a stack of indices, in which:
- All the elements in the stack follows ascending order.
- The elements popped out between adjacent elements remains in the stack are all taller, i.e.
$$height[stack[j]] <= height[k], \ \forall k \in [stack[j-1], stack[j]]$$
- So for any element $j$ popped out
- leftmost element is $stack[-1] + 1$
- rightmost element is current index $i-1$
- the width is $(i-1)-(stack[-1]+1)+1=i-stack[-1]-1$
Before height[3] enter | After height[3] enter |
0 |
1 |
2 |
3 |
4 |
|
|
|
x |
|
|
|
x |
x |
|
|
x |
x |
x |
x |
x |
x |
x |
x |
x |
|
|
- when 3 pops, the leftmost is 1+1=2, rightmost is 4-1=3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class Solution:
def largestRectangleArea(self, heights):
stack, max_area = [], 0
heights.append(0)
for i in range(len(heights)):
while stack and heights[i] < heights[stack[-1]]:
popped_idx = stack.pop()
height = heights[popped_idx]
left = stack[-1] + 1 if stack else 0
right = max(i-1, 0)
width = right - left + 1
max_area = max(max_area, height*width)
stack.append(i)
return max_area
|
Notes:
- To ensure that
left
and right
is valid, watch out for the corner cases when calculating.
- Append
0
to heights
to ensure it pop out all the elements in the stack.