leetcode--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.

leetcode--Largest Rectangle in Histogram

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

leetcode--Largest Rectangle in Histogram

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.

题意:求连续的最大矩形。

分类:数组,栈

解法1:

 此解法的核心思想为:一次性计算连续递增的区间的最大面积,并且考虑完成这个区间之后,考虑其前、后区间的时候,不会受到任何影响。也就是这个连续递增区间的最小高度大于等于其前、后区间。

这个方法非常巧妙,最好通过一个图来理解:

leetcode--Largest Rectangle in Histogram

假设输入直方图为:int[] height = {2,7,5,6,4}.

这个方法运行的时候,当遇到height[2] == 5的时候,发现其比之前一个高度小,则从当前值(5)开始,向左搜索比当前值小的值。当搜索到最左边(2)时,比5小,此时计算在height[0]和height[2]之间的最大面积,注意不包括height[0]和和height[2]。height[1]以红色标出的这个区域就被计算完成。同样的方法,计算出绿色和粉色的面积。

因此这个方法需要使用两个栈。第一个栈为高度栈heightStack,用于记录还没有被计算过的连续递增的序列的值。第二个栈为下标栈indexStack,用于记录高度栈中对应的每一个高度的下标,以计算宽度。

算法具体执行的步骤为:

若heightStack为空或者当前高度大于heightStack栈顶,则当前高度和当前下标分别入站(下面有一个解法可以只用一个栈即可,用栈来保存下标,而高度由下标很容易得到)。所以heightStack记录了一个连续递增的序列。

若当前高度小于heightStack栈顶,heightStack和indexStack出栈,直到当前高度大于等于heightStack栈顶。出栈时,同时计算区间所形成的最大面积。注意计算完之后,当前值入栈的时候,其对应的下标应该为最后一个从indexStack出栈的下标。比如height[2]入栈时,其对应下标入栈应该为1,而不是其本身的下标2。如果将其本身下标2入栈,则计算绿色区域的最大面积时,会忽略掉红色区域。

[java] view plain copy
  1. public class Solution {  
  2.     public int largestRectangleArea(int[] height) {  
  3.         int len = height.length;  
  4.         int area = 0;  
  5.         Stack<Integer> heightStack = new Stack<Integer>();  
  6.         Stack<Integer> indexStack = new Stack<Integer>();  
  7.         for(int i=0;i<len;i++){  
  8.             if(heightStack.isEmpty()||height[i]>=height[i-1]){  
  9.                 heightStack.push(height[i]);  
  10.                 indexStack.push(i);  
  11.             }else{  
  12.                 int j = 0;    
  13.                 while (!heightStack.empty() && heightStack.peek() > height[i]) {    
  14.                     j = indexStack.pop();    
  15.                     int currArea = (i - j) * heightStack.pop();    
  16.                     if (currArea > area) {    
  17.                         area = currArea;    
  18.                     }    
  19.                 }    
  20.                 heightStack.push(height[i]);    
  21.                 indexStack.push(j);   
  22.             }  
  23.         }  
  24.         while (!heightStack.empty()) {    
  25.             int currArea = (height.length - indexStack.pop()) * heightStack.pop();    
  26.             if (currArea > area) {    
  27.               area = currArea;    
  28.             }    
  29.         }    
  30.         return area;  
  31.     }  
  32. }  




原文链接http://blog.****.net/crazy__chen/article/details/48323505