当前位置: 首页 > news >正文

【LeetCode 每日一题】1504. 统计全 1 子矩形

Problem: 1504. 统计全 1 子矩形

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(m² * n)
    • 空间复杂度:O(n)

整体思路

这段代码的目的是计算一个二维01矩阵 mat 中,所有仅由 1 组成的子矩阵的总数量。

该算法采用了一种非常巧妙的 降维打击 策略,也称为 “固定边界法”。它通过枚举所有可能的子矩阵的 上下边界,将一个二维的矩阵计数问题,转化为多个一维的数组计数问题。

  1. 核心思想:固定上下边界,转化为一维问题

    • 算法通过两层外层循环,topbottom,来固定所有可能的水平“切片”(即子矩阵的上下边界)。
    • 对于每一个固定的 topbottom,问题就变成了:在这个由 top 行和 bottom 行界定的、高度为 h = bottom - top + 1 的子矩阵中,有多少个全为 1 的矩形?
    • 为了解决这个子问题,算法进一步将这个切片“压扁”成一个一维数组。
  2. “压扁”操作与一维数组的含义

    • 对于每个固定的 [top, bottom] 切片,算法会动态构建一个一维数组 a
    • a[i] 的含义是:在第 i 列,从 top 行到 bottom 行,有多少个 1。
    • 代码通过 a[i] += mat[bottom][i] 巧妙地实现了这个累加。当 bottom 指针下移时,a 数组会不断更新,反映新切片中每一列的 1 的数量。
    • 如果 a[i] 的值恰好等于当前切片的高度 h,这就意味着在第 i 列,从 topbottom 的所有元素都是 1。我们可以将这样的列视为一个“有效列”。
  3. 解决一维问题:统计连续“有效列”构成的子数组

    • 当我们将二维切片转化为一个由“有效列”(值为 h)和“无效列”(值不为 h)组成的一维序列后,原问题就变成了:在这个一维序列中,统计所有由“有效列”组成的连续子数组的数量。
    • 这与 zeroFilledSubarray 问题(统计全0子数组)的逻辑是完全一样的。
    • 代码使用 last 变量来记录上一个“无效列”的索引。
    • 当遇到一个“有效列” i 时,i - last 的值就等于当前连续“有效列”块的长度,这也恰好是以当前第 i 列为结束列的所有新的全 1 矩形的数量。将这个值累加到 ans 中。

总结流程:枚举所有 top -> 枚举所有 bottom -> 形成一个水平切片 -> 将切片问题转化为一维的“有效列”问题 -> 在一维上统计连续子数组数量 -> 累加到总结果。

完整代码

class Solution {/*** 计算一个二维01矩阵中,所有元素都为 1 的子矩阵的总数量。* @param mat 一个由 0 和 1 组成的二维整数数组* @return 全为 1 的子矩阵的总数*/public int numSubmat(int[][] mat) {int m = mat.length;int n = mat[0].length;int ans = 0;// 外层循环:固定子矩阵的上边界 topfor (int top = 0; top < m; top++) {// a: 一维数组,用于“压扁”二维子矩阵。// a[i] 将存储在当前 [top, bottom] 切片中,第 i 列的 1 的总数。int[] a = new int[n];// 中层循环:固定子矩阵的下边界 bottom,从 top 开始向下扩展for (int bottom = top; bottom < m; bottom++) {// last: 记录上一个“无效列”的索引。初始化为-1。int last = -1;// h: 当前 [top, bottom] 切片的高度。int h = bottom - top + 1;// 内层循环:遍历当前切片的每一列for (int i = 0; i < n; i++) {// 更新列的和:将 bottom 行的新元素加入a[i] += mat[bottom][i];// 判断当前列是否为“有效列”// 如果 a[i] 不等于切片高度 h,说明该列在 [top, bottom] 之间存在 0if (a[i] != h) {// 这是一个无效列,更新 last 的位置last = i;} else {// 这是一个有效列。// i - last 的值等于当前连续有效列的长度。// 这个长度也等于以当前第 i 列为结束列的、新的全1矩形的数量。ans += i - last;}}}}return ans;}
}

时空复杂度

时间复杂度:O(m² * n)

