For example, Given heights = [2,1,5,6,2,3], return 10
要求一個矩形的面積,要知道高和寬。 若是每次肯定高度爲height[i], 而後調用一個helper function找到左右邊界,即不小於height[i]的最左和最右。 這是一個明顯O(N^2)的算法,每次掃描都會重走整個array。 這裏有些步驟是沒必要要的,好比高度爲2往左掃的時候已經知道2>1了,然當高度爲1的時候,沒必要往左走,咱們能夠經過空間來記憶已知信息。 一個遞增序列156這種,咱們知道能夠夠成的矩形是會不斷增大的。而當1562,遇到2的時候矩形可能變小,這時咱們就要計算面積了。 遞增序列預處理,遞減的時候計算。
用代碼打印出每步的結果。 height : 0 left :0 right : 1 cur 2 area : 2 height : 3 left :3 right : 4 cur 6 area : 6 height : 2 left :2 right : 4 cur 10 area : 10 height : 5 left :5 right : 6 cur 3 area : 10 height : 4 left :2 right : 6 cur 8 area : 10 height : 1 left :0 right : 6 cur 6 area : 10
public class Solution { public int largestRectangleArea(int[] heights) { Stack<Integer> stk = new Stack<>(); int area = 0; for(int i=0; i<= heights.length; i++){ int h = i == heights.length ? 0 : heights[i]; if(stk.isEmpty() || h >= heights[stk.peek()]){ stk.push(i); } else { int top = stk.pop(); // 爲何用stk.peek()+1, 由於這裏stack裏存的可能不連續。 area = Math.max(area, heights[top]*(stk.isEmpty()? i: i-(stk.peek()+1))); i--; } } return area; }