84. Largest Rectangle in Histogram
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.
Example 1:
Input: heights = [2,1,5,6,2,3]
Output: 10
Explanation: The above is a histogram where width of each bar is 1.
The largest rectangle is shown in the red area, which has an area = 10 units.
Example 2:
Input: heights = [2,4]
**Output:**4
Constraints:
- 1 < = h e i g h t s . l e n g t h < = 1 0 5 1 <= heights.length <= 10^5 1<=heights.length<=105
- 0 < = h e i g h t s [ i ] < = 1 0 4 0 <= heights[i] <= 10^4 0<=heights[i]<=104
From: LeetCode
Link: 84. Largest Rectangle in Histogram
Solution:
Ideas:
-
Initialize a Stack: The stack is used to keep track of the indices of the bars. Bars are pushed onto the stack in increasing order of their heights.
-
Iterate Over the Bars: We iterate through each bar and perform one of two actions at each step:
- Push on the Stack: If the current bar is taller than the bar at the top of the stack or the stack is empty, we push the current index onto the stack.
- Calculate Area: If the current bar is shorter than the bar at the top of the stack, this means we’ve found a potential right boundary for the largest rectangle containing the bar at the top of the stack. We pop the stack, and calculate the area of the rectangle that uses the popped bar as the smallest (or minimum height) bar. The width of this rectangle extends from the current index to the index of the next item on the stack or to the beginning of the histogram if the stack is empty after popping.
-
Update the Maximum Area: After calculating the area, if it is greater than the current maximum area, we update the maximum area.
-
Handle Remaining Bars: After we’ve processed all the bars, there may still be some bars left on the stack. These bars were always taller than the bars after them. For each of these bars, we calculate the area assuming the rectangle extends to the end of the histogram.
-
Return the Largest Area: After processing all bars and emptying the stack, the largest area found is returned as the solution.
Code:
int largestRectangleArea(int* heights, int heightsSize) {
// Stack to keep indices of the bars.
int *stack = (int*)malloc(sizeof(int) * heightsSize);
int top = -1; // Stack is initially empty.
int maxArea = 0;
int areaWithTop; // To store area with top bar as the smallest bar
int i = 0;
while (i < heightsSize) {
// If this bar is higher than the bar on top stack, push it to stack.
if (top == -1 || heights[stack[top]] <= heights[i]) {
stack[++top] = i++;
} else {
// If this bar is lower than top of stack, then calculate area of rectangle
// with stack top as the smallest (or minimum height) bar.
// 'i' is 'right index' for the top and element before top in stack is 'left index'.
int topOfStack = stack[top--];
areaWithTop = heights[topOfStack] * (top == -1 ? i : i - stack[top] - 1);
// Update max area, if needed.
if (maxArea < areaWithTop) {
maxArea = areaWithTop;
}
}
}
// Now pop the remaining bars from stack and calculate area with every popped bar as the smallest bar.
while (top > -1) {
int topOfStack = stack[top--];
areaWithTop = heights[topOfStack] * (top == -1 ? i : i - stack[top] - 1);
if (maxArea < areaWithTop) {
maxArea = areaWithTop;
}
}
// Free the allocated stack memory.
free(stack);
return maxArea;
}