2022.12.11最大正方形

1 力扣题221:最大正方形

1.1 题目描述

在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。

1.2 思路分析

1.2.1 由回溯为切入点

在这个问题中,由于是在二维数组中进行搜索,首先考虑深搜,深搜的一个经典实现是遍历数组,对每个点进行上下左右搜索,或者在其中再构建辅助数组,但是这种方式在这个场景不成立,因为若以遍历当前元素为左上角进行正方形判断,若判断出正方形辅助数组相应位置清零,此时依然有一些情况被忽略(实际深搜真实数组上,判断在辅助数组上),所以不可取。正确方式是不进行剪枝,即抛弃辅助数组,直接暴力搜索,判断正方形通过不断地加一行和一列来实现

1.2.2 动态规划

涉及到二维数组的场景也可用动态规划来解决。dp[i][j]表示以i,j位置为右下角的最大正方形,状态转移方程为若该位置为0,则为0,若该位置为1,则dp(i,j)=min(dp(i−1,j),dp(i−1,j−1),dp(i,j−1))+1,可用假设证明的思路证明其具有最优子结构

1.3 代码实现

1.3.1 由回溯切入

public int maximalSquare(char[][] matrix) {
        //辅助表,正方形新增一行一列进行判断
        this.matrix = matrix;
        int max_length = 0;
        for (int i=0; i<matrix.length; i++) {
            for (int j=0; j<matrix[0].length; j++) {
                if (matrix[i][j]=='1') {
                    int length = seek_tangle(i,j);
                    max_length = Math.max(length,max_length);
                }
            }
        }
        return max_length*max_length;
    }

    public int seek_tangle(int i, int j) {
        int length = 1;
        while (true) {
            if (i+length<matrix.length && j+length<matrix[0].length) {
                for (int p=j; p<j+length; p++) {
                    if (matrix[i+length][p]=='0')
                        return length;
                }
                for (int p=i; p<=i+length; p++) {
                    if (matrix[p][j+length]=='0')
                        return length;
                }
                length += 1;
            } else
                break;
        }
        return length;
    }

1.3.2 动态规划

public int maximalSquare(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]);
                }
            }
        }
        int maxSquare = maxSide * maxSide;
        return maxSquare;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值