[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;*/ } }