Largest Rectangle in Histogram – Solution & Complexity

1. Understanding the Problem

  • Each bar has width 1 and a given height.
  • A rectangle spans a contiguous range of bars and its height is the shortest bar in that range.
  • We want the maximum possible height * width over all ranges.

2. The Key Insight

  • For each bar, imagine it is the limiting (shortest) bar of a rectangle.
  • That rectangle stretches left and right until it meets a strictly shorter bar.
  • If we know those left/right boundaries for every bar, the area is height * (right - left - 1).

3. Using a Monotonic Stack

  • Keep a stack of bar indices whose heights are increasing.
  • When the current bar is shorter than the bar on top of the stack, that top bar's rectangle must end here.
  • Pop it, compute its area, and repeat until the stack is increasing again.
def largest_rectangle_area(heights):
    stack = []  # indices of increasing bars
    best = 0
    for i, h in enumerate(heights):
        while stack and heights[stack[-1]] > h:
            height = heights[stack.pop()]
            width = i if not stack else i - stack[-1] - 1
            best = max(best, height * width)
        stack.append(i)
    return best

4. Draining the Stack with a Sentinel

  • After the loop, bars still on the stack never met a shorter bar to their right.
  • Appending a sentinel height of 0 forces every remaining bar to be popped and measured.
  • The width uses the array length as the right boundary.
def largest_rectangle_area(heights):
    stack = []
    best = 0
    for i, h in enumerate(heights + [0]):  # sentinel flushes the stack
        while stack and heights[stack[-1]] >= h:
            height = heights[stack.pop()]
            width = i if not stack else i - stack[-1] - 1
            best = max(best, height * width)
        stack.append(i)
    return best

5. Complexity

  • Time: O(n) because each bar is pushed and popped exactly once.
  • Space: O(n) for the stack.

FAQ

See also: