1 public class Solution 2 { 3 public int LargestRectangleArea(int[] hist) 4 { 5 // The main function to find the 6 // maximum rectangular area under 7 // given histogram with n bars 8 int n = hist.Length; 9 // Create an empty stack. The stack 10 // holds indexes of hist[] array 11 // The bars stored in stack are always 12 // in increasing order of their heights. 13 Stack<int> s = new Stack<int>(); 14 15 int max_area = 0; // Initialize max area 16 int tp; // To store top of stack 17 int area_with_top; // To store area with top 18 // bar as the smallest bar 19 20 // Run through all bars of 21 // given histogram 22 int i = 0; 23 while (i < n) 24 { 25 // If this bar is higher than the 26 // bar on top stack, push it to stack 27 if (s.Count == 0 || hist[s.Peek()] <= hist[i]) 28 { 29 s.Push(i++); 30 } 31 32 // If this bar is lower than top of stack, 33 // then calculate area of rectangle with 34 // stack top as the smallest (or minimum 35 // height) bar. 'i' is 'right index' for 36 // the top and element before top in stack 37 // is 'left index' 38 else 39 { 40 tp = s.Peek(); // store the top index 41 s.Pop(); // pop the top 42 43 // Calculate the area with hist[tp] 44 // stack as smallest bar 45 area_with_top = hist[tp] * 46 (s.Count == 0 ? i : i - s.Peek() - 1); 47 48 // update max area, if needed 49 if (max_area < area_with_top) 50 { 51 max_area = area_with_top; 52 } 53 } 54 } 55 56 // Now pop the remaining bars from 57 // stack and calculate area with every 58 // popped bar as the smallest bar 59 while (s.Count > 0) 60 { 61 tp = s.Peek(); 62 s.Pop(); 63 area_with_top = hist[tp] * 64 (s.Count == 0 ? i : i - s.Peek() - 1); 65 66 if (max_area < area_with_top) 67 { 68 max_area = area_with_top; 69 } 70 } 71 72 return max_area; 73 } 74 }
参考:https://www.geeksforgeeks.org/largest-rectangle-under-histogram/
补充一个python的实现:
1 class Solution: 2 def largestRectangleArea(self, heights: 'List[int]') -> int: 3 heights.append(0)#默认最后补充一个0,方便统一处理 4 n = len(heights) 5 s = [] 6 max_area = 0#最大面积 7 tp = 0#栈顶索引 8 area_with_top = 0#临时面积 9 i = 0 10 while i < n: 11 if len(s) == 0 or heights[s[-1]] <= heights[i]: 12 s.append(i)#栈内记录的是高度递增的索引 13 i += 1 14 else:#遇到了高度比当前栈顶元素低的元素时, 15 tp = s.pop(-1)#清算栈内的元素的高度 16 if len(s) == 0: 17 area_with_top = heights[tp] * i#栈内没有元素,则宽度是i 18 else:#高度是栈顶元素,宽度是i - 1 - 前一个栈顶元素的索引 19 area_with_top = heights[tp] * (i - s[-1] - 1) 20 max_area = max(max_area,area_with_top)#更新最大值 21 # while len(s) > 0:#处理栈内剩余元素,处理流程和遇到一个 22 # tp = s.pop(-1) 23 # if len(s) == 0: 24 # area_with_top = heights[tp] * i 25 # else: 26 # area_with_top = heights[tp] * (i - s[-1] - 1) 27 # max_area = max(max_area,area_with_top) 28 return max_area
采用了一个小技巧,在heights最后补一个0,则21行到27行的代码就可以省略了。