问题
直方图是排列在同一基线上的一系列矩形组成的多边形,求解其中面积最大的矩形
不完整子问题栈的线性搜索
有很多方法解决这个问题,基于栈的方法如下,首先按照从做至右的顺序来处理元素,并将已经开始但尚未完成的子直方图信息保存在一个栈中,如果栈为空,通过将元素压入栈来开启一个新的子问题,否则,将元素与栈顶元素比较,如果新元素大,那么将其入栈,如果两者相等,跳过,继续处理下一个新元素。
如果新元素小,那么用栈顶元素更新最大区域,并结束最顶层子问题,然后删除栈顶元素,保持当前的新元素并重复上述过程,这样,所有的子问题都会结束直到栈空,或者栈顶元素小于或等于新元素,导致上述行为,如果所有元素都被处理过而栈仍然不为空,那么用栈顶元素更新最大区域来解决剩余的子问题
代码
private class StackItem {
public int height;
public int index;
public StackItem(int height, int index) {
this.height = height;
this.index = index;
}
}
long maxRectangleArea(int A[], int n) {
long maxArea = 0;
if (A == null || A.length == 0) {
return maxArea;
}
Stack<StackItem> S = new Stack<>();
S.push(new StackItem(Integer.MIN_VALUE, -1));
for (int i = 0; i <= n; i++) {
StackItem cur = new StackItem(i < n ? A[i] : Integer.MIN_VALUE, i);
if (cur.height > S.peek().height) {
S.push(cur);
continue;
}
while (S.size() > 1) {
StackItem prev = S.peek();
long area = (i - prev.index) * prev.height;
if (area > maxArea) {
maxArea = area;
}
prev.height = cur.height;
if (prev.height > S.get(S.size() - 2).height) {
break;
}
S.pop();
}
}
return maxArea;
}