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.
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.
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)。