Largest Rectangle in Histogram Using Stack in DSA Java - Time & Space Complexity
We want to understand how the time needed to find the largest rectangle in a histogram changes as the number of bars grows.
How does the algorithm's work increase when the histogram gets bigger?
Analyze the time complexity of the following code snippet.
public int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
for (int i = 0; i <= heights.length; i++) {
int h = (i == heights.length) ? 0 : heights[i];
while (!stack.isEmpty() && h < heights[stack.peek()]) {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}
This code finds the largest rectangle area in a histogram by using a stack to track bars and calculate areas efficiently.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop runs through all bars once, and inside it, bars are pushed and popped from the stack.
- How many times: Each bar is pushed once and popped once, so stack operations happen at most 2n times for n bars.
As the number of bars increases, the total operations grow roughly in a straight line with the number of bars.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 stack operations |
| 100 | About 200 stack operations |
| 1000 | About 2000 stack operations |
Pattern observation: The operations grow linearly, doubling the bars roughly doubles the work.
Time Complexity: O(n)
This means the time to find the largest rectangle grows directly in proportion to the number of bars.
[X] Wrong: "Because there is a nested while loop inside the for loop, the time complexity must be O(n²)."
[OK] Correct: Each bar is pushed and popped only once, so the inner loop does not run for every iteration fully, keeping total operations linear.
Understanding this linear time stack approach shows you can solve complex problems efficiently, a skill that impresses in interviews and real projects.
"What if we used a simple nested loop checking all rectangles instead of a stack? How would the time complexity change?"
Practice
Solution
Step 1: Understand the role of the stack
The stack stores indices of bars in increasing height order to efficiently find boundaries for rectangles.Step 2: Why increasing order is important
When a lower height bar is found, it signals the end of rectangles for taller bars, allowing area calculation.Final Answer:
To keep track of bars' indices with increasing heights -> Option AQuick Check:
Stack tracks increasing bars = To keep track of bars' indices with increasing heights [OK]
- Thinking stack sorts bars by height
- Using stack to store areas directly
- Ignoring the order of bars in stack
Solution
Step 1: Identify correct generic syntax in Java
Java uses generics with angle brackets and wrapper classes like Integer, not primitive int.Step 2: Check each option
Stack<Integer> stack = new Stack<>(); uses Stack<Integer> stack = new Stack<>(); which is correct syntax for an empty integer stack.Final Answer:
Stack<Integer> stack = new Stack<>(); -> Option DQuick Check:
Correct generic syntax = Stack<Integer> stack = new Stack<>(); [OK]
- Using primitive int in generics
- Missing diamond operator <>
- Not specifying generic type
public class Histogram {
public static int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0, i = 0;
while (i < heights.length) {
if (stack.isEmpty() || heights[i] >= heights[stack.peek()]) {
stack.push(i++);
} else {
int top = stack.pop();
int area = heights[top] * (stack.isEmpty() ? i : i - stack.peek() - 1);
maxArea = Math.max(maxArea, area);
}
}
while (!stack.isEmpty()) {
int top = stack.pop();
int area = heights[top] * (stack.isEmpty() ? i : i - stack.peek() - 1);
maxArea = Math.max(maxArea, area);
}
return maxArea;
}
public static void main(String[] args) {
int[] heights = {2, 1, 5, 6, 2, 3};
System.out.println(largestRectangleArea(heights));
}
}Solution
Step 1: Trace the stack operations and area calculations
For heights {2,1,5,6,2,3}, the largest rectangle area is 10 (from bars 5 and 6 with width 2).Step 2: Confirm final maxArea value
After processing all bars and stack cleanup, maxArea is 10.Final Answer:
10 -> Option BQuick Check:
Largest rectangle area = 10 [OK]
- Miscomputing width when stack is empty
- Not popping all remaining bars after loop
- Confusing indices with heights
public static int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0, i = 0;
while (i < heights.length) {
if (stack.isEmpty() || heights[i] > heights[stack.peek()]) {
stack.push(i++);
} else {
int top = stack.pop();
int area = heights[top] * (stack.isEmpty() ? i : i - stack.peek() - 1);
maxArea = Math.max(maxArea, area);
}
}
while (!stack.isEmpty()) {
int top = stack.pop();
int area = heights[top] * (stack.isEmpty() ? i : i - stack.peek() - 1);
maxArea = Math.max(maxArea, area);
}
return maxArea;
}Solution
Step 1: Analyze the if condition in the main loop
The condition uses '>' which skips pushing bars of equal height, causing incorrect area calculation.Step 2: Fix by changing '>' to '>='
Using '>=' ensures bars of equal height are pushed, maintaining correct stack order and area calculation.Final Answer:
Change '>' to '>=' in the if condition to handle equal heights -> Option CQuick Check:
Use '>=' to handle equal heights correctly [OK]
- Using '>' causes missing equal height bars
- Removing second loop causes incomplete area calculation
- Using queue breaks LIFO needed for stack
Solution
Step 1: Use stack to track indices of increasing heights
Push indices while heights increase; pop when current height is less, calculating area with popped height as smallest bar.Step 2: Calculate largest area for given heights
For {6,2,5,4,5,1,6}, largest rectangle area is 15 (bars at indices 0 and 6 with height 6 and width 1, or bars 2,3,4 with height 4 and width 3, but max is 15 from bars 0 to 0 or 6 to 6 or combined area 15 from bars 2,3,4 with height 5 and width 3).Final Answer:
15 -> Option AQuick Check:
Stack helps find max area = 15 [OK]
- Not popping all bars after iteration
- Incorrect width calculation when stack is empty
- Ignoring bars with same height
Ready to prove it?
Pass the test and this pattern moves unknown
