給了一個數組,數組值代表高度,這構成了一個直方圖,求直方圖中最大矩形的面積
[leetcode84]https://leetcode.com/problems/largest-rectangle-in-histogram/
思路:
考慮必須包含某個柱子的矩形的最大面積,那么我們就需要找到這個柱子往左和往右的邊界,這樣寬度高度都有了,就有了必須包含這個柱子的最大面積,左右柱子的這個最大面積求出來,這其中的最大即為全局最大。
算法步驟
- 使用一個stack,首先壓入第一個元素的位置,然后遍歷數組,在遇到當前數組大于棧頂對應值時,直接入棧即可,否則進行出棧操作,知道棧頂元素的值小于當前元素。這一過程中即可求出必須包含棧頂元素的最大矩陣面積。
然后壓入當前元素。 - 遍歷結束后如果棧中還有元素,也需要將其彈出,并計算。
算法原理
假設現在遍歷到i,如果棧頂元素小于heights[i],表明這個i就是棧頂元素的左邊界,而棧頂元素的右邊界就是棧頂元素的下邊一個元素(為空補-1),這樣就可以求得必須包含棧頂元素的最大矩形面積。這樣遍歷一次之后就所有的情況都考慮到了。需要注意的是你遍歷結束之后,可能棧中還有元素,也需要把這些元素彈出結算,此時這些元素的右邊界即為heights.length。
代碼
public class Solution {
public int largestRectangleArea(int[] heights) {
if(heights==null||heights.length==0)
return 0;
int res=0;
Stack<Integer> stack=new Stack<Integer>();
for(int i=0;i<heights.length;i++){
while(!stack.isEmpty()&&heights[i]<=heights[stack.peek()]){
int cur=stack.pop();
int left=stack.isEmpty()?-1:stack.peek();
res=Math.max(res,(i-left-1)*heights[cur]);
}
stack.push(i);
}
while(!stack.isEmpty()){
int cur=stack.pop();
int left=stack.isEmpty()?-1:stack.peek();
res=Math.max(res,(heights.length-left-1)*heights[cur]);
}
return res;
}
}