Lesson 51 of 250
84. Largest Rectangle in Histogram
NeetCode: Largest Rectangle in Histogram · LeetCode: 84. Largest Rectangle in Histogram · Difficulty: Hard
Given bar heights of a histogram (each bar has width 1), return the area of the largest rectangle.
Example
Input: heights = [7, 1, 7, 2, 2, 4] Output: 8 (the bars 2, 2, 4 at height 2 give 2 x 4)Brute force: expand from every bar
The best rectangle that uses bar i as its shortest bar extends left and right as long as the neighbours are at least as tall. Compute that for every i. The area is height * width in int arithmetic. If a height times a width could exceed the int range, the product wraps silently to a wrong value, and the computation would need long.
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
int best = 0;
for (int i = 0; i < n; i++) {
int left = i;
while (left > 0 && heights[left - 1] >= heights[i]) {
left--;
}
int right = i;
while (right + 1 < n && heights[right + 1] >= heights[i]) {
right++;
}
best = Math.max(best, heights[i] * (right - left + 1));
}
return best;
}
}
public class Main {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.largestRectangleArea(new int[]{7, 1, 7, 2, 2, 4}));
System.out.println(s.largestRectangleArea(new int[]{1, 3, 7}));
}
}8
7Time: O(n²). Space: O(1).
Optimal: monotonic stack
Keep a stack of {start index, height} pairs, stored as two-element int[] arrays in an ArrayDeque, with strictly increasing heights. A new bar shorter than the top means the top bar cannot extend any further to the right: pop it, compute its rectangle (height * (i - start)), and remember that the new bar can extend left to that popped bar's start. After the scan, everything left on the stack extends to the end. Iterating an ArrayDeque with a for-each loop visits entries from the top of the stack to the bottom; the order does not matter here because only the maximum is kept.
import java.util.ArrayDeque;
import java.util.Deque;
class Solution {
public int largestRectangleArea(int[] heights) {
Deque<int[]> stack = new ArrayDeque<>(); // each entry is {start, height}
int best = 0;
for (int i = 0; i < heights.length; i++) {
int h = heights[i];
int start = i;
while (!stack.isEmpty() && stack.peek()[1] >= h) {
int[] top = stack.pop();
best = Math.max(best, top[1] * (i - top[0]));
start = top[0];
}
stack.push(new int[]{start, h});
}
int n = heights.length;
for (int[] entry : stack) {
best = Math.max(best, entry[1] * (n - entry[0]));
}
return best;
}
}
public class Main {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.largestRectangleArea(new int[]{7, 1, 7, 2, 2, 4}));
System.out.println(s.largestRectangleArea(new int[]{1, 3, 7}));
}
}8
7Time: O(n). Space: O(n).