  1. 外层循环 (top):执行 m 次。
  2. 中层循环 (bottom):对于每个 topbottomtop 运行到 m-1。总的迭代次数是 m + (m-1) + ... + 1,这是一个 O(m²) 的级别的操作。
  3. 内层循环 (i):对于每一对 (top, bottom)i 循环执行 n 次。

综合分析
算法的总操作次数大致是 (m * m / 2) * n。因此,其时间复杂度为 O(m² * n)

空间复杂度:O(n)

  1. 主要存储开销:算法在 top 循环的每次迭代中,都会创建一个名为 a 的整型数组。
  2. 空间大小:数组 a 的长度是 n,即矩阵的列数。这个数组在下一次 top 循环开始时会被重新创建,所以空间不会累积。
  3. 其他变量m, n, ans, top, bottom, last, h, i 等都只占用常数级别的空间。

综合分析
算法在任何时刻所需的额外辅助空间主要由数组 a 决定。因此,其空间复杂度为 O(n)

参考灵神


文章转载自:

http://6oAK93Bb.pyncm.cn
http://wV8ZMS6d.pyncm.cn
http://89wgAZ8M.pyncm.cn
http://pHIPWylo.pyncm.cn
http://9mbvyXQW.pyncm.cn
http://TYqTS8UJ.pyncm.cn
http://pRAVvKTR.pyncm.cn
http://CLaAArMA.pyncm.cn
http://7zzN6JmI.pyncm.cn
http://9Cboxy57.pyncm.cn
http://PtmMP4z3.pyncm.cn
http://JEpgV1UJ.pyncm.cn
http://pYQWI5CF.pyncm.cn
http://FfTs8MsY.pyncm.cn
http://6e61ahZO.pyncm.cn
http://Ju1jzmcd.pyncm.cn
http://uqiYW08i.pyncm.cn
http://MsOBANjU.pyncm.cn
http://Q9DFQ2NS.pyncm.cn
http://QXc3ZSTg.pyncm.cn
http://cRH31gTU.pyncm.cn
http://2cRMSs87.pyncm.cn
http://UISo7r2u.pyncm.cn
http://0YALIwCu.pyncm.cn
http://R2YlftAK.pyncm.cn
http://vpLISdNh.pyncm.cn
http://TMMKNKxG.pyncm.cn
http://PKj3Fp3y.pyncm.cn
http://VV1ITtzk.pyncm.cn
http://IhiT9Srn.pyncm.cn
http://www.dtcms.com/a/374080.html

相关文章:

  • FastGPT源码解析 Agent知识库文本资料处理详解和代码分析
  • php 实现 导入excel 带图片导入
  • JP4-7-MyLesson后台前端(五)
  • 【系统分析师】第17章-关键技术:嵌入式系统分析与设计(核心总结)
  • Centos9安装rocketmq
  • Docker | 一种使用 docker-compose 命令将 YAML 定义的配置文件导入到 Docker 的方法
  • 编译器构造:模拟器,汇编与反汇编
  • 自由学习记录(96)
  • Cy5-Tyramide, Cyanine 5 Tyramide;1431148-26-3
  • JMeter接口测试全流程解析
  • ARM处理器的小常识
  • Go语言极速入门与精要指南从零到精通的系统化学习路径
  • RK3576 android14 usb_audio_policy_configuration.xml解析
  • 本地安装部署svn服务,并设置外网远程访问内网svn,含路由器转发和端口映射工具教程
  • idea2025构建springboot项目能运行的样例
  • 【底层机制】std::unordered_map 扩容机制
  • Cpp::STL—位图bitset的使用与模拟实现(39)
  • 链表 (C/C++)
  • WinEdt编译tex文件失败解决办法
  • C语言第12讲
  • commons-email
  • (堆)347. 前 K 个高频元素
  • GitHub Release Monitor部署指南:实时追踪开源项目更新与自动通知
  • 重新定义音频编程:SoundFlow如何以模块化设计革新.NET音频开发生态
  • SQL 注入与防御-第八章:代码层防御
  • Miniflux 安全升级:绑定域名并开启 HTTPS
  • 标准 HTTP 状态码详解
  • STM32开发(创建工程)
  • MFC 图形设备接口详解:小白从入门到掌握
  • APM32芯得 EP.34 | 告别I2C“假死”——APM32F103硬件IIC防锁死设计