动态规划ing-最大正方形|Java 刷题打卡

493 阅读3分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看<活动链接>

【Java 刷题打卡 】刷题比玩游戏好多了,成就感越来越强,每天坚持刷几道题,每天锻炼30分钟,等8块腹肌,等大厂offer.

那就干吧! 这个专栏都是刷的题目都是关于动态规划的,我会由浅入深、循序渐进,刷题就是这样需要连续不断的记忆--艾宾浩斯记忆法2121112。动态规划的内容不多,但是都是每个程序员必备的

这是一道比较简单的题目😄😄😄 \color{green}{这是一道比较简单的题目😄 😄 😄 ~}

什么题可以选择动态规划来做?

1.计数

  • 有多少种方式走到右下角
  • 有多少种方法选出k个数是的和是sum

2.求最大值最小值

  • 从左上角走到右下角路径的最大数字和
  • 最长上升子序列长度

3.求存在性

  • 取石子游戏,先手是否必胜
  • 能不能选出k个数使得和是sum

4.综合运用

  • 动态规划 + hash
  • 动态规划 + 递归
  • ...

leecode 221. 最大正方形

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

示例 1:

image.png

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]

输出:4

image.png

输入:matrix = [["0","1"],["1","0"]]

输出:1

示例 3:

输入:matrix = [["0"]]

输出:0

提示:

m == matrix.length

n == matrix[i].length

1 <= m, n <= 300

matrix[i][j] 为 '0' 或 '1'


--

❤️❤️❤️❤️

2.1. 动态规划组成部分1:确定状态

简单的说,解动态规划的时候需要开一个数组,数组的每个元素f[i]或者f[i][j]代表什么,类似数学题中x, y, z代表什么

最后一步

image.png

我们用这个事例来讲解

我们定义d[i][j]为 最大正方形的边长 - 1

如果是一个正方形的话,计算d[i][j]的最大边,就需要以d[i-1][j],d[i][j-1],d[i-1][j-1]它们三的最小值作为边,如图,这三个值都是1,所以 边长 = 1 + 1 =2

  • 假如,i,j-2和i-1,j-2 的值都为1,那么它就是一个边长为三的正方形。

  • 要想计算i,j的边长,就要计算d[i-1][j],d[i][j-1],d[i-1][j-1],很明显,根据上面步骤,我们得出边长为2,所以边长 = 2 + 1 , 面积就为9.

1.2. 动态规划组成部分2:转移方程

dp[i][j] = min{d[i-1][j],d[i][j-1],d[i-1][j-1]} + 1

1.3. 动态规划组成部分3:初始条件和边界情况

1.根其他类型题目一样,先考虑两边,在考虑中间,i = 0 或j = 0 时,边长 = 1

  1. 定义一个变量为最大边长maxSide ,因为遍历到后面有可能不是最大边。

1.4. 动态规划组成部分4:计算顺序

依次计算。i去遍历j

棒!😄😄😄 \color{green}{棒!😄 😄 😄 ~}

参考代码

NICE太简单啦😄😄😄 \color{red}{NICE太简单啦😄 😄 😄 ~}

java版

class Solution {
    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;
    }
}


真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️