• 221.最大正方形


    image-20200508141904109

    解法1(暴力解法)

    思路

    • 遍历数组,依次以每一个点作为正方形的左上角
    • 计算所能构成正方形的最大边长
    • 在最大正方形的范围内,边长从小到大增大。边长每增加1,则新增一行一列,判断新增的点是否为 '1',maxSide保存符合要求的边的值。
    • 注意细节处理

    代码

     
    /*
     *暴力解法
     *4ms
     */
    public int maximalSquare2(char[][] matrix){
            int maxSide=0;
            if(matrix==null||matrix.length==0||matrix[0].length==0) return maxSide;
            int r=matrix.length,c=matrix[0].length;
            for(int i=0;i<r;i++){
                for(int j=0;j<c;j++){
                    if(matrix[i][j]=='1'){
                        //一个值为1的点 可以构成一个边长为1的正方形
                        maxSide=Math.max(maxSide, 1);
                        //以当前点  作为 正方形的左上角顶点,计算能构成正方形的最大边长
                        int curMaxSide=Math.min(r-i, c-j);
                        for(int k=1;k<curMaxSide;k++){
                            boolean flag=true;
                            //判断正方形的右下角顶点是否为1  (对角线上)
                            if(matrix[i+k][j+k]=='0'){
                                break;
                            }
                            //新增一行一列 判断多出来的点是否为 '1' 不包含右下角顶点
                            for(int m=0;m<k;m++){
                                if(matrix[i+k][j+m]=='0'||matrix[i+m][j+k]=='0'){
                                    flag=false;
                                    break;
                                }
                            }
                            if(flag){
                                maxSide=Math.max(maxSide, k+1);
                            }else{
                                break;
                            }
                        }
                    }
                }
            }
            return maxSide*maxSide;
        }
    

    解法2(动态规划)

    官方思路

    • 通过动态规划降低时间复杂度,用dp(i,j)表示以(i,j)为右下角,且只包含1的正方形的边长的最大值。

    • 如何计算dp的值?

      • 如果该位置的值是0,则dp(i,j)=0

      • 如果该位置的值为1,则dp(i,j)的值由其上方,左方和左上方的三个相邻位置的dp值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加+1

        dp(i,j)=min(dp(i−1,j),dp(i−1,j−1),dp(i,j−1))+1

        推导过程链接: 1277.统计全为1的正方形子矩阵

      • 此外 需考虑边界条件。如果i和j中至少有一个为0,则以位置(i,j)为右下角的最大正方形的边长只能为1,即dp(i,j)=1

    image-20200508164708614

    代码

     /**
         * 6ms 动态规划
         * @param matrix
         * @return
         */
        public int maximalSquare3(char[][] matrix){
            int maxSide=0;
            if(matrix==null||matrix.length==0||matrix[0].length==0) return maxSide;
            int rows=matrix.length,columns=matrix[0].length;
            int[][] dp=new int[rows][columns];
            for(int i=0;i<rows;i++){
                for(int j=0;j<columns;j++){
                    if(matrix[i][j]=='1'){
                        if(i==0||j==0){
                            dp[i][j]=1;
                        }else{
                            dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]), dp[i-1][j-1])+1;
                        }
                        maxSide=Math.max(maxSide, dp[i][j]);
                    }
                }
            }
            return maxSide*maxSide;
        }
    
  • 相关阅读:
    pytest实现参数化(@pytest.mark.parametrize)
    pytest标记测试用例为预期失败(@pytest.mark.xfail)
    pytest标记跳过某些测试用例不执行
    pytest的conftest.py配置
    pytest之fixture使用
    模拟赛42 题解
    模拟赛41 题解
    一些可能永远用不到的性质
    补锅
    骗分杂谈
  • 原文地址:https://www.cnblogs.com/yh-simon/p/12851878.html
Copyright © 2020-2023  润新知