leetcode hot 100- 84. 柱狀圖中最大的矩形
阿新 • • 發佈:2020-11-03
84. 柱狀圖中最大的矩形
思路一:暴力法
列舉每個柱子為高度的最大矩形的面積
實現:對每個高度的柱子向兩邊擴張,試圖尋找以當前高度為矩形的最大寬度
1 class Solution { 2 public int largestRectangleArea(int[] heights) { 3 4 // 對每個高度的柱子向兩邊擴張,試圖尋找以當前高度為矩形的最大寬度5 int maxArea = 0; 6 int len = heights.length; 7 for(int i = 0; i < len; i++){ 8 int leftBorder = i-1; 9 for(; leftBorder >= 0 && heights[leftBorder] >= heights[i]; leftBorder--); 10 int rightBorder = i+1; 11 for(; rightBorder < len && heights[rightBorder] >= heights[i]; rightBorder++); 12 maxArea = Math.max(maxArea, heights[i] * (rightBorder - leftBorder - 1)); 13 } 14 return maxArea; 15 } 16 }
leetcode執行用時:938 ms > 19.41%, 記憶體消耗:40.2 MB > 40.10%
複雜度分析:
時間複雜度:O(n2
空間複雜度:O(1)。
思路二:遞減棧
遞減棧,從棧頂到棧底的序列是一個降序序列,遞減 如果當前高度大於棧頂下標對應的高度,直接入棧,否則迴圈出棧,直至當前高度大於棧頂高度或者棧為空,每次出棧一個元素,用當前下標減去出棧下標再減一,得到寬度,乘以出棧下標對應的元素,得出面積 計算寬度,如果棧為空,左邊界為0,右邊界為i,否則左邊界為棧頂下標,右邊界為陣列長度 一次遍歷之後,出棧棧中剩餘元素, 出棧過程中如果當前出棧的元素等於棧頂下標對應的元素,持續出棧,直到棧頂下標元素小於當前元素的下標為止,因為高度相等的話只需要統計最左邊的柱子和他的寬度即可,中間的沒必要統計,因為都一樣。 如果棧為空,左邊界為0,否則左邊界為棧頂下標,右邊界為陣列長度1 class Solution { 2 public int largestRectangleArea(int[] heights) { 3 4 Stack<Integer> stack = new Stack<>(); 5 int len = heights.length; 6 int maxArea = 0; 7 for(int i = 0; i < len; i++){ 8 // 如果當前高度大於棧頂下標對應的高度,直接入棧,否則迴圈出棧,直至當前高度大於棧頂高度或者棧為空 9 while(!stack.isEmpty() && heights[i] < heights[stack.peek()]){ 10 int index = stack.pop(); 11 int width = 0; 12 // 計算寬度,如果棧為空,左邊界為0,右邊界為i, 否則左邊界為棧頂下標,右邊界為陣列長度 13 if(stack.isEmpty()){ 14 width = i; 15 }else{ 16 width = i - stack.peek() - 1; 17 } 18 maxArea = Math.max(maxArea, width * heights[index]); 19 } 20 stack.push(i); 21 } 22 // 一次遍歷之後,出棧棧中剩餘元素, 23 while(!stack.isEmpty()){ 24 int index = stack.pop(); 25 // 出棧過程中如果當前出棧的元素等於棧頂下標對應的元素, 26 // 持續出棧,直到棧頂下標元素小於當前元素的下標為止 27 while(!stack.isEmpty() && heights[stack.peek()] == heights[index]){ 28 stack.pop(); 29 } 30 int width = 0; 31 // 如果棧為空,左邊界為0, 否則左邊界為棧頂下標,右邊界為陣列長度 32 if(stack.isEmpty()){ 33 width = len; 34 }else{ 35 width = len - stack.peek() - 1; 36 } 37 maxArea = Math.max(maxArea, width * heights[index]); 38 } 39 return maxArea; 40 } 41 }
leetcode執行用時:12 ms > 71.41%, 記憶體消耗:39.9 MB > 63.66%
複雜度分析:
時間複雜度:O(n)。每個元素下標最多隻被入棧一次以及出棧一次,所以 時間複雜度為O(n)。
空間複雜度:O(n)。空間花費取決於棧的大小,棧的大小最大為O(n-1), 即當heights[]陣列遞增排列時,所有元素的下標都會入隊,所以空間複雜度為O(n)。