1.题目
给出的n个非负整数表示每个直方图的高度,每个直方图的宽均为1,在直方图中找到最大的矩形面积。
以上直方图宽为1,高度为[2,1,5,6,2,3]。
最大矩形面积如图阴影部分所示,含有10单位
2.算法
算法1:时间复杂度为O(n^2)
1.从左向右扫描,以i为左边界,从i往后扫描以j为右边界,这样以i和j为窗口可以把所有情况包括进内。
public int largestRectangleArea(int[] height) {
// write your code here
int largest = 0; //最大面积
for (int i = 0; i < height.length; i++) //以i为右边界找最大面积
{
int aera = 0; //局部面积
int high = height[i];
for (int j = i; j < height.length; i++) //以j为左边界找最大面积
{
if (high > height[j]) //找最小高度
{
high = height[j];
}
aera = (j - i + 1) * high;//局部最大值
if (aera > largest)
{
largest = aera;
}
}
}
return largest;
}
算法2:时间复杂度为O(n)
1.基本思路是维护一个递增的栈,栈内放的是数组下标,如果找到不是递增的第一个下标i
2,取出栈顶元素index,如果此时栈为空,则index为i之前最小的,应为栈内元素递增,
3,如果栈不为空,则计算局部最大值,(i - stack.peek() - 1) * height[index],直到栈内元素小于下标为i的值为直
public int largestRectangleArea(int[] height) {
// write your code here
if (height == null || height.length == 0)
{
return 0;
}
int max = 0;
LinkedList<Integer> stack = new LinkedList<Integer>();
for (int i = 0; i < height.length; i++) //从前往后扫描
{
while (!stack.isEmpty() && height[i] <= height[stack.peek()]) //找不是递增的数
{
int index = stack.pop();
int curArea = stack.isEmpty() ? i * height[index] : (i - stack.peek() - 1) * height[index]; //如果栈为空,则index为最小值
max = Math.max(curArea, max);
}
stack.push(i);
}
while (!stack.isEmpty()) //如果之后栈内还有数
{
int index = stack.pop();
int curArea = stack.isEmpty() ? height.length * height[index] : (height.length - stack.peek() - 1) * height[index];
max = Math.max(curArea, max);
}
return max;
}