思路:
题意可以理解为比较当前是否比前一个小,大则继续,小则去掉前一个,并且继续往前比较
很容易想到要使用单调栈
代码:
class Solution {
public int largestRectangleArea(int[] heights) {
int n=heights.length,max=0;
Deque<Integer> stack=new ArrayDeque<>();
for(int i=0;i<=n;i++){
//条件是:1.不为空 2.当前height小于栈顶端的height 3.i到了最后
while(!stack.isEmpty()&&(i==n||heights[i]<heights[stack.peekLast()])){
//先一步把值弹出,下面算的peekLast就是再前一个的下标
int height=heights[stack.removeLast()];
int width=stack.isEmpty()?i:i-1-stack.peekLast();
max=Math.max(max,height*width);
}
//若不满足while的条件,就把值压入栈中(heights[i]>heights[stack.peek()])
stack.addLast(i);
}
return max;
}
}
分解:
1)使用ArrayDeque,而不是ArrayList,或是LinkedList,或者是Stack
原因是ArrayDeque和ArrayList是数组形式,而LinkedList是链表形式,而Stack在Java中则不建议使用(具体可以查看写的另一篇博文https://blog.csdn.net/di_ko/article/details/115004162)
2)
int height=heights[stack.removeLast()];
int width=stack.isEmpty()?i:i-1-stack.peekLast();
这几行代码其实有所简略,原始版本是:
int height=heights[stack.peekLast()];
int width=stack.isEmpty()?i:i-stack.peekLast();
stack.removeLast();
3)while循环之外的以下代码其实也有所简略
stack.addLast(i);
原始版本:
whie(...){
stack.addLast(i);
}
if(heights[i]<heights[stack.peekLast()]){
stack.addLast(i);
}