Largest Rectangle in Histogram

Question: 

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.

histogram

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

histogram

The largest rectangle is shown in the shaded area, which has area = 10 unit.

 

Example:

Given height = [2,1,5,6,2,3],
return 10.

 

Analysis:
1. 暴力的解法:用两个指针(i,j),遍历以i为起始,j为终点构成的矩形的面积。高度由i~j中高度最短的那根决定。高度可以在j指针向右移动的时候,用一个变量保存所经过点的高度的最小值。时间复杂度O(n ^ 2)。
 
2. 递增stack解法(code见下):遍历数组的同时往stack中push每一个值,保证stack中的值是一个递增的序列。push的时候分两种情况:如果该值大于或者等于stack顶部的值,直接将该值push进去;如果小于stack顶部的值,则将stack顶部
的值pop,同时计算以该值为高度的最大矩形的面积(因为stack里面是递增序列,矩形的左顶点就是pop的那个值之前一位的index,右顶点就是将它pop出去的那个值的index)。当height数组中所有的值都从stack中pop出去以后,便可得到面积的最大值。
这个解法比较难理解,可以参考这位博主的文章结合图进行理解:http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html
 
 
Code:
 1 public class Solution {
 2     /**
 3      * @param height: A list of integer
 4      * @return: The area of largest rectangle in the histogram
 5      */
 6     public int largestRectangleArea(int[] height) {
 7         int size = height.length;
 8         if(height == null || size == 0) {
 9             return 0;
10         }
11         
12         int max = 0;
13         Stack<Integer> stack = new Stack<Integer>();
14         for(int i = 0; i <= size; i++) {
15             int curtHeight = i == size ? -1 : height[i];
16             while(!stack.isEmpty() && curtHeight < height[stack.peek()]) {
17                 int h = height[stack.pop()];  //以该木头为高度所能构成的最大矩形
18                 int w = stack.isEmpty() ? i : i - stack.peek() - 1;
19                 max = Math.max(max, h * w);
20             }
21             stack.push(i);
22         }
23         
24         return max;
25     }
26 }

 

Complexity:
时间复杂度是O(n)。不能因为看见两层循环就以为时间复杂度是O(n ^ 2)。这个程序中,height数组里的每个数都会入栈一次,然后出栈一次,所以总共的复杂度是线性的O(n)。
 
 

posted on 2016-01-22 13:59  BillZ  阅读(128)  评论(0编辑  收藏  举报

导航