84. Largest Rectangle in Histogram
Reference: http://www.geeksforgeeks.org/largest-rectangle-under-histogram/
1. Description:
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.
2. Difficulty:
Hard
3. Relative Problems
1 | 85. Maximal Rectangle |
4. Solution:
Analysis: How to get a Largest Rectangle? The problems sounds like buckets effect. The main idea is to find the height with its longest width. But How to do this in one pass?
When we observe the graph above, the first height 2 can only have width 1. Because the right height is 1. It is easy to see 1 depend on the buckets height.
When we look at 1, its longest width is 6. [2,1,5,6,2,3]
.
When we look at 5, its longest width is 2. 5,6
When we look at 6, its longest width is 1. 6
When we look at 2, its longest width is 4. 5,6,2,3
When we look at 3, its longest width is 1. 3
So if we want to get the longest width. We should find the bars whose height are lower than it !(both left bound and right bound).
For 2, we get left bound 1. So we get the largest bucket for 2 2
.
For 5, we get left bound 1, right bound 2. So we get the largest bucket for 5 5,6
.
For 6, we get left bound 5, right bound 2. So we get the largest bucket for 6 6
.
For 2, we get left bound 1, right bound 0 (consider histgram[length] = 0). So we get the largest bucket for 2. 5,6,2,3
Now let’s discuss how to get the bound.
Look at our requirement. One pass, get longest width for higher height.
As we analysize above, after getting 6’s width, 6 is useless, it could be 5,6,7 whatever >= 5.
After get 5’s width, 5 is useless. Because we know that all the rest of height is smaller than 5.
So We could use stack of ascendent order ( bottom to top ) to solve this problem.
Stack Solution:
In stack, I store index.
For corner case, I set leftmost and rightmost height as 0.
According to our analysis above, we just need to get higher height. So if the top of stack is smaller than the new height. We should push new height into stack.
1 | if(stack.empty() || heights[stack.peek()] <= h) |
Else, which means the current bucket’s height can not get longer width, we should pop top out and get its max Area. At this moment, we get the right bound.
What is its left bound? The current top of stack !
1 | int cur = stack.pop(); |
But we didn’t push the right bound into stack, so we need current i in next iteration. So i- -
.
Code:
1 | Stack<Integer> stack = new Stack<>(); |
1 | Stack<Integer> stack = new Stack<>();//栈中元素只会更大 |