单调栈的应用:
用一个栈维护顺序,按照单调增或者减的顺序,一旦遇到不按照单调规律的值,就不断的弹出,直至栈顶元素和要入栈的元素满足单调关系。在这个过程中进行某种计算,最终得到想要的值。
public int largestRectangleArea(int[] heights){
int len = heights.length;
if (len == 0) {
return 0;
}
if(len == 1){
return heights[0];
}
int area = 0;
int[] newHeights = new int[len+2];
for(int i=0; i<len; i++){
newHeights[i+1] = heights[i];
}
len += 2;
heights = newHeights;
Deque<Integer> stack = new ArrayDeque<>();
stack.addLast(0);
for(int i=1; i<len; i++){
while(heights[stack.peekLast()] > heights[i]){
int height = heights[stack.removeLast()];
int width = i - stack.peekLast() -1;
area = Math.max(area, width * height);
}
stack.addLast(i);
}
return area;
}
对于某种高度(栈顶元素),只需要确定他的左右边界。那么我们保证栈中的元素按照单调增。那么栈顶元素的左边界就是挨着它的元素,右边界就是这个即将入栈,并且小于栈顶的元素。
在头和尾都放置了0。头部的作用是,不用判断栈是否为空了,应为永远不会为空。尾部的作用是使栈内的元素全部弹出(防止高度最小的,没有参与计算)。