Given an array of integers heights
representing the histogram's bar height where the width of each bar is 1
, return the area of the largest rectangle in the histogram.
Example 1:
Input: heights = [2,1,5,6,2,3] Output: 10 Explanation: The above is a histogram where width of each bar is 1. The largest rectangle is shown in the red area, which has an area = 10 units.
Example 2:
Input: heights = [2,4] Output: 4
Constraints:
1 <= heights.length <= 105
0 <= heights[i] <= 104
The core challenge of this problem is to find the largest rectangular area that can be formed within the histogram. This problem is significant in various fields such as computer graphics, data visualization, and computational geometry. A common pitfall is to attempt a brute-force solution, which would be inefficient for large inputs.
To solve this problem efficiently, we can use a stack-based approach. The idea is to maintain a stack of indices of the histogram's bars. We iterate through each bar and use the stack to keep track of the bars that are not yet processed. This allows us to calculate the maximum area in O(n) time complexity.
A naive solution would involve checking every possible rectangle by iterating through each pair of bars and calculating the area. This approach would have a time complexity of O(n^2), which is not feasible for large inputs.
The optimized solution uses a stack to keep track of the indices of the bars. We iterate through the histogram, and for each bar, we pop from the stack until we find a bar that is shorter than the current bar. For each popped bar, we calculate the area with the popped bar as the smallest (or minimum height) bar. This ensures that we calculate the maximum area for each bar efficiently.
Here is a step-by-step breakdown of the stack-based algorithm:
def largestRectangleArea(heights):
# Initialize an empty stack and max_area to 0
stack = []
max_area = 0
index = 0
while index < len(heights):
# If the stack is empty or the current bar is taller than the bar at the stack's top index
if not stack or heights[index] >= heights[stack[-1]]:
stack.append(index)
index += 1
else:
# Pop the top index from the stack
top_of_stack = stack.pop()
# Calculate the area with heights[top_of_stack] as the smallest bar
area = (heights[top_of_stack] *
((index - stack[-1] - 1) if stack else index))
# Update max_area if the calculated area is larger
max_area = max(max_area, area)
# Pop the remaining bars from the stack and calculate the area for each
while stack:
top_of_stack = stack.pop()
area = (heights[top_of_stack] *
((index - stack[-1] - 1) if stack else index))
max_area = max(max_area, area)
return max_area
The time complexity of this approach is O(n) because each bar is pushed and popped from the stack at most once. The space complexity is O(n) due to the stack used to store the indices.
Potential edge cases include:
Each of these cases is handled by the algorithm as it iterates through all bars and calculates the area accordingly.
To test the solution comprehensively, consider the following test cases:
assert largestRectangleArea([2,1,5,6,2,3]) == 10
assert largestRectangleArea([2,4]) == 4
assert largestRectangleArea([0,0,0,0]) == 0
assert largestRectangleArea([1,1,1,1]) == 4
assert largestRectangleArea([6,2,5,4,5,1,6]) == 12
When approaching such problems, it is crucial to:
In this blog post, we discussed the problem of finding the largest rectangle in a histogram. We explored a stack-based approach to solve the problem efficiently in O(n) time complexity. Understanding and solving such problems is essential for improving algorithmic thinking and problem-solving skills.
For further reading and practice, consider the following resources:
Our interactive tutorials and AI-assisted learning will help you master problem-solving skills and teach you the algorithms to know for coding interviews.
Start Coding for FREE