疑惑点解答
矩形高度即是当前弹出坐标对应的高度。
矩形的宽度是i-1-peek() 这是因为栈中的元素(数组坐标)不是连续的,当前的宽度是向左延伸、向右延伸。向右延伸最多到当前i,向左延伸最多到第一个小于等于他的坐标,即弹出它之后的下一个栈顶。
- 第一种
class Solution {
public int largestRectangleArea(int[] heights) {
if(heights==null || heights.length==0)
return 0;
if(heights.length==1)
return heights[0];
Stack<Integer> stack = new Stack<>();
int n = heights.length;
int res = 0;
for(int i=0;i<n;i++){
while(!stack.isEmpty() && heights[stack.peek()]>heights[i]){
int idx = stack.pop();
int h = heights[idx];
int w = 0;
if(stack.isEmpty())
w=i;
else
w = i-stack.peek()-1;
res = Math.max(res,h*w);
}
stack.push(i);
}
while(!stack.isEmpty()){
int idx = stack.pop();
int h = heights[idx];
int w = 0;
if(stack.isEmpty())
w = n;
else
w = n-1-stack.peek();
res = Math.max(res,h*w);
}
return res;
}
}
- 第二种
这一种方法加入在头尾各加入一个0,头部的0使得stack永不为空,尾部的0使得栈中的元素(属于heights的那些元素)都可以弹出,然后计算,省却了未弹出部分的计算。class Solution { public int largestRectangleArea(int[] heights) { if(heights==null || heights.length==0) return 0; if(heights.length==1) return heights[0]; Stack<Integer> stack = new Stack<>(); int n = heights.length+2; int[] arr = new int[n]; for(int i=0;i<n;i++){ if(i==0 || i==n-1) arr[i] = 0; else arr[i] = heights[i-1]; } stack.push(0); int res = 0; for(int i=1;i<n;i++){ while(arr[stack.peek()]>arr[i]){ int idx = stack.pop(); int h = arr[idx]; int w = i-stack.peek()-1; res = Math.max(res,h*w); } stack.push(i); } return res; }
}