leetcode84 - Largest Rectangle in Histogram - hard
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.
Example:
Input: [2,1,5,6,2,3] Output: 10
维护一个递增栈, 因为我们要考虑宽度的,栈里存index。遍历所有的bar尝试push,如果当前bar的高度比栈顶要小了,依次把栈里比它大的的pop出来,再把它push进去。pop的这个过程就是计算面积打擂台的时候:pop出来的高度肯定是逐渐变小的,所以高就取pop出来的这个,宽要注意,如果栈都pop空了,说明当前这个高度是最小的,就相当于木桶原理那个最短板,它之前的所有bar都能提供宽度。其他情况下,宽取的是夹在中间的那段,左是当前的栈顶,右是当前遍历到的短板,左右都不包含。
单调栈的问题难都难在思路,不在代码,有很多细节要注意,想清楚以后实现很容易。
细节:
1. 为了最后一个bar也能被考虑到,先往heights里填个0
2. 每个bar要么直接被push进栈了,要么操作后也要被push进去,且只会进栈一次,pop出来了就是没用了,不会再放回去的
3. pop出来的前提是它比当前遍历到的那个大!
4. 宽度计算,左边要考虑现在的栈顶的idx,而不是刚被pop出来的这个的idx,他们不一定是相邻的关系!(i-cur_idx != i-1-st.top()!!!!!)
比如[4,2,0,3,2,5] 这个例子,0这个高度是pop不出来的,所以遍历到结尾然后逐一pop到idx=4的时候,栈顶是idx=2!也就是说2-4直接的之前pop出去过了,但它们是比idx=4的这个要高的,要算进去。
实现:
class Solution { public: int largestRectangleArea(vector<int>& heights) { int res = 0; stack<int> st; heights.push_back(0); for(int i=0; i<heights.size(); i++){ if(st.empty() || (!st.empty() && heights[i] >= heights[st.top()])) st.push(i); else{ while(!st.empty() && heights[st.top()] > heights[i]){ int idx = st.top(); st.pop(); int h = heights[idx]; int w = st.empty() ? i : (i-1-st.top()); res = max(res, h * w); } st.push(i); } } return res; } };

浙公网安备 33010602011771号