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
.
思路1
1 暴力解法,把每个可能的长方形面积都计算,需要O(n^2)的时间。
2 需要裁减,每次选取右边的时候,可以发觉并不是每个右边都需要计算面积。当要计算某个X(height[k])为右边时,看看它右边Y(如果有)height[k+1],如果比X大,那么必然会选取Y作为右边,因为他为右界面积更大。
代码1
public int largestRectangleArea(int[] height) {
if(height.length ==0){
return 0;
}
int maxArea = 0;
int n = height.length;
for(int rightside=0;rightside<n;rightside++){
for(int testside =rightside+1;testside<n;testside++){
if(height[testside]<height[testside-1]){
rightside = testside-1;
break;
}
else{
rightside = testside;
}
}
int lowest = height[rightside];
for(int leftside = rightside;leftside>=0;leftside--){
if(height[leftside] < lowest){
lowest = height[leftside];
}
int curArea = (rightside-leftside+1)* lowest;
if(curArea > maxArea){
maxArea = curArea;
}
}
}
return maxArea;
}
思路2
1 http://www.youtube.com/watch?v=E5C5W6waHlo
2 第一次处理或者很长时间没碰怎么思考出这道题的思路?我是这样想的:如果一会儿高,一会儿低,没有规则。但是如果从左到右高度递增,那么只要计算以计算(n-j)*height[j]就可以,一共n次就可以完成。那么怎么样使左到右递增呢?碰到右边X比左边小了,就让左边比他高的长方形面积都计算出来,然后把这些高的给去掉,再把X那个放进去就又是递增的数组了。
3 但是不管怎么想,这道题都是很牵强的想出的思路。只能再多练几次,foudation很重要。
4 另外其实可以用一个栈来记录index,思路是一样的。
代码2
public class Solution {
public int largestRectangleArea(int[] height) {
if(height.length ==0){
return 0;
}
int maxArea = 0;
LinkedList<Integer> heightstack = new LinkedList<Integer>();
LinkedList<Integer> indexstack = new LinkedList<Integer>();
for(int i =0;i<height.length;i++){
if(heightstack.isEmpty() || heightstack.peek() <=height[i]){
heightstack.push(height[i]);
indexstack.push(i);
}
else if(heightstack.peek() > height[i]){
int j =0;
while (!heightstack.isEmpty() && heightstack.peek() > height[i]) {
j = indexstack.pop();
int curArea = (i-j)*heightstack.pop();
if(curArea>maxArea){
maxArea = curArea;
}
}
heightstack.push(height[i]);
indexstack.push(j);
}
}
while(!heightstack.isEmpty()){
int curArea = (height.length - indexstack.pop()) * heightstack.pop();
if(curArea>maxArea){
maxArea = curArea;
}
}
return maxArea;
}
}