|
| 1 | +--- |
| 2 | +comments: true |
| 3 | +difficulty: hard |
| 4 | +# Follow `Topics` tags |
| 5 | +tags: |
| 6 | + - Array |
| 7 | + - Stack |
| 8 | + - Monotonic Stack |
| 9 | +--- |
| 10 | + |
| 11 | +# [84. Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/description/) |
| 12 | + |
| 13 | +## Description |
| 14 | + |
| 15 | +You are given an array of integers heights, where each element represents the height of a bar in a histogram. Each bar has a width of 1. |
| 16 | +Your task is to compute and return the area of the largest rectangle that can be formed within the bounds of the histogram. |
| 17 | + |
| 18 | +**Example 1:** |
| 19 | +``` |
| 20 | +Input: heights = [2,5,3,3] |
| 21 | +Output: 9 |
| 22 | +Explanation: he above is a histogram where width of each bar is 1. |
| 23 | +The largest rectangle is [5, 3, 3] area, which has an area = 9 units. |
| 24 | +``` |
| 25 | + |
| 26 | +**Example 2:** |
| 27 | +``` |
| 28 | +Input: heights = [3,4] |
| 29 | +Output: 6 |
| 30 | +``` |
| 31 | + |
| 32 | +**Constraints:** |
| 33 | + |
| 34 | +* `1 <= heights.length <= 10^5` |
| 35 | +* `0 <= heights[i] <= 10^4` |
| 36 | + |
| 37 | +## Solution |
| 38 | + |
| 39 | +The key idea is using a monotonic stack to track bar indices. For each bar, we pop taller bars from stack to calculate rectangles, as they can't extend further. The stack maintains increasing heights, making it efficient to find the largest possible rectangle at each position. |
| 40 | + |
| 41 | +```java |
| 42 | +class Solution { |
| 43 | + public int largestRectangleArea(int[] heights) { |
| 44 | + Stack<Integer> stack = new Stack<>(); |
| 45 | + int maxArea = 0; |
| 46 | + stack.push(-1); |
| 47 | + |
| 48 | + for (int i = 0; i < heights.length; i++) { |
| 49 | + while (!stack.isEmpty() && stack.peek() != -1 && heights[stack.peek()] >= heights[i]) { |
| 50 | + int height = heights[stack.pop()]; |
| 51 | + int width = i - stack.peek() - 1; |
| 52 | + maxArea = Math.max(maxArea, height * width); |
| 53 | + } |
| 54 | + stack.push(i); |
| 55 | + } |
| 56 | + |
| 57 | + while (stack.peek() != -1) { |
| 58 | + int height = heights[stack.pop()]; |
| 59 | + int width = heights.length - stack.peek() - 1; |
| 60 | + maxArea = Math.max(maxArea, height * width); |
| 61 | + } |
| 62 | + return maxArea; |
| 63 | + } |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +```python |
| 68 | +class Solution: |
| 69 | + def largestRectangleArea(self, heights: list[int]) -> int: |
| 70 | + max_area = 0 |
| 71 | + stack = [-1] |
| 72 | + for i, h in enumerate(heights): |
| 73 | + while stack[-1] != -1 and heights[stack[-1]] > h: |
| 74 | + height = heights[stack.pop()] |
| 75 | + width = i - stack[-1] - 1 |
| 76 | + max_area = max(max_area, height * width) |
| 77 | + stack.append(i) |
| 78 | + |
| 79 | + while stack[-1] != -1: |
| 80 | + height = heights[stack.pop()] |
| 81 | + width = len(heights) - stack[-1] - 1 |
| 82 | + max_area = max(max_area, height * width) |
| 83 | + return max_area |
| 84 | +``` |
| 85 | + |
| 86 | +## Complexity |
| 87 | + |
| 88 | +- Time complexity: $$O(n)$$ |
| 89 | +<!-- Add time complexity here, e.g. $$O(n)$$ --> |
| 90 | + |
| 91 | +- Space complexity: $$O(n)$$ |
| 92 | +<!-- Add space complexity here, e.g. $$O(n)$$ --> |
0 commit comments