题目:
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 heights = [2,1,5,6,2,3]
,
return 10
.
题意及分析:给出一系列相邻的直方图,求出能够组成的最大面积。
方法一:暴力求解,查找查找两个数组成的子数组,作为最左直方和最右直方,然后查找其中最低的直方,得到面积,这样的数组一共有2^n个,查找最低直方为o(n),所以时间复杂度为o(n^3),会超时,略
方法二:可以从每一个直方往两边走,以自己的高度为标准,直到两边低于自己的高度为止,然后用自己的高度乘以两边走的宽度得到矩阵面积。因为对于任意一个bar都计算了以自己为目标高度的最大矩阵,所以最好的结果一定会被取到。每次往两边走的复杂度是O(n),总共有n个bar,所以时间复杂度是O(n^2),也会超时。。。
方法三:如果已知height数组是升序的,应该怎么做?比如1,2,5,7,8那么就是(1*5) vs. (2*4) vs. (5*3) vs. (7*2) vs. (8*1)也就是max(height[i]*(size-i)),使用栈的目的就是构造这样的升序序列,按照以上方法求解。在构造栈的时候保存可能的最大值
代码:
class Solution { public int largestRectangleArea(int[] heights) { if(heights == null || heights.length==0) return 0; int tempResult = 0; Stack<Integer> stack = new Stack<>(); stack.push(heights[0]); for(int i=1;i<heights.length;i++){ if(heights[i]>=stack.peek()){ //升序 stack.push(heights[i]); }else{ if(!stack.isEmpty()){ int count = 0; int min = stack.peek(); while(!stack.isEmpty() && stack.peek()>heights[i]){ if(stack.peek()<min){ min = stack.peek(); } stack.pop(); count ++; if(tempResult<count*min){ tempResult = count*min; } } int j=0; while(j<=count){ stack.push(heights[i]); j++; } } } } for(int i=heights.length-1;i>=0;i--){ int x= stack.pop(); if((heights.length-i)*x>tempResult){ tempResult =(heights.length-i)*x; } } return tempResult; } }