The problem involves finding the largest rectangle area in a histogram, where each bar has a height given by the array heights
. Each bar has a width of 1, and the rectangle's area is determined by the minimum height across a contiguous range of bars multiplied by the width of that range.
The solution uses a monotonic stack to efficiently compute the maximum rectangle area by tracking bars in increasing height order. Here’s how it works:
(height, index)
, where height
is the bar’s height, and index
is the starting index where this height is valid. The stack is initially empty, and we track the maximum area found (max_area
).i
with height height
, we set start = i
as the potential left boundary. While the stack is not empty and the current height is less than the height of the top stack element (stk[-1][0]
), we pop the top element (h, j)
:
h
and width i - j
(from index j
to i-1
).max_area
if this area is larger.start = j
, extending the current bar’s potential left boundary to the popped bar’s start index, as the current height can form a rectangle back to j
.(height, start)
onto the stack, indicating that this height is valid from index start
.(h, j)
, computing the area with height h
and width n - j
(from j
to the end of the array). Update max_area
if necessary.max_area
as the largest rectangle area found.n
is the number of bars. The stack stores at most n
elements, so the space complexity is O(n).
The "Largest Rectangle in Histogram" problem challenges us to find the area of the largest rectangle that can be formed within a histogram. The histogram is represented as an array of integers, where each element indicates the height of a bar and all bars have equal width of 1 unit. A rectangle can span one or more adjacent bars, and its height is limited by the shortest bar within that span.
A brute-force approach would involve checking every possible pair of start and end indices, calculating the minimum height within the range, and then computing the area. However, this would be inefficient. Instead, we use a monotonic increasing stack to keep track of the heights and their corresponding indices. This structure allows us to compute the largest rectangle in O(n) time by systematically managing and collapsing ranges of bars.
Start with an empty stack and a variable max_area
to store the largest area encountered.
For each index i
and corresponding height
in the array:
After finishing the iteration, we may have some bars left in the stack. These bars extend all the way to the end of the array. Pop each and calculate the area using the formula height × (n - index)
.
The stack-based method works efficiently because each bar is pushed and popped at most once. The stack maintains an increasing sequence of bar heights. When a smaller height is encountered, it acts as a boundary, triggering the calculation of maximal areas for all taller bars on the stack that can no longer extend beyond the current index.
By recording the earliest index where each height is valid, we ensure that widths are correctly computed even as we collapse prior rectangles.
Consider the input [2, 1, 5, 6, 2, 3]
. The algorithm builds the stack while maintaining increasing height order. When it reaches a height smaller than the stack top, it pops heights, calculates areas, and updates the max area. It ultimately finds that the rectangle covering [5,6]
with height 5 yields the largest area of 10.
Time Complexity: O(n). Each bar is pushed and popped from the stack at most once.
Space Complexity: O(n). The stack may store up to n elements in the worst case.
This problem is a classic demonstration of how a monotonic stack can be used to optimize problems involving ranges and boundaries. The algorithm is efficient and elegant, balancing complexity and performance in a way that is both optimal and easy to reason about once understood.