有一个两维的矩阵,里面的值是 '0' 和 '1',找到面积最大的里面的值都是'1'的矩阵。
1 | 1 | 0 | 1 | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 1 | 1 | 0 |
0 | 1 | 1 | 1 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 1 | 0 | 1 |
记得以前的最大面积的直方图吗?不熟悉这个问题的请先看我的之前的post。(只要会求最大面积的直方图,这个问题就会很简单了)
我们可以将这个矩阵转化成直方图的想法来。
对于矩阵的第一行,对应的直方图为:
1 | 1 | 0 | 1 | 0 | 0 | 0 |
对于矩阵的第二行,对应的直方图为:
2 | 2 | 0 | 2 | 1 | 1 | 0 |
所以,最终我们会有matrix.length个直方图,取最大的那个面积就是,最大的都是1的矩形面积了。
代码:
public int maximalRectangle(char[][] matrix) {
int maxArea = 0;
int m = matrix.length;
if (m == 0) {
return 0;
}
int n = matrix[0].length;
int[] heights = new int[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
heights[j] = (matrix[i][j] == '0' ? 0 : heights[j] + 1);
}
maxArea = Math.max(maxArea, largestRectangleAreaStack(heights));
}
return maxArea;
}
求最大直方图的代码:
public int largestRectangleAreaStack(int[] heights) {
int i = 0;
int maxArea = 0;
int curArea = 0;
Stack<Integer> store = new Stack<>(); // to store the left smaller index
while (i < heights.length) {
if (store.empty() || heights[store.peek()] <= heights[i]) {
store.add(i);
i++;
} else {
int curTop = store.pop();
// the ‘left smaller index’ is previous (previous to tp) item in stack and ‘right smaller index’ is ‘i’ (current index).
if (!store.isEmpty()) {
curArea = heights[curTop] * (i - store.peek() - 1);
} else {
curArea = heights[curTop] * i;
}
maxArea = Math.max(maxArea, curArea);
}
}
while (!store.isEmpty()) {
int curTop = store.pop();
if (!store.isEmpty()) {
curArea = heights[curTop] * (i - store.peek() - 1);
} else {
curArea = heights[curTop] * i;
}
maxArea = Math.max(maxArea, curArea);
}
return maxArea;
}