Published: Sep 7, 2022

## Introduction

A couple of approaches exist to solve this problem such as two pointers or divide and conquer.
The monotonically increasing stack is another solution.
Using stack, this problem can be solved by `O(n)`

performance.

## Problem Description

Given an array of integers

`heights`

representing the histogram’s bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram.Constraints:

`1 <= heights.length <= 10**5`

`0 <= heights[i] <= 10**4`

https://leetcode.com/problems/largest-rectangle-in-histogram/

## Examples

```
Example 1:
Input: heights = [2,1,5,6,2,3]
Output: 10
Explanation: The above is a histogram where width of each bar is 1.
The largest rectangle is shown in the red area, which has an area = 10 units.
.
6 . █
+---+
. |█ █|
. |█ █|
. |█ █| █
. █ |█ █|█ █
. █ █|█ █|█ █
0 . . . . . . . .
0 5
```

```
Example 2:
Input: heights = [2,4]
Output: 4
Explanation: one of below.
+-+ 4 . █
4 . |█| . █
. |█| .+---+
. █|█| .|█ █|
. █|█| .|█ █|
0 . . . 0 . . .
0 1 0 1
```

## Analysis

The monotonically increasing stack is a good data structure here. The stack will save indices. If a smaller height comes in, indices of taller heights are popped out. While popping out, calculate the area and update max area. At the end, process remaining indices in the stack.

## Solution

```
class LargestRectangleInHistogram:
def largestRectangleArea(self, heights: List[int]) -> int:
if not heights: return 0
max_area, stack, n = 0, [], len(heights)
for i in range(len(heights)):
while stack and heights[stack[-1]] > heights[i]:
h = heights[stack.pop()]
w = i if len(stack) == 0 else i - stack[-1] - 1
max_area = max(max_area, w * h)
stack.append(i)
while stack:
h = heights[stack.pop()]
w = n if len(stack) == 0 else n - stack[-1] - 1
max_area = max(max_area, w * h)
return max_area
```

## Complexities

- Time:
`O(n)`

- Space:
`O(n)`