Introduction
The Max Histogram Area Problem is a common coding challenge that involves finding the largest rectangular area that can be formed in a histogram. The bars of the histogram are represented as an array of non-negative integers, where each value corresponds to the height of a bar. Our goal is to determine the largest rectangle that can be formed using consecutive bars.
In this blog post, we will solve the Max Histogram Area problem using a stack-based approach, which efficiently computes the largest area in O(n) time complexity.
Problem Statement
Given an array representing the heights of bars in a histogram, find the maximum rectangular area that can be formed using the bars.
Example:
- Input:
histogram = [4, 2, 8, 6, 5, 3]
- Output:
Max area = 16
Histogram Representation:
| |
| | |
| | | |
| | | | |
| | | | | |
| | | | | | |
4 2 8 6 5 3
- The largest rectangle (with area 16) can be formed between bars at index 2 and 4, with a height of 5.
Approach
Stack-Based Solution
To solve the problem efficiently, we can use a stack to store indices of the histogram bars and compute the largest rectangle as follows:
- Traverse the Histogram: For each bar, check if it can form a larger rectangle than the previous bars.
- Stack Management: Use the stack to store the indices of the bars. If the current bar is shorter than the bar at the top of the stack, calculate the area of the rectangle formed by the bar at the top of the stack.
- Area Calculation: For each popped bar, calculate the area by determining the width of the rectangle. The width is determined by the distance between the current bar and the nearest smaller bar on the left (determined using the stack).
Java Code Implementation
Stacks Class (Max Histogram Area Calculation)
package coding.challenge;
import java.util.Stack;
public final class Stacks {
private Stacks() {
throw new AssertionError("Cannot be instantiated");
}
public static int maxAreaUsingStack(int[] histogram) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
for (int bar = 0; bar <= histogram.length; bar++) {
int barHeight;
// Handle the case where we process the last "virtual" bar
if (bar == histogram.length) {
barHeight = 0; // Take into account the end of the histogram
} else {
barHeight = histogram[bar];
}
// Process the stack if the current bar is smaller than the one on top of the stack
while (!stack.isEmpty() && barHeight < histogram[stack.peek()]) {
int top = stack.pop(); // Index of the highest bar
int left = stack.isEmpty() ? -1 : stack.peek(); // Find the left boundary
int areaRectWidth = bar - left - 1; // Calculate width of the rectangle
// Compute the area of the rectangle and update maxArea
int area = areaRectWidth * histogram[top];
maxArea = Math.max(area, maxArea);
}
// Push the current bar index onto the stack
stack.push(bar);
}
return maxArea;
}
}
Explanation:
Stack Setup:
- We use a
Stack<Integer>
to store the indices of the bars.
- We use a
Traverse the Histogram:
- We loop through each bar in the histogram. If the current bar is smaller than the top of the stack, we pop the stack and calculate the area formed by the bar at the top.
Area Calculation:
- For each bar popped from the stack, calculate the width of the rectangle it can form using the distance between the current bar and the bar at the left boundary (top of the stack after popping).
- The area is calculated as
areaRectWidth * histogram[top]
.
Final Area Calculation:
- After processing all the bars, the stack may still contain indices. We treat these remaining bars as potential candidates for forming rectangles and calculate their areas.
Main Class (Driver Program)
package coding.challenge;
public class Main {
public static void main(String[] args) {
int[] histogram = {4, 2, 8, 6, 5, 3};
int maxArea = Stacks.maxAreaUsingStack(histogram);
System.out.println("Max area: " + maxArea);
}
}
Example Output:
Max area: 16
Explanation of Output:
- For the input
histogram = [4, 2, 8, 6, 5, 3]
, the largest rectangle that can be formed has an area of16
. This rectangle spans the bars at indices 2, 3, and 4, with a height of 5 and a width of 3.
Time Complexity
Time Complexity: O(n), where
n
is the number of bars in the histogram. Each bar is pushed and popped from the stack at most once, making the time complexity linear.Space Complexity: O(n), since we use a stack to store the indices of the bars.
Conclusion
In this blog post, we solved the Max Histogram Area Problem using a stack-based approach in Java. This approach allows us to efficiently compute the largest rectangular area in a histogram in O(n) time complexity. The use of a stack ensures that we can calculate the maximum area by managing the indices of bars and their relative heights. This method is optimal and widely used in technical interviews and competitive programming.
Great post! Thanks!
ReplyDelete