LeetCode--221. 最大正方形

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

示例:

输入:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

输出: 4

我的思路:我用的是暴力,但是过程有所优化。我找的是遍历过程中该点最大的正方形边长。优化思路是:假设当前节点dp(i,j)为0,那正常后移一位计算dp(i,j+1)。如果do(i,j)==1,标记tmpRes = 1,接下来计算dp(i+1,j+1),如果也是1,那就计算这个点对应的这个列是否都为1,如果有其中一个不是1,那么后移,直接跳到计算dp(i,不为1的这一列后面一列)。如果dp(i+1,j+1)是0,也是这样后移。比如示例先计算dp(0,0)为起点,dp(1,1)为0,因为不管dp(0,1)是什么,以他为起点不会比前面的1大,所以下一个遍历直接跳到dp(0,2)。

代码如下:

    public static int maximalSquare(char[][] matrix) {
        int matrixRow = matrix.length;
        if (matrixRow == 0)
            return 0;
        int matrixCol = matrix[0].length;
        int res = 0;
        int[][] matrixInt = new int[matrixRow][matrixCol];
        boolean flag = false;
        for (int i = 0; i < matrixRow; ++i){
            for (int j = 0; j < matrixCol; ++j){
                matrixInt[i][j] = Integer.parseInt(String.valueOf(matrix[i][j]));
                if (matrixInt[i][j] > 0 )
                    flag = true;
            }
        }
        if(!flag)
            return 0;
        res = 0;
        int indexRow = 0;
        int indexCol = 0;
        while (true){
            if (indexCol >= matrixCol){
                if(res != 0 && res >= matrixRow -1 - indexRow){
                    break;
                }
                indexCol = 0;
                indexRow++;
            }
            //这个if判断是否超出坐标,也是终止条件
            if(indexRow >= matrixRow)
                break;
            if (matrixInt[indexRow][indexCol] == 1){
                int tmpRes = 1;
                int tmpRow = indexRow + 1;
                int tmpCol = indexCol + 1;
                flag = false;
                //如果下一个对角线超出坐标了
                if(tmpRow >= matrixRow || tmpCol >= matrixCol){
                    res = Math.max(res,tmpRes);
                    if(tmpCol >= matrixCol){
                        indexCol = 0;
                    }
                    indexRow++;
                    continue;
                }
                while (matrixInt[tmpRow][tmpCol] == 1){
                    for (int i = indexRow; i < tmpRow; ++i){
                        if(matrixInt[i][tmpCol] == 0){
                            indexCol = tmpCol;
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                        break;
                    for (int j = indexCol; j < tmpCol; ++j){
                        if(matrixInt[tmpRow][j] == 0){
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                        break;
                    tmpRow++;
                    tmpCol++;
                    tmpRes++;
                    if(tmpRow >= matrixRow || tmpCol >= matrixCol)
                        break;
                }
                if(tmpRow < matrixRow && tmpCol < matrixCol){
                    if(matrixInt[tmpRow][tmpCol] == 0){
                        indexCol = tmpCol;
                    }
                }
                res = Math.max(res,tmpRes);
            }
            //可以提前结束的条件
            if(res >= matrixCol -1 - indexCol && res != 0){
                if(res >= matrixRow -1 - indexRow){
                    break;
                }
                indexRow++;
                indexCol = 0;
            }else {
                indexCol++;
            }
        }
        return res * res;
    }

官方给出的动态规划思想:关键是找到如何找到局部最优?遍历过程中数组记录该点为右下角时候的最大边长为几。该点的最大长度由其上,左上,左,这三个决定的。值为这三个中最小的加1.如果该点为0,自然是0,不用计算其他。

猜你喜欢

转载自blog.csdn.net/lfanchenyu/article/details/106008935