You are given an array of integers heights
representing the histogram's bar height where the width of each bar is 1
. Your task is to return the area of the largest rectangle in the histogram.
For example, consider a histogram represented by the array [2,1,5,6,2,3]
. The bars have heights 2, 1, 5, 6, 2, and 3 respectively, each with a width of 1. The largest rectangle that can be fit within this histogram has an area of 10. This rectangle spans from the bar of height 5 to the bar of height 6, and its height is limited by the shorter bar (height 5). So, the area is 5 (height) * 2 (width) = 10.
Another example is [2,4]
. The largest rectangle in the histogram is of area 4.
Write a function that takes an array heights
as input and returns the area of the largest rectangle in the histogram. Note that:
1 <= heights.length <= 10^5
0 <= heights[i] <= 10^4
This problem asks us to find the largest rectangular area that can be fit within a histogram. The histogram is represented by an array of integers, where each integer represents the height of a bar and each bar has a width of 1.
A brute-force approach would involve considering every possible rectangle within the histogram and calculating its area. We can iterate through all possible starting and ending points for the rectangle and determine the height of the rectangle based on the smallest bar within that range. The area is then calculated by multiplying the width (ending point - starting point + 1) by the minimum height. Finally, we keep track of the maximum area found so far.
def largestRectangleArea_brute_force(heights):
max_area = 0
n = len(heights)
for i in range(n):
for j in range(i, n):
min_height = min(heights[i:j+1])
width = j - i + 1
area = min_height * width
max_area = max(max_area, area)
return max_area
Time Complexity: O(n^2), where n is the number of bars in the histogram. We have nested loops to consider every possible rectangle.
Space Complexity: O(1), as we only use a few variables to store the maximum area, minimum height, and width.
A more efficient approach involves using a stack to keep track of the indices of increasing heights. When we encounter a bar that is shorter than the bar at the top of the stack, it indicates that we can calculate the area of a rectangle with the bar at the top of the stack as the minimum height. The width of the rectangle is determined by the distance between the current bar and the bar before the one at the top of the stack.
def largestRectangleArea(heights):
stack = []
max_area = 0
n = len(heights)
for i in range(n + 1):
# use a zero height at the end to clear the stack
while stack and (i == n or heights[stack[-1]] >= heights[i]):
height = heights[stack.pop()]
width = i if not stack else i - stack[-1] - 1
max_area = max(max_area, height * width)
stack.append(i)
return max_area
Explanation:
max_area
to 0.heights
array, appending a 0 to the end. This ensures that all bars in the stack are processed at the end.i
and the index of the previous element in the stack (if the stack is not empty).max_area
is updated if necessary.max_area
.Time Complexity: O(n), where n is the number of bars in the histogram. Each bar is pushed onto the stack and popped off the stack at most once.
Space Complexity: O(n), as the stack can contain up to n indices in the worst case (when the heights are in increasing order).
heights
array is empty, the maximum area is 0.while
loop, correctly capturing the maximum area. For example, heights = [5,4,3,2,1]