读书笔记-求最大子矩阵的大小

问题描述:给一个矩阵 均是 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;

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值