柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]
。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10
个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
解法一
最差时O(n^2) 时间复杂度,对每个heights[i],分别向左向右遍历原数组,记录以该height[i]为高的矩形面积。
代码一
class Solution {
public int largestRectangleArea(int[] heights) {
int maxValue = 0;
if(heights == null || heights.length==0){
return 0;
}
int[] size = new int[heights.length];
for(int i=0;i<heights.length;i++){
size[i] = heights[i];
//向右
for(int j=i+1;j<heights.length;j++){
if(heights[j]<heights[i])
break;
else
size[i]+=heights[i];
}
//向左
for(int j=i-1;j>=0;j--){
if(heights[j]<heights[i])
break;
else
size[i]+=heights[i];
}
}
//遍历数组
for(int i=0;i<size.length;i++){
if(size[i]>maxValue){
maxValue = size[i];
}
}
return maxValue;
}
}
解法二
基本思想:
- 对原数组排序,如[2,1,5,6,2,3],排序后为[1,2,2,3,5,6],那么只需要再遍历一遍,取Max(1*6,2*5,2*4,3*3,5*2,6*1)即可。
实际做法:
代码二
class Solution {
//http://chuansong.me/n/390896436960
public int largestRectangleArea(int[] heights) {
if(heights == null || heights.length==0){
return 0;
}
//最大值
int maxValue = 0;
Stack<Integer> res = new Stack<Integer>();
int i=0;
for(;i<heights.length;i++){
//栈为空,或栈顶元素top对应的heights[top]小于heights[i],入栈
if(res.empty() || heights[res.peek()] <= heights[i])
res.push(i);
else{
//heights[i]>heights[top],栈顶元素出栈
int top = res.pop();
//求矩形长度
int index = res.empty() ? -1:res.peek();
maxValue = Math.max(maxValue,heights[top] * (i-1-index));
//再次比较 heights[i]与此时的栈顶元素
i--;
}
}
while(!res.empty()){
//对每个栈顶元素top 求矩形面积
int top = res.pop();
int index = res.empty() ? -1:res.peek();
maxValue = Math.max(maxValue,heights[top] * (i-1-index));
}
return maxValue;
}
}