问题描述:给一个矩阵 均是 0或者1 求出这个矩阵的最大子矩阵的面积
解题思路: 将大矩阵分成一行一行的,计算当前行的最大子矩阵的面积 最后求最大 而在每一行计算每一列的最大拓展面积 这里用到了栈 栈自顶向底 由大向小排序 对于每一列 向左的话 就是栈的下一个k+1 向右边的话 就是比它小的那个i-1 即无论向哪边拓展 都是第一个比当前小的那个。这样的话 对于每一列的最大拓展面积就是(i-1-(k+1)+1)* height[j]=(i-k-1)height[j]
复杂度分析:对于每一行中的M列 一个数需要进栈一次 出栈一次 复杂度是M 一共是n行 所以复杂度一共是M*N
package Charpter1;
import java.util.Stack;
public class MaxPecSize {
public static void main(String[]args){
int [][] map ={{1,1,0},{1,0,1},{1,1,1}};
System.out.println(maxRecSize(map));
// System.out.println(map[0].length);
}
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[j] = map[i][j]==0 ? 0:height[j]+1;
}
//System.out.println(maxArea);
maxArea = Math.max(maxRecFromBotton(height),maxArea);//计算当前行的最大拓展面积
}
return maxArea;
}
public static int maxRecFromBotton(int[] height){
if (height == null || height.length==0){
return 0;
}
int maxsize = 0;
Stack<Integer> stack = new Stack<>();
for (int i = 0;i<height.length;i++) {
while ((!stack.isEmpty()) && height[i]<=height[stack.peek()]){//相等没关系 相等的话 j列和i列相同 对求最大没有影响
int j = stack.pop();
int k =stack.isEmpty()?-1:stack.peek();
int curArea =(i-k-1)*height[j];
maxsize = Math.max(curArea,maxsize);
}
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];
maxsize = Math.max(maxsize,curArea);
}
return maxsize;
}
}