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
.
给定一组非负数,然后求出最大面积(画到数轴上,宽度都是1)。
这道题感觉还是比较难的,反正我没有做出来。
刚开始我想的是比较暴力的算法,就是遍历每个数字,然后以这个数字为中心,向两边延伸,找到最大的面积(最小也是他本身)。但是这样超时了。
public class Solution { public int largestRectangleArea(int[] heights) { int len = heights.length; int high ,result = 0, ans; int[] flag = new int[len]; for( int i = 0;i<len;i++){ if( flag[i] == 1) continue; high = heights[i]; ans = high; int j = i+1; while( j<len){ if( heights[j] > high){ ans+=high; }else if( heights[j] == high){ ans+=high; flag[j] = 1; } else break; j++; } j = i-1; while( j >= 0){ if( heights[j] >= high){ ans+=high; } else break; j--; } result = result>ans?result:ans; } return result; } }
然后想的是利用动态规划,但是代码一直有问题,也没有通过。
后来看了答案, 发现也是类似动态规划的想法,运用得很巧妙,找到左边界和右边界,然后就顺利找出了。
左边界:指的是从0-i这个范围内,以heights[i]为高度,向左延伸的最大位置。
右边界同理。
public class Solution { public int largestRectangleArea(int[] heights) { int len = heights.length; int result = 0; if( len == 0) return 0; int[] left = new int[len]; int[] right = new int[len]; left[0] = 0; for( int i = 1;i<len;i++){ int CurLeft = i-1; while( CurLeft >= 0 && heights[CurLeft]>=heights[i]){ CurLeft = left[CurLeft]-1; } left[i] = CurLeft+1; } right[len-1] = len-1; for( int i = len-2;i>=0;i--){ int CurRight = i+1; while( CurRight<len && heights[CurRight]>=heights[i]) CurRight = right[CurRight]+1; right[i] = CurRight-1; } for( int i = 0;i<len;i++){ result = Math.max(result,(right[i]-left[i]+1)*(heights[i])); } return result; } }