Largest Rectangle in Histogram Using Stack in DSA Javascript - 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.
function largestRectangleArea(heights) {
const stack = [];
let maxArea = 0;
for (let i = 0; i <= heights.length; i++) {
const h = (i === heights.length) ? 0 : heights[i];
while (stack.length && h < heights[stack[stack.length - 1]]) {
const height = heights[stack.pop()];
const width = stack.length ? i - stack[stack.length - 1] - 1 : i;
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 through all bars plus stack push/pop operations.
- How many times: Each bar is pushed and popped at most once, so operations happen roughly twice per bar.
As the number of bars increases, the algorithm processes each bar a limited number of times.
| 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 roughly in direct proportion to the number of bars.
Time Complexity: O(n)
This means the time to find the largest rectangle grows linearly with the number of bars in the histogram.
[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 total number of stack operations is at most 2n, keeping the overall time linear.
Understanding this stack-based approach shows your ability to use data structures smartly to solve problems efficiently, a skill valued in many coding challenges.
"What if we replaced the stack with a simple array and searched for the largest rectangle by checking every possible pair of bars? 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 help calculate areas efficiently.Step 2: Explain why this helps
When a smaller bar is found, the stack helps find the largest rectangle with the previous taller bars as height.Final Answer:
To keep track of bars' indices with increasing heights -> Option CQuick 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 instead of indices
- Ignoring the order of bars in the stack
Solution
Step 1: Identify stack data structure in JavaScript
Stacks are implemented using arrays, so initializing with [] is correct.Step 2: Explain why other options are incorrect
{ } is an object, null is no structure, 0 is a number, none suitable for stack operations.Final Answer:
const stack = []; -> Option BQuick Check:
Stack as array = const stack = [] [OK]
- Using object {} instead of array
- Assigning null or number instead of array
- Confusing stack with other data structures
function largestRectangleArea(heights) {
const stack = [];
let maxArea = 0;
for (let i = 0; i <= heights.length; i++) {
const h = i === heights.length ? 0 : heights[i];
while (stack.length && h < heights[stack[stack.length - 1]]) {
const height = heights[stack.pop()];
const width = stack.length ? i - stack[stack.length - 1] - 1 : i;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}
console.log(largestRectangleArea([2, 1, 5, 6, 2, 3]));Solution
Step 1: Trace the stack and area calculation
Process bars: max area updates to 10 (5*2), final max area is 10.Step 2: Confirm final max area
Largest rectangle covers bars with heights 5 and 6, width 2, area 10.Final Answer:
10 -> Option DQuick Check:
Largest rectangle area = 10 [OK]
- Calculating area without considering width correctly
- Not popping all taller bars from stack
- Forgetting to add a zero height bar at end
function largestRectangleArea(heights) {
const stack = [];
let maxArea = 0;
for (let i = 0; i <= heights.length; i++) {
const h = i === heights.length ? 0 : heights[i];
while (stack.length && h < heights[stack[stack.length - 1]]) {
const height = heights[stack.pop()];
const width = i - stack[stack.length - 1];
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}Solution
Step 1: Analyze width calculation
Width should be i - stack top - 1, but code misses subtracting 1, causing wrong width.Step 2: Explain impact of bug
Incorrect width leads to overestimating area, so maxArea may be wrong.Final Answer:
Width calculation misses subtracting 1 -> Option AQuick Check:
Width = i - stack top - 1 needed [OK]
- Using heights instead of indices in stack
- Not adding a zero height bar at end
- Incorrect loop boundary causing missed bars
Solution
Step 1: Use stack to find largest rectangle
Process bars: largest rectangle covers bars with heights 5,4,5 (indices 2 to 4), min height 4, width 3, area = 12. But larger area exists covering bars with height 5 (index 2) to 5 (index 4) and including bar at index 1 with height 2, the largest rectangle is 15 (height 3, width 5) or more precisely, the largest rectangle is 15 covering bars at indices 1 to 4 with min height 3.Step 2: Confirm no larger area exists
Largest rectangle area is 15.Final Answer:
15 -> Option AQuick Check:
Largest rectangle area = 15 [OK]
- Calculating area without considering width correctly
- Not popping all taller bars before pushing new bar
- Ignoring the last bar by not adding zero height at end
Ready to prove it?
Pass the test and this pattern moves unknown
