Largest Rectangle in Historgram

Tags: monotonic stack, stack


Problem Statement:

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.

Example:

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.

Intuition:

for any index (say i), the max area that can be formed including that element is
area = heights[i] * (nse[i] - pse[i] -1).

Note: For one pass solution, the key insight (memorize this)
NSE is discovered when an element is popped
PSE is discovered when an element is pushed
That’s the entire “one-pass” trick.

Code:

My Solution

def largestRectangleArea(self, heights: List[int]) -> int:
	n = len(heights)
	nse = [n] * n
	stk = []
	for i,h in enumerate(reversed(heights)):
		i = n - i - 1
		while stk and heights[stk[-1]] >= h:
			stk.pop()
		if stk:
			nse[i] = stk[-1]
		stk.append(i)

	pse = [-1] * n
	stk = []
	for i,h in enumerate(heights):
		while stk and heights[stk[-1]] >= h:
			stk.pop()
		if stk:
			pse[i] = stk[-1]
		stk.append(i)

	mx = 0
	for i, h in enumerate(heights):
		area = h * (nse[i] - pse[i] - 1)
		mx = max(mx, area)

	return mx
        

One Pass Solution

def largestRectangleArea(self, heights: List[int]) -> int:
	n = len(heights)
	stk = []
	left = [-1] * n
	right = [n] * n
	for i, h in enumerate(heights):
		while stk and heights[stk[-1]] >= h:
			right[stk[-1]] = i
			stk.pop()
		if stk:
			left[i] = stk[-1]
		stk.append(i)
	return max(h * (right[i] - left[i] - 1) for i, h in enumerate(heights))