Largest Rectangle in Histogram

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 }

 

你可能感兴趣的:(in)