Solution: Largest Rectangle in Histogram
Let's solve the Largest Rectangle in Histogram problem using the Stacks pattern.
Statement#
Given an array of integers, heights, that represents the heights of bars in a histogram, find the area of the largest rectangle in the histogram, where the rectangle has a constant width of
Constraints
heights.lengthheights[i]
Solution#
So far, you have probably brainstormed some approaches and have an idea of how to solve this problem. Let’s explore some of these approaches and figure out which one to follow based on considerations such as time complexity and any implementation constraints.
Naive approach#
A naive approach is to consider every possible rectangle that can be formed in the histogram and compute the area of each rectangle. This involves iterating over all possible pairs of bars in the histogram and, for each pair, computing the height of the rectangle as the minimum height of the bar between them, and the width of the rectangle as the distance between them. The product of the height and width will give us the area of the rectangle for that pair. We return the rectangle with the maximum area.
This time complexity of this approach is
The space complexity of this approach is
Optimized approach using stacks#
We can improve the naive approach by using stacks. The idea is that a rectangle's width can be maximized if it extends as far as possible to the left and right without encountering a bar shorter than the current rectangle's height. By iterating through the histogram bars, we maintain a stack of indices in increasing order of height. When encountering a bar shorter than the one at the top of the stack, we calculate the area of the rectangle formed by the popped height and the width between the current index and the index at the top of the stack. This process ensures that the algorithm explores potential rectangle formations at each bar's position while keeping track of the largest possible area seen so far. It capitalizes on the observation that a taller bar might provide opportunities for larger rectangles by extending to adjacent shorter bars.
Here's how the algorithm works:
Create the following variables to assist the algorithm:
stack: This is the stack that will be used to store the indices of the bars. It is initialized to. max_area: This will store the current maximum area of the rectangle as we traverse theheightsarray. It is initialized to.
Traverse the
heightsarray from left to right:If the current bar's height,
height[i], is greater than that of the previous bar,height[i-1], the width of the rectangle of height,height[i-1], can be increased for a greater area. Therefore, we simply push the index of the current bar,i, tostack.Otherwise, the current bar's height is less than that of the previous bar. This means that the maximum area of all the rectangles to the left of this bar can now be calculated. The following are the steps to calculate the area of each of these rectangles:
The top of
stack, containing the index of the previous bar, will be popped.The respective height at this index will become the current height of the rectangle.
The right boundary of this rectangle, i.e., the bar to its right is the current index
i. It is stored in theright_boundaryvariable.The left boundary of this rectangle, i.e., the bar to its left that will not be a part of this rectangle, is the index contained in the new top of
stack. It is stored in theleft_boundaryvariable.The width of this rectangle is calculated using the formula:
right_boundary - left_boundary - 1.is subtracted since neither of the bars at the boundary are included in the width. The area of the rectangle is calculated by taking the product of the height and width.
Finally, we update
max_areaif the calculated area is greater than its existing value.This process is repeated until the current bar's height is less than the top of the stack, after which it is pushed to the stack.
Repeat the process above until the array has been traversed completely.
If
stackcontains elements other than-1, we have still not calculated the maximum area of the rectangle at all possible heights. Therefore, we calculate the area of the rectangle for all the heights of the remaining bars. The following are the steps to calculate these areas of each of these rectangles:Pop from
stackand calculate the maximum area of the rectangle of height corresponding to the index of the popped element.The right boundary of this rectangle is the length of the
heightsarray.The left boundary of this rectangle is the index contained in the new top of
stack. It is stored in theleft_boundaryvariableThe width of this rectangle is calculated using the formula:
len(heights) - left_boundary - 1.The area of the rectangle is calculated by taking the product of the height and width.
Finally, we update
max_areaif the calculated area is greater than its existing value.This process is repeated until the stack only contains
-1, meaning that the maximum area of the rectangle at all possible heights has been calculated and evaluated.
The
max_areavariable now stores the overall maximum area, so we return it.
The illustration below depicts how the algorithm runs:
1 of 20
2 of 20
3 of 20
4 of 20
5 of 20
6 of 20
7 of 20
8 of 20
9 of 20
10 of 20
11 of 20
12 of 20
13 of 20
14 of 20
15 of 20
16 of 20
17 of 20
18 of 20
19 of 20
20 of 20
Let’s look at the code for this solution below:
Solution summary#
The solution can be summarized in the following steps:
Initialize a stack to
, and a variable to store the indices and to track the current maximum area, respectively. Loop through each bar's height in the histogram.
Push the current bar's index onto the stack if its height is greater than the one at the top of the stack.
Do the following until the stack is not empty and the current bar's height is less than the height at the top of the stack:
Pop bars from the stack and calculate the area of rectangles they form.
Update the maximum area if needed.
After the loop, handle the remaining bars in the stack:
Calculate areas considering the rightmost boundaries.
Update the maximum area if needed.
Return the maximum area calculated.
Time complexity#
The time complexity of this solution is
Space complexity#
The space complexity of this solution is
Largest Rectangle in Histogram
Implement Queue Using Stacks