84. Largest Rectangle in Histogram
hardAsked at eBayeBay's seller analytics dashboard visualizes listing activity as bar charts — finding the largest contiguous block of equal or taller listings tells analysts about peak sustained activity windows. Largest Rectangle in Histogram is a stack-based hard problem that eBay uses to test monotonic stack mastery, one of the most powerful patterns for range-query problems.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in eBay loops.
- Glassdoor (2025-10)— Listed as an occasional eBay hard problem in senior SWE onsite reports, testing monotonic stack proficiency.
- Blind (2025-07)— eBay SWE threads mention Largest Rectangle in Histogram as a stack-mastery signal problem in senior algorithm interviews.
Problem
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.
Constraints
1 <= heights.length <= 10^50 <= heights[i] <= 10^4
Examples
Example 1
heights = [2,1,5,6,2,3]10Explanation: The largest rectangle spans bars at indices 2 and 3 (height 5, width 2), giving area 5*2=10.
Example 2
heights = [2,4]4Explanation: Single bar of height 4 gives the largest rectangle (area = 4*1 = 4).
Approaches
1. Monotonic increasing stack
Maintain a stack of indices in increasing height order. When a shorter bar is encountered, pop bars taller than it and compute the rectangle they could form: height of the popped bar, width from the new stack top to the current index.
- Time
- O(n)
- Space
- O(n)
function largestRectangleArea(heights) {
const stack = []; // indices, increasing heights
let maxArea = 0;
const n = heights.length;
for (let i = 0; i <= n; i++) {
const currHeight = i === n ? 0 : heights[i];
while (stack.length > 0 && currHeight < heights[stack[stack.length - 1]]) {
const height = heights[stack.pop()];
const width = stack.length === 0 ? i : i - stack[stack.length - 1] - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}Tradeoff: O(n) time, O(n) space — optimal. Each index is pushed and popped at most once. The sentinel (i === n, height 0) flushes all remaining bars from the stack at the end without a separate cleanup loop.
2. Divide and Conquer
Find the minimum bar in the range. The rectangle using all bars is min_height * range_width. Recurse on left and right of the minimum. Max of these three is the answer.
- Time
- O(n log n) average, O(n²) worst case
- Space
- O(log n) call stack
function largestRectangleArea(heights) {
function helper(lo, hi) {
if (lo > hi) return 0;
let minIdx = lo;
for (let i = lo + 1; i <= hi; i++) {
if (heights[i] < heights[minIdx]) minIdx = i;
}
const width = hi - lo + 1;
return Math.max(
heights[minIdx] * width,
helper(lo, minIdx - 1),
helper(minIdx + 1, hi)
);
}
return helper(0, heights.length - 1);
}Tradeoff: O(n log n) average but O(n²) in the worst case (sorted heights). Conceptually clean but not the expected O(n) solution. Present it as an alternative approach before the stack solution.
eBay-specific tips
eBay interviewers want you to name the pattern: 'monotonic increasing stack.' Explain the invariant before coding: 'The stack stores bars in increasing height order. When I encounter a shorter bar, every bar taller than it pops — it can no longer extend further right. Its width spans from after the new stack top to just before the current bar.' Draw the [2,1,5,6,2,3] example step-by-step. The sentinel 0 at the end is an elegant trick to avoid a post-loop cleanup; mention it explicitly.
Common mistakes
- Incorrect width calculation when the stack is empty after popping — width = i (the bar spans from index 0 to i-1), not i - 0 - 1.
- Forgetting the sentinel (appending 0 at i === n) — leaving bars unprocessed when the loop ends misses valid rectangles.
- Using a decreasing stack instead of increasing — inverts the pop condition and produces wrong results.
- Computing height from the stack top instead of the popped element — the popped element's height is the rectangle height; the new top is the left boundary.
Follow-up questions
An interviewer at eBay may pivot to one of these next:
- Maximal Rectangle (LC 85) — apply this solution row by row on a binary matrix to find the largest rectangle of 1s.
- Trapping Rain Water (LC 42) — complementary problem using similar stack/two-pointer reasoning on bar heights.
- How would you find the largest rectangle if bars could be non-integer (floating-point) heights?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
What does the stack invariant mean?
At any point, the stack stores indices of bars whose heights are strictly increasing from bottom to top. When a new bar is shorter than the stack top, the stack top can't extend further right — pop and compute its rectangle.
Why is the width i - stack[top] - 1 and not i - poppedIndex?
After popping, the left boundary of the rectangle is the new stack top (the next smaller bar to the left). Width = current index - new stack top - 1. The popped bar's index is not used for width — only its height.
Why does adding a sentinel 0 at the end work?
A height-0 sentinel is smaller than all bars, so it triggers a pop of every remaining element in the stack. This avoids needing a separate post-loop flush, keeping the code uniform.
Practice these live with InterviewChamp.AI
Drill Largest Rectangle in Histogram and other eBay interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →