[leedcode 84] 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.

public class Solution {
    public int largestRectangleArea(int[] height) {
        //维护一个递增的栈,栈保存的是数组下标
        /*遍历height数组,
        1 如果stack为空或者当前元素的高度大于等于height stack顶元素(前一个元素)的高度 => 把当前高度的index添加到stack顶
        2 如果当前元素的高度小于height stack顶元素的高度 => 持续弹栈直到当前元素的高度大于栈顶元素,并每次都计算面积(height[temp]*(stack           .empty()?i:(i-stack.peek()-1)),保存最大面积。
        3 本题有一个讨巧之处,为了防止最后栈不为空,在height的最后一位补0 ,可以使栈中所有元素的弹出*/
        int res=0;
        if(height==null||height.length<1) return res;
        height=Arrays.copyOf(height,height.length+1);
        height[height.length-1]=0;
        int i=0;
        Stack<Integer> stack=new Stack<Integer>();
        while(i<height.length){
            if(stack.empty()||height[i]>=height[stack.peek()]){
                stack.push(i++);
            }else{
                int temp=stack.pop();
                res=Math.max(res,height[temp]*(stack.empty()?i:(i-stack.peek()-1)));
            }
        }
        return res;
      /*  只要知道第i个条左边连续多少个(a)比他高   右边连续多少个(b)比他高  那么以这个条为最大高度的面积就是hi*(a+b+1);
        可以发现   当第i-1个比第i个高的时候   比第i-1个高的所有也一定比第i个高  

        于是可以用到动态规划的思想

        令left[i]表示包括i在内比i高的连续序列中最左边一个的编号   right[i]为最右边一个的编号

        那么有:当h[left[i]-1]>=h[i]]时   left[i]=left[left[i]-1]  从前往后可以递推出left[i]   

        同理:当h[right[i]+1]>=h[i]]时   right[i]=right[right[i]+1]   从后往前可递推出righ[i]

        最后答案就等于 max((right[i]-left[i]+1)*h[i])了,但是结果是TLE*/
        /*int res=0;
        if(height==null||height.length<1) return res;
        int h[]=new int[height.length+2];
        for(int i=1;i<h.length-1;i++){
            h[i]=height[i-1];
        }
        h[0]=-1;
        h[h.length-1]=-1;
        int left[]=new int[height.length+1];
        int right[]=new int[height.length+1];
        for(int i=1;i<=height.length;i++){
            left[i]=i;right[i]=i;
        }
        for(int i=1;i<=height.length;i++){
            while(h[left[i]-1]>=h[i]){
                left[i]=left[left[i]-1];
            }
        }
        for(int i=1;i<=height.length;i++){
            while(h[right[i]+1]>=h[i]){
                right[i]=right[right[i]+1];
            }
        }
        for(int i=1;i<h.length-1;i++){
            res=Math.max(res,h[i]*(right[i]-left[i]+1));
        }
        return res;*/
    }
}
原文地址:https://www.cnblogs.com/qiaomu/p/4649358.html