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 <= heights.length <= 10^5
0 <= heights[i] <= 10^4
Intuition
Need to maximize the area formed by a rectangle by combining rectangles from left and right.
If the heights of the rectangles on the left/right sides are more than or equal to the length of the current rectangle we can combine those to calculate the area and the resultant area will be the height of the current rect * width.
Width can be calculated by the distance between the indices of the chosen rightmost and the leftmost rect which is the nearest smaller to the current one.
Approach
To choose the leftmost rect we can find the
nearest smaller left
and similarlynearest smaller right
using thestack
inO(N)
.Store their
indices
in two vectors sayleft
andright
.
If there is no smaller rect in theleft
we can use-1
as an index and for the rightlen
as an index.The width will be equal to the
right - left - 1
.Now traverse the
heights
array and calculate thearea
for every rect and store themax_area
.
Complexity
Time complexity:O(N)
Space complexity:O(N)
Code
int largestRectangleArea(vector<int> &heights) {
int len = heights.size();
vector<int> left(len, -1), right(len, len);
stack<pair<int, int>> st;
// storing the indices of nearest smaller left for each element
for (int in = 0; in < len; ++in) {
if (!st.empty() && st.top().second < heights[in]) {
left[in] = st.top().first;
} else if (!st.empty() && st.top().second >= heights[in]) {
while (!st.empty() && st.top().second >= heights[in])
st.pop();
if (!st.empty())
left[in] = st.top().first;
}
st.push({in, heights[in]});
}
st = stack<pair<int, int>>();
// storing the indices of nearest right element for each element
for (int in = len - 1; in >= 0; in--) {
if (!st.empty() && st.top().second < heights[in]) {
right[in] = st.top().first;
} else if (!st.empty() && st.top().second >= heights[in]) {
while (!st.empty() && st.top().second >= heights[in])
st.pop();
if (!st.empty())
right[in] = st.top().first;
}
st.push({in, heights[in]});
}
// calculate area for every rectangle by combining the nearer left and rigt and store the maximum area.
int max_area = 0;
for (int in = 0; in < len; ++in) {
int area = heights[in] * (right[in] - left[in] - 1);
max_area = max(max_area, area);
}
return max_area;
}
Please Upvote if you found it helpful.