Leetcode 221. 最大正方形

news/2024/11/28 10:39:29/
  • Leetcode 221. 最大正方形
  • 题目
    • 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。
    • m == matrix.length
    • n == matrix[i].length
    • 1 <= m, n <= 300
    • matrix[i][j] 为 ‘0’ 或 ‘1’
  • 解法
    • 动态规划+状态压缩:定义三个 dp,分别为:
      • rowDp[i][j]:在第 i 行当前节点(含)往前连续有多少个 1
      • colDp[i][j]:在第 j 列当前节点(含)往上连续有多少个 1
      • squareDp[i][j]:以当前节点为右下角,连续 1 的最大正方形边长
    • 此时循环矩阵,如果为 0 则全是 0,如果为 1 转移方程为:
      • rowDp[i][j] = rowDp[i][j - 1] + 1
      • colDp[i][j] = colDp[i - 1][j] + 1
      • squareDp[i][j] = min(rowDp[i][j], rowDp[i][j], squareDp[i - 1][j - 1] + 1) 意为左上的正方形加上当前行、当前列可以形成的最大正方形
    • 空间压缩:rowDp 压缩后每个值等于前一个值加一(矩阵为 1),colDp 压缩后每个值等于上一轮循环当前位加一(矩阵为 1),squareDp 必须使用二维数组,因为每次遍历时会将上一行的前一位数据更新掉,同时 squareDp[i][j] = min(rowDp[i][j](当前行列), rowDp[i][j](当前行列), squareDp[i - 1][j - 1] + 1(上一行、上一列))
    • 时间复杂度:O(m*n),空间复杂度:O(n)
  • 代码
    /*** 动态规划+状态压缩:定义三个 dp,分别为:*     rowDp[i][j]:在第 i 行当前节点(含)往前连续有多少个 1*     colDp[i][j]:在第 j 列当前节点(含)往上连续有多少个 1*     squareDp[i][j]:以当前节点为右下角,连续 1 的最大正方形边长* 此时循环矩阵,如果为 0 则全是 0,如果为 1 转移方程为:rowDp[i][j] = rowDp[i][j - 1] + 1,colDp[i][j] = colDp[i - 1][j] + 1,* squareDp[i][j] = min(rowDp[i][j], rowDp[i][j], squareDp[i - 1][j - 1] + 1) 意为左上的正方形加上当前行、当前列可以形成的最大正方形* 空间压缩:rowDp 压缩后每个值等于前一个值加一(矩阵为 1),colDp 压缩后每个值等于上一轮循环当前位加一(矩阵为 1),* squareDp 必须使用二维数组,因为每次遍历时会将上一行的前一位数据更新掉,* 同时 squareDp[i][j] = min(rowDp[i][j](当前行列), rowDp[i][j](当前行列), squareDp[i - 1][j - 1] + 1(上一行、上一列))* 时间复杂度:O(m*n),空间复杂度:O(n)*/public int solution(char[][] matrix) {// 判空if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return 0;}int m = matrix.length;int n = matrix[0].length;// 定义三个 dp,空间压缩,避免判断下标 0 可以让 dp 往后/下移动一位int[] rowDp = new int[n + 1];int[] colDp = new int[n + 1];// 注意必须使用二维数组,因为顺序遍历时会将上一行的前一位数据更新int[][] squareDp = new int[2][n + 1];// 循环处理三个 dpint res = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (matrix[i][j] == '0') {rowDp[j + 1] = 0;colDp[j + 1] = 0;squareDp[i & 1][j + 1] = 0;} else {rowDp[j + 1] = rowDp[j] + 1;colDp[j + 1] = colDp[j + 1] + 1;// squareDp[i][j] = min(rowDp[i][j](当前行列), rowDp[i][j](当前行列), squareDp[i - 1][j - 1] + 1(上一行、上一列))squareDp[i & 1][j + 1] = Math.min(rowDp[j + 1], Math.min(colDp[j + 1], squareDp[(i + 1) & 1][j] + 1));res = Math.max(res, squareDp[i & 1][j + 1]);}
//                System.out.print(matrix[i][j] + " : " + rowDp[j + 1] + " : " + colDp[j + 1] + " : " + squareDp[i & 1][j + 1] + "\t");}
//            System.out.println();}return res * res;}

http://www.ppmy.cn/news/88399.html

相关文章

Android系统原理性问题分析 - 单路情况下的C/S模型

声明 在Android系统中经常会遇到一些系统原理性的问题&#xff0c;在此专栏中集中来讨论下。Android系统中很多地方都采用了I/O多路复用的机制&#xff0c;为了引出I/O多路复用机制&#xff0c;先来分析多路并发情况下的C/S模型。此篇参考一些博客和书籍&#xff0c;代码基于A…

Java的ssm框架中开发常用注解的作用和功能小小总结!!!

Java 的 SSM (Spring SpringMVC MyBatis) 框架是 Java Web 开发中常用的框架之一。其中&#xff0c;Spring、SpringMVC、MyBatis 框架各自都提供了很多注解&#xff0c;以下是一些常用注解及其功能&#xff1a; Spring 框架常用注解 Component&#xff1a;用于标记一个类为组…

视频会议产品对比分析

内网视频会议系统如何选择&#xff1f;有很多单位为了保密&#xff0c;只能使用内部网络&#xff0c;无法连接互联网&#xff0c;那些SaaS视频会议就无法使用。在内网的优秀视频会议也有很多可供选择&#xff0c;以下是几个常用的&#xff1a; 1. 宝利通&#xff1a;它支持多种…

2019下半年上午题

2019下半年上午题 b 选a c 最后统一单位 计算需要多少片芯片&#xff1a; 流水线&#xff1a; 也就是&#xff1a; 对于这一道题&#xff1a; c ssl&#xff1a;安全套接层 https&#xff1a;安全通道 PGP&#xff1a;电子邮件加密 d b a b b 受委托方和委…

Java枚举

Java枚举 &#x1f37a;1 背景及定义&#x1f37a;&#x1f9c3;2 使用&#x1f9c3;&#x1f964;3 枚举优点缺点&#x1f964;&#x1f375;4 枚举和反射&#x1f375;&#x1f377;4.1 枚举是否可以通过反射&#xff0c;拿到实例对象呢&#xff1f;&#x1f377; ☕️5 总结…

多文件分布式上传-SpringBoot

前言 在现代化的互联网应用中&#xff0c;各种形式的上传都成为了必备的功能之一。而对于大文件上传以及多文件上传来说&#xff0c;我们往往需要考虑分布式储存的方案&#xff0c;以实现高效和可扩展性。 本文将详细介绍在SpringBoot中实现多文件分布式上传的方法&#xff0…

Python多线程爬虫又来了

Python多线程的主要好处是可以在单个程序中同时执行多个任务&#xff0c;从而提高应用程序的性能和效率。具体来说&#xff0c;多线程有以下几个优点&#xff1a; 提高CPU利用率&#xff1a;通过多线程&#xff0c;可以更充分地利用CPU资源&#xff0c;尤其适用于计算密集型的…

项目中遇到的一些问题总结(十二)

有状态认证和无状态认证 有状态认证和无状态认证是两种不同的身份验证方式&#xff0c;主要的区别在于是否需要在服务端保留用户的会话或状态信息。 有状态认证&#xff1a;在服务器端记录与用户身份验证相关的会话信息&#xff0c;服务器需要维持这些会话信息来验证用户的每…