题目描述:
LeetCode_85:最大矩形
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例:
输入:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
输出: 6
主要思路:
利用单调栈,与工藤新木:柱状图中最大的矩形非常有关联,关键是要具体化出来到柱状图,直接复用其代码即可。
![fca76c4f79531a05d4f775bb657c1e83.png](https://img-blog.csdnimg.cn/img_convert/fca76c4f79531a05d4f775bb657c1e83.png)
解题如下:
class Solution {
public int maximalRectangle(char[][] matrix) {
// 长度为0的校验
if (matrix.length == 0) {
return 0;
}
int max = 0;
int[] heights = new int[matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
// 构造每一行的柱状图,直接再用84题的解题代码
for (int j = 0; j < matrix[0].length; j++) {
heights[j] = (matrix[i][j] == '1' ? heights[j] + 1 : 0);
}
max = Math.max(max, largestRectangleArea(heights));
}
return max;
}
public int largestRectangleArea(int[] heights) {
// 初始化栈,存位置-1,压底
Stack<Integer> posStack = new Stack<>();
posStack.push(-1);
// 最大面积
int maxArea = 0;
for (int i = 0; i <= heights.length; i++) {
// 当前值比栈顶大,即压栈
if (i < heights.length && heights[i] >= (posStack.peek() == -1 ? -1 : heights[posStack.peek()])) {
posStack.push(i);
}
else {
// 已到头了,挨个向前把每个面积都算一下
if (i >= heights.length) {
while (posStack.peek() != -1) {
maxArea = getMaxArea(posStack, maxArea, i, heights[posStack.peek()]);
}
}
// 未到头时,当前值比栈顶小的,则向前计算面积,直到比栈顶大,压栈
else {
while (heights[i] < (posStack.peek() == -1 ? -1 : heights[posStack.peek()])) {
maxArea = getMaxArea(posStack, maxArea, i, (posStack.peek() == -1 ? -1 : heights[posStack.peek()]));
}
posStack.push(i);
}
}
}
return maxArea;
}
private int getMaxArea(Stack<Integer> posStack, int maxArea, int i, int height) {
posStack.pop();
int area = height * (i - posStack.peek() - 1);
return area > maxArea ? area : maxArea;
}
}
父贴子:工藤新木:单调栈算法