Skip to content

Commit 0d4ceb1

Browse files
committed
84-largest-rectangle-in-histogram.md Added another way to calculate the width.
1 parent 056bc07 commit 0d4ceb1

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

en/1-1000/84-largest-rectangle-in-histogram.md

+37-7
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,67 @@ Output: 4
2525
- `1 <= heights.length <= 100000`
2626
- `0 <= heights[i] <= 10000`
2727

28-
## Thoughts
28+
## Intuition
2929
This problem can be solved using **Monotonic Stack**.
3030

3131
* The `heights` in the stack from bottom to top are in ascending order.
3232
* While `current_height < stack_top_height`, pop `stack_top_height`.
3333
* Follow **Monotonic Stack**'s common rule: **only calculating when `pop()` is happening**. This common rule can be applied to calculating result for **most** of the `Monotonic Stack` problems.
34-
* Disappeared heights (popped by `current_height` or popped by `stack_top_height`) are all taller than `stack_top_height`. This logic will be used to calculate the `width`.
34+
* To calculate the `width`, there are two ways:
3535

36-
Detailed solutions will be given later, and now only the best practices in 7 languages are given.
36+
### Way 1
37+
* The last `popped_index` from stack should be kept since we need it to calculate the `width`.
38+
39+
### Way 2
40+
* Disappeared heights (popped when `current_height < stack_top_height`) are all taller than `stack_top_height`. This logic will be used to calculate the `width`.
3741

3842
### Complexity
3943
* Time: `O(n)`.
4044
* Space: `O(n)`.
4145

4246
## Python
47+
### Way 1
48+
```python
49+
class Solution:
50+
def largestRectangleArea(self, heights: List[int]) -> int:
51+
max_area = 0
52+
index_stack = []
53+
heights.append(0) # different from way 2
54+
55+
for i, height in enumerate(heights):
56+
popped_index = None # different from way 2
57+
58+
while index_stack and height < heights[index_stack[-1]]:
59+
popped_index = index_stack.pop()
60+
area = heights[popped_index] * (i - popped_index) # different from way 2
61+
max_area = max(max_area, area)
62+
63+
if popped_index is not None: # different from way 2
64+
i = popped_index
65+
heights[i] = height
66+
67+
index_stack.append(i)
68+
69+
return max_area
70+
```
71+
72+
### Way 2
4373
```python
4474
class Solution:
4575
def largestRectangleArea(self, heights: List[int]) -> int:
46-
heights = [0] + heights + [0]
4776
max_area = 0
4877
index_stack = []
78+
heights = [0] + heights + [0] # different from way 1
4979

5080
for i, height in enumerate(heights):
5181
while index_stack and height < heights[index_stack[-1]]:
5282
popped_index = index_stack.pop()
5383

5484
popped_height = heights[popped_index]
5585

56-
left_index = index_stack[-1] # popped_height's remaining left heights are all shorter than 'popped_height', because when 'popped_height' itself was pushed into stack, it must have caused some (could be none) taller heights been popped out of the stack.
57-
right_index = i # popped_height's right heights (which are all taller than 'popped_height') have been popped out of the stack (disappeared) when current `i` height is being pushed into stack.
58-
width = right_index - left_index - 1 # So in the range of 'width', they are all no shorter than `popped_height`, although they have been popped out of the stack (disappeared).
86+
left_index = index_stack[-1] # Different from way 1. popped_height's remaining left heights are all shorter than 'popped_height', because when 'popped_height' itself was pushed into stack, it must have caused some (could be none) taller heights been popped out of the stack.
87+
right_index = i # Different from way 1. popped_height's right heights (which are all taller than 'popped_height') have been popped out of the stack (disappeared) when current `i` height is being pushed into stack.
88+
width = right_index - left_index - 1 # Different from way 1. So in the range of 'width', they are all no shorter than `popped_height`, although they have been popped out of the stack (disappeared).
5989

6090
area = popped_height * width
6191
if area > max_area:

0 commit comments

Comments
 (0)