问题描述
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.
1
Above is a histogram where width of each bar is 1, given height =[2,1,5,6,2,3].
2
The largest rectangle is shown in the shaded area, which has area =10 unit.
For example,
Given height =[2,1,5,6,2,3],
return10.
问题分析
这一题也是LeetCode上十分经典的一题了,求相邻直方图的最大面积,这题的第一想法是用dp来做,但是想了很久,都没有想到怎么做,只能看网上用栈实现的方式了,这题采用的想法很巧妙,采用栈来构造升序序列实现:
下面用栈实现一下题目中的样例[2,1,5,6,2,3]:
- 2进栈,s={2},result=0;
- 1比栈顶元素2小,无法进栈,弹出2,记录当前result=2*1=2,其中1表示2是弹出的第一个元素,1进栈,2用1替换也进栈,s={1,1}
- 5比栈顶元素1大,进栈,s={1,1,5},result不变
- 6比栈顶元素5大,进栈,s={1,1,5,6},result不变
- 2比栈顶元素6小,弹出6,result=6*1=6(6是弹出的第一个元素),继续尝试进栈,此时s={1,1,5}
- 2还是比栈顶元素5小,弹出5,result=5*2=10(5是弹出的第二个元素了),再次尝试进栈,此时s={1,1}
- 2比栈顶元素1小,可以进栈,把5和6变成2,重新进栈,result不变,s={1,1,2,2,2}
- 3比栈顶元素2小,进栈,s={1,1,2,2,2,3},result不变
- 至此,所有元素进栈完成,并且有序,result=10
- 计算栈内大小,
result=max(result,栈元素*所在位置深度)=(result,3*1,2*2,2*3,2*4,1*5,1*6)=10
- 所求的result大小就为10
代码实现
public int largestRectangleArea(int[] height) {
if (height.length == 0) return 0;
Stack<Integer> stack = new Stack<>();
int result = 0;
for (int i = 0; i < height.length; i++) {
if (stack.isEmpty() || stack.peek() <= height[i]) stack.push(height[i]);
else {
int count = 0;
while (!stack.isEmpty() && stack.peek() > height[i]) {
count++;
result = Math.max(result, stack.peek() * count);
stack.pop();
}
while (count > 0) {
count--;
stack.push(height[i]);
}
stack.push(height[i]);
}
}
int depth = 1;
while (!stack.isEmpty()) {
result = Math.max(result, stack.peek() * depth);
stack.pop();
depth++;
}
return result;
}
网友评论