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
.
思路:
松祚向右,分别以每一个为左起始点,向右找到面积的最大值,即先固定左端点,从此点开始遍历到结尾,以每一个点作为右端点(每一步中记录这个左右端点之间的最小值),用最小值乘以左右端点下标之差,与面积比较,求出面积的最大值。此为暴力解法,复杂度为O(n^2)
1 public int largestRectangleArea(int[] height) { 2 if (height == null || height.length <= 0) return 0; 3 int maxArea = 0; 4 for (int i = 0; i < height.length; i++) { 5 int minHeight = height[i]; 6 for (int j = i; j < height.length; j++) { 7 if (height[j] < minHeight) { 8 minHeight = height[j]; 9 } 10 int tempArea = minHeight * (j - i + 1); 11 if (tempArea > maxArea) { 12 maxArea = tempArea; 13 } 14 } 15 } 16 return maxArea; 17 }
复杂度较高,考虑其他解法,由于每个柱的作用只有两种,以自己做高向外扩展;以别人做高自己被扩展。每个柱以自己做高时,找到在其之前的连续的比它高的元素,计算面积;以其他做高自己被扩展时,将信息记录等到后面可以扩展到它时再计算。
基于上面的思路,需要记录的是一个高度递增的序列,并记录高度所对应的下标。
Case 1: 当前高度大于栈顶元素的高度
将当前高度和下标入栈作为面积最大的矩形起点的一个备选方案
Case 2: 当前高度等于栈顶元素的高度
忽略
Case 3: 当前高度小于栈顶元素的高度
将高度栈顶出栈直到栈顶高度小于当前高度,并在每次出栈过程中计算面积并更新最大面积,最后将当前高度和从栈中取出的最小下标入栈
栈中记录的是每一个备选的起点,每一次遍历时,就是将当前的当做终点,与栈中所有的备选起点组成矩形,更新最大面积的过程。每次更新栈中元素,即记录以当前的高度为高时,左端最远能扩展到的下标。
1 public int largestRectangleArea(int[] height) { 2 if (height == null || height.length == 0) return 0; 3 4 int maxArea = 0; 5 Stack<Integer> stackHeight = new Stack<Integer>(); 6 Stack<Integer> stackIndex = new Stack<Integer>(); 7 8 for (int i = 0; i < height.length; i++) { 9 //case 1 10 if (stackHeight.isEmpty() || height[i] > stackHeight.peek()) { 11 stackHeight.push(height[i]); 12 stackIndex.push(i); 13 } else if (height[i] < stackHeight.peek()) { 14 // case 3 15 int lastIndex = 0; 16 while (stackHeight.isEmpty() == false && height[i] < stackHeight.peek()) { 17 lastIndex = stackIndex.pop(); 18 int tempArea = stackHeight.pop() * (i - lastIndex); 19 if (maxArea < tempArea) { 20 maxArea = tempArea; 21 } 22 } 23 stackHeight.push(height[i]); 24 stackIndex.push(lastIndex); 25 } 26 } 27 28 while(stackHeight.isEmpty() == false) { 29 int tempArea = stackHeight.pop() * (height.length - stackIndex.pop()); 30 if (tempArea > maxArea) { 31 maxArea = tempArea; 32 } 33 } 34 return maxArea; 35 }