標籤:style blog http color io 使用 ar for div
Given n non-negative integers representing the histogram‘s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].The largest rectangle is shown in the shaded area, which has area = 10 unit.For example,Given height = [2,1,5,6,2,3],return 10.
難度:94. 參考了網上各種解法,歸納如下:
解法一:brute force的方法很直接,就是對於每一個視窗,找到其中最低的高度,然後求面積,去其中最大的矩形面積。總共有n^2個視窗,找最低高度是O(n)的操作,所以複雜度是O(n^3)。
解法二:就是從每一個bar往兩邊走,以自己的高度為標準,直到兩邊低於自己的高度為止,然後用自己的高度乘以兩邊走的寬度得到矩陣面積。因為我們對於任意一個bar都計算了以自己為目標高度的最大矩陣,所以最好的結果一定會被取到。每次往兩邊走的複雜度是O(n),總共有n個bar,所以時間複雜度是O(n^2)。
解法三:在網上發現另外一個使用一個棧的O(n)解法,代碼非常簡潔,棧記憶體儲的是高度遞增的下標。對於每一個長條圖高度,分兩種情況。1:當棧空或者當前高度大於棧頂下標所指示的高度時,當前下標入棧。否則,2:當前棧頂出棧,並且用這個下標所指示的高度計算面積。而這個方法為什麼只需要一個棧呢?因為當第二種情況時,for迴圈的迴圈下標回退,也就讓下一次for迴圈比較當前高度與新的棧頂下標所指示的高度,注意此時的棧頂已經改變由於之前的出棧。
這種方法其實是第二種方法的變體,因為其實我們對於任何一個bar都計算了以自己為目標高度的最大矩陣,只是因為有了棧的引入,我們能夠立即知道自己兩邊低於自己高度的bar的座標,節省了兩邊走的複雜度O(N)
實現中注意最後還要對剩下的棧做清空並且判斷,因為演算法中每次是對於前面的元素麵積進行判斷,所以迴圈結束中如果棧中仍有元素,還是要繼續維護面積直到棧為空白。
這道題思路還是比較繞的,要仔細想想才能理清。不過解法確實很簡練,總共只需要掃描一遍,所以時間複雜度是O(n),空間複雜度是棧的大小,最壞情況是O(n)。
1 public class Solution { 2 public int largestRectangleArea(int[] height) { 3 if (height == null || height.length == 0) { 4 return 0; 5 } 6 LinkedList<Integer> stack = new LinkedList<Integer>(); 7 int area = 0; 8 for (int i=0; i<height.length; i++) { 9 if (stack.size()==0 || height[stack.peek()]<height[i]) {10 stack.push(i);11 }12 else {13 int temp = stack.pop();14 int width = (stack.size()==0)? i : i-stack.peek()-1;15 area = Math.max(area, height[temp]*width);16 i--;17 }18 }19 while (stack.size()!=0) {20 int temp = stack.pop();21 int width = (stack.size()==0)? height.length : height.length-stack.peek()-1;22 area = Math.max(area, height[temp]*width);23 }24 return area;25 }26 }
Leetcode: Largest Rectangle in Histogram