Largest Rectangle in Histogram
You are given an array of integers representing the heights of histogram bars where each bar has width 1. Find the area of the largest rectangle that can be formed within the bounds of the histogram.
The brute force approach checks every possible rectangle by expanding left and right from each bar, running in O(n²). A monotonic increasing stack solves it in O(n). As you iterate through the bars, the stack maintains indices of bars in increasing height order. When a shorter bar arrives, it means the taller bar on the stack cannot extend further to the right. Pop the taller bar, calculate its area using the current index as the right boundary and the new top of stack as the left boundary, and update the maximum.
At the end, process any remaining bars in the stack with the array length as the right boundary.
The monotonic increasing stack is the key to the O(n) solution. The stack maintains indices of bars in increasing height order. When a shorter bar arrives, it means the taller bars in the stack cannot extend further to the right. For each popped bar, its height is the limiting factor, and the width is determined by the distance between the current index and the new top of stack.
A critical part of this algorithm is the sentinel value of 0 at the end. By iterating to heights.length and treating the extra iteration as height 0, all remaining bars in the stack are automatically processed because 0 is shorter than any positive height.
The brute force approach expands left and right from each bar, checking every possible rectangle, which runs in O(n²). The stack approach is O(n) because each index is pushed and popped exactly once.
This is one of the most commonly asked hard-level stack problems in interviews. Understanding the boundary calculation is the hardest part.
The key to understanding this algorithm is realizing that the maximum rectangle containing a particular bar as the shortest bar extends from the previous shorter bar to the next shorter bar. The monotonic stack discovers these boundaries efficiently by keeping indices of bars in increasing height order.
When visualizing this algorithm, imagine each bar being pushed onto the stack, waiting for a shorter bar to its right that will define its right boundary. The left boundary is determined by the bar immediately below it in the stack. This dual-boundary discovery is what makes the algorithm elegant.
Practice tracing through the example [2,1,5,6,2,3] step by step to fully understand how the stack maintains the boundaries and how the maximum area of 10 is found.
Example Input & Output
The largest rectangle is formed by bars of height 2 and 5,6,2 spanning width 2 (area 5x2=10, or the 2x5 rectangle).
All bars height 1, width 4, area 4.
Either the full 2x2 rectangle (area 4) or the 4x1 bar (area 4).
Algorithm Flow

Solution Approach
Iterate through heights. While the stack is not empty and the current height is less than the height at the top of the stack, pop the top index. The height for that popped bar is its own height. The width is the current index minus the new top index minus 1 (or just the current index if the stack is empty). Calculate area and update the maximum. Push the current index. After the loop, process remaining indices with n as the right boundary.
Time complexity is O(n). Space complexity is O(n).
Best Answers
import java.util.*;
class Solution {
public int solution(int[] heights) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
for (int i = 0; i <= heights.length; i++) {
int h = i < heights.length ? heights[i] : 0;
while (!stack.isEmpty() && h < heights[stack.peek()]) {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}
}Comments (0)
Join the Discussion
Share your thoughts, ask questions, or help others with this Challenge.
