題目描述
有一個長條圖,用一個整數數組表示,其中每列的寬度為1,求所給長條圖包含的最大矩形面積。比如,對於長條圖[2,7,9,4],它所包含的最大矩形的面積為14(即[7,9]包涵的7x2的矩形)。
給定一個長條圖A及它的總寬度n,請返回最大矩形面積。保證長條圖寬度小於等於500。保證結果在int範圍內。
測試範例:[2,7,9,4,1],5
返回:14
網上流行的解法是利用一個單調遞增棧stack,棧中記錄的是列的下標而不是高度,棧始終維護這樣一種關係:stack[i]左邊第一個高度小於它的列的下標為stack[i-1]。而要保持這種性質就需要在入棧時做些工作: 如果棧為空白或入棧列的高度不小於棧頂列的高度,則直接入棧。毫無疑問這樣肯定滿足上述要求; 如果入棧列的高度小於棧頂列的高度,這樣直接入棧會破壞關係,所以需要將棧頂pop出去,之後要計算一下這個列所能組成的最大矩形面積:假設當前出棧列的下標為i,根據上述性質,這個矩形向左不能超過stack[i-1],向右不能超過當前入棧列的下標k(因為當前入棧列是右邊第一次出現高度小於棧頂列)。如此計算stack[i-1]和k之間列的個數再乘上出棧列的高度就是出棧列所能組成的最大矩形面積,然後與目前記錄的最大值比較。如果出棧後的棧頂列依然大於入棧列,則迴圈執行上述操作,直至棧為空白或入棧列的高度不小於棧頂列的高度。
代碼如下:
import java.util.*;public class MaxInnerRec { public int countArea(int[] A, int n) { LinkedList<Integer> stack = new LinkedList<>(); int result = Integer.MIN_VALUE; for(int i = 0 ; i <= A.length ; ++i){ int h = i == A.length ? 0 : A[i]; if(stack.isEmpty() || h >= A[stack.peek()]){ stack.push(i); } else{ int height = stack.pop(); result = Math.max(result, A[height] * (stack.isEmpty() ? i : i - stack.peek() -1) ); i--; } } return result; }}