LeetCode OJ --问题与解答 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.

思路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


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;
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值