最大矩阵的大小
矩阵只由0
和1
组成,求其中全部由1
组成的矩形中的最大的矩形面积:
int[][] map = {
{1, 0, 1, 1},
{1, 1, 1, 1},
{1, 1, 1, 0}
};
思路:
- 设置一个
height
数组,每迭代一行,就生成对应的height
数组(基于上一行对应的height
数组),height
数组的意义:该行的每个元素向上数,连续的1
的数量- 迭代完一行后,即对
height
数组处理- 遍历
height
数组,设置一个辅助栈stack
,设当前遍历的为height[i]
:如果栈为空或者栈顶(设栈顶为j
)对应的元素小于当前遍历的height
数组元素(即height[i] > height[j]
),则将当前height
数组的index(即i
)压入栈中;否则(即height[i] <= height[j]
)则弹出栈顶j
,设k
为新的栈顶,计算一个面积(i - k - 1) * height[j]
,然后继续比较,若任然如此,则继续按照此规则弹出,每次计算出的面积中取最大- 遍历完成之后,如果
stack
不为空,则栈中索引对应的height
数组元素必是递增的,所以从栈顶依次出栈,按照下面规则依次计算面积最大值:设栈顶弹出j
,k
为新的栈顶,面积=(height.length - k - 1) * height[j]
代码实现如下:
package com.lilydedbb;
import java.util.Stack;
/**
* Created by dbb on 2016/12/25.
*/
public class MaxRecSize {
public static int maxRecSize(int[][] map){
if(map == null || map.length == 0 || map[0].length == 0)
return 0;
int maxArea = 0;
int[] height = new int[map[0].length];
for(int i = 0; i < map.length; i++){ // 行迭代
for(int j = 0; j < map[0].length; j++){ // 列迭代
// 每迭代一行,就生成对应的height数组(基于上一行对应的height数组)
height[j] = (map[i][j] == 0) ? 0 : height[j] + 1;
}
// 每迭代一行,就依据当前的height数组,计算面积,然后于最大面积比较大小
maxArea = Math.max(maxRecFromBottom(height), maxArea);
}
return maxArea;
}
public static int maxRecFromBottom(int[] height){
if(height == null || height.length == 0)
return 0;
int maxArea = 0;
Stack<Integer> stack = new Stack<Integer>(); // 存储height数组的index
for(int i = 0; i < height.length; i++){
while(!stack.isEmpty() && height[i] <= height[stack.peek()]){
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int curArea = (i - k - 1) * height[j]; // 当前元素向左能够扩大的最大矩形面积
maxArea = Math.max(maxArea, curArea);
}
stack.push(i);
}
while (!stack.isEmpty()){
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int curArea = (height.length - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
return maxArea;
}
}