leetcode.1504. 统计全 1 子矩形(单调栈-java)

news2024/10/7 18:26:23

统计全 1 子矩形

  • leetcode.1504. 统计全 1 子矩形
    • 题目描述
    • 单调栈解题
    • 代码演示
  • 单调栈专题

leetcode.1504. 统计全 1 子矩形

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-submatrices-with-all-ones

题目描述

给你一个 m x n 的二进制矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。

示例1:
在这里插入图片描述
输入:mat = [[1,0,1],[1,1,0],[1,1,0]]
输出:13
解释:
有 6 个 1x1 的矩形。
有 2 个 1x2 的矩形。
有 3 个 2x1 的矩形。
有 1 个 2x2 的矩形。
有 1 个 3x1 的矩形。
矩形数目总共 = 6 + 2 + 3 + 1 + 1 = 13 。

示例2:
在这里插入图片描述
输入:mat = [[0,1,1,0],[0,1,1,1],[1,1,1,0]]
输出:24
解释:
有 8 个 1x1 的子矩形。
有 5 个 1x2 的子矩形。
有 2 个 1x3 的子矩形。
有 4 个 2x1 的子矩形。
有 2 个 2x2 的子矩形。
有 2 个 3x1 的子矩形。
有 1 个 3x2 的子矩形。
矩形数目总共 = 8 + 5 + 2 + 4 + 2 + 2 + 1 = 24 。

提示:
1 <= m, n <= 150
mat[i][j] 仅包含 0 或 1

单调栈解题

首先看第一个问题,只有一行的时候,怎么计算矩形的数量呢.
如图:
在这里插入图片描述
矩形数量的计算公式为.
Sum(n) = n * (n + 1) / 2;

有了上面的计算公式后,我们在以第一行为底座,去计算每一列矩形的高度.有了高度后,可以按单调栈的方式去计算数量了.
// 比如
// 1
// 1
// 1 1
// 1 1 1
// 1 1 1
// 1 1 1
//
// 2 … 6 … 9
// 如上图,假设在6位置,1的高度为6
// 在6位置的左边,离6位置最近、且小于高度6的位置是2,2位置的高度是3
// 在6位置的右边,离6位置最近、且小于高度6的位置是9,9位置的高度是4
// 此时我们求什么?
// 1) 求在3~8范围上,必须以高度6作为高的矩形,有几个?
// 2) 求在3~8范围上,必须以高度5作为高的矩形,有几个?
// 也就是说,<=4的高度,一律不求
// 那么,1) 求必须以位置6的高度6作为高的矩形,有几个?
// 3…3 3…4 3…5 3…6 3…7 3…8
// 4…4 4…5 4…6 4…7 4…8
// 5…5 5…6 5…7 5…8
// 6…6 6…7 6…8
// 7…7 7…8
// 8…8
// 这么多!= 21 = (9 - 2 - 1) * (9 - 2) / 2
// 这就是任何一个数字从栈里弹出的时候,计算矩形数量的方式

代码演示

  /**
     * 计算矩形的数量
     * @param mat
     * @return
     */
    public static int numSubmat(int[][] mat) {
        if (mat == null || mat.length == 0 || mat[0].length == 0){
            return 0;
        }
        int n = mat.length;
        int m = mat[0].length;
        int[] ans = new int[m];
        int nums = 0;
        for (int i = 0; i < n;i++){
            for (int j = 0;j < m;j++){
                ans[j] = mat[i][j] == 0 ? 0 : ans[j] + 1;
            }
            nums += countFromBottom(ans);
        }
        return nums;
    }


    /**
     * 单调栈,用数组来实现栈
     * @param heights
     * @return
     */
    public static int countFromBottom(int[]heights){
        //记录计算的结果
        int ans = 0;
        //用数组来代替栈结构,常数时间会得到优化,速度变快
        int[]stack = new int[heights.length];
        //来标记栈顶元素,最开始没有值,标记为-1
        int stackSize = -1;

        for (int i  = 0; i < heights.length;i++){
            while (stackSize != -1 && heights[stack[stackSize]] >= heights[i]){
                int cur = stack[stackSize--];
                if (heights[cur] > heights[i]){
                    int left = stackSize == -1 ? -1 : stack[stackSize];
                    int maxDown =  Math.max(left == -1 ? 0 : heights[left],heights[i]);
                    int width = i - left - 1;
                    ans += (heights[cur] - maxDown) * count(width);
                }
            }
            stack[++stackSize] = i;
        }

        while (stackSize != -1){
            int cur = stack[stackSize--];

            int left = stackSize == -1 ? -1 : stack[stackSize];
            int maxDown = left == -1 ? 0 : heights[left];
            int width = heights.length - left - 1;
            ans += (heights[cur] - maxDown) * count(width);

        }
        return ans;
    }
    /**
     * n 是宽度
     * 公式 计算
     */
    public static  int count(int n){
        return (n * (n + 1)) >> 1;
    }

单调栈专题

单调栈的实现-单调递减栈和单调递增栈

leetcode1856. 子数组最小乘积的最大值

leetcode84. 柱状图中最大的矩形

leetcode.85. 最大矩形

leetcode42. 接雨水

leetcode739. 每日温度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytest之配置文件pytest.ini

前言&#xff1a; pytest.ini文件是pytest的主配置文件&#xff0c;可以改变pytest的运行方式&#xff0c;它是一个固定的文件pytest.ini文件&#xff0c;读取配置信息&#xff0c;按指定的方式去运行。 pytest.ini文件的位置一般放在项目的根目录下&#xff0c;不能随便放&a…

Vant入门介绍

Vant 介绍 Vant是有赞开源的一套基于Vue2.0的Mobile组件库。Vant 是一套轻量、可靠的移动端组件库。通过 Vant&#xff0c;可以搭建出风格统一的&#xff0c;提升开发效率。通过Vant,可以搭建出风格统一的,提升开发效率。目前已有近50个组件,这些组件被广泛使用于有赞的各个移…

LVS-DR排错思路

一.LVS-DR实验排错思路 1.案例架构图 DR服务器&#xff1a;192.168.27.11 web服务器1&#xff1a;192.168.27.12 web服务器2&#xff1a;192.168.27.13 vip&#xff1a;192.168.27.180 客户端&#xff1a;192.168.27.2 1&#xff1a;配置负载调度器&#xff1a;&#xff…

【集群】脑裂是什么?Zookeeper是如何解决的?

文章目录 什么是脑裂Zookeeper集群中的脑裂场景过半机制 什么是脑裂 脑裂(split-brain)就是“大脑分裂”&#xff0c;也就是本来一个“大脑”被拆分了两个或多个“大脑”&#xff0c;我们都知道&#xff0c;如果一个人有多个大脑&#xff0c;并且相互独立的话&#xff0c;那么…

[HDCTF2019]MFC

前言 mfc逆向&#xff0c;有一个VM壳一看到它就头疼&#xff0c;好在这道题用不到&#xff0c;可以直接通过xspy获取mfc自定义消息 分析 工具下载&#xff1a; https://bbs.kanxue.com/thread-170033.htm 开始时完全没有头绪&#xff0c;有虚拟壳&#xff0c;用ida打开也看…

AMEYA360:Panasonic松下HF系列压敏电阻器

Panasonic HF系列压敏电阻器符合AEC-Q200标准&#xff0c;最大允许额定电压为16VDC&#xff0c;钳位电压高达43A。这些紧凑型SMD压敏电阻器适合用于汽车应用&#xff0c;采用模制结构&#xff0c;因此能够耐受很强的“焊接热冲击”。这些压敏电阻器符合ISO7637-2和ISO16750-2负…

迪赛智慧数——饼图(玫瑰饼图):抑郁症发病群体年龄

效果图 痛心&#xff0c;震惊了全网&#xff0c;著名歌手李玟&#xff0c;抑郁症自杀离世&#xff01; 为什么看起来阳光开朗的人&#xff0c;也会得抑郁症&#xff1f;据数据调查显示&#xff0c;15-30岁为抑郁症的高发年纪&#xff0c;由于思想不够成熟&#xff0c;经验少&a…

QT开发技巧之QComboBox通过qss设置item高度,增加间隔

1.问题描述 QComboBox默认的下拉item间距太小&#xff0c;字挤在一起不好看&#xff0c;直接qss设置item高度但是没效果 2.解决后效果 可通过qss设置item的最小高度&#xff0c;增加间距&#xff0c;不同字体大小的combobox都能使用&#xff0c;简单方便 3.代码实现 &#xf…

葡萄牙语翻译,北京哪个公司比较好?

近年来&#xff0c;随着中国与各葡语系国家&#xff0c;特别是与巴西经贸、科技、文化交流的不断扩大&#xff0c;葡萄牙语翻译的需求也越来越大&#xff0c;但是专业葡语翻译人才紧缺。那么&#xff0c;如何做好葡萄牙语翻译&#xff0c;北京葡语翻译公司哪家好&#xff1f; 我…

分布式消息服务设计

分布式消息服务设计 背景 为了解决当A系统的一个“操作”需要发送一个通知&#xff08;生产者&#xff09;&#xff0c;由关心这个操作的业务&#xff08;消费者&#xff09;订阅消息并处理时&#xff0c;实现业务解耦&#xff0c;并适合分布式。本文主要讲解以消息中间件Rab…

Debug_性能分析工具_Perf +

目录 1. perf 作用 2. perf 安装 3. perf 使用示例 3.1 耗时统计&#xff0c;画出火焰图 1. 下载绘制火焰图的开源pl代码 2. 执行以下命令 3. 用浏览器打开svg文件&#xff0c;看当前进程各子模块耗时占比 1. perf 作用 Perf 是Linux kernel自带的系统性能优化工具。 P…

HCIA-HarmonyOS Application Developer学习笔记

目录 一、HarmonyOS 介绍二、HarmonyOS 应用开发流程HarmonyOS 系统架构HarmonyOS 子系统集DevEco StudioHarmonyOS 应用包结构使用资源文件的方法权限管理分布式能力 三、Ability 设计与开发Ability 的概念和分类页面生命周期Intent载体页面间导航Particle Ability 开发 四、U…

使用Vue脚手架2

ref属性 src/components/SchoolName.vue <template><div class"school"><h2>学校名称&#xff1a;{{name}}</h2><h2>学校地址&#xff1a;{{address}}</h2></div> </template><script>export default {name:…

【C++修炼之路】31.异常

每一个不曾起舞的日子都是对生命的辜负 异常 一.C语言传统的处理错误的方式二.C异常概念三.异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 四.自定义异常体系五.C标准库的异常体系六.异常的优缺点 一.C语言传统的处理错误的方式 传统的错误处理机…

Idea运行springboot项目(保姆级教学)

**大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯…

PHP:对比数据库,隐藏不满足条件的标签;对比数据库,将标签中的内容更改为数据库中的对应项

一、查询数据库数据&#xff0c;A列数据如果等于前端div中的值&#xff0c;那么将div中的值给其赋值为对应数据库中B列的值 如下案例&#xff1a;以第一个为例&#xff0c;如果id为append1&#xff0c;并且此id等于满足条件的数据库中colum_name列中的append1&#xff0c;就将…

Windows安装 PostgreSQL数据库并进行简单数据操作

介绍&#xff1a; 在开发和管理数据库应用程序时&#xff0c;选择合适的数据库管理系统是至关重要的。PostgreSQL 是一个强大且广受欢迎的开源关系型数据库管理系统&#xff0c;它具有稳定性、可靠性和丰富的功能。本文将介绍如何在 Windows 操作系统上下载、安装 PostgreSQL&a…

6. QT环境下使用OPenCV(利用鼠标实现图像的ROI区域选择)

1. 说明 一张图像显示的内容可能并非所有的都是有用信息,有时需要选定某些区域做出特殊的处理。在OPenCV当中可以在图像上响应鼠标的操作,选取出图像上的特殊区域 — ROI区域。 效果展示: 2. 实现步骤 首先在QtCreator中创建一个新的widget项目,并配置好OPenCV的开发环…

【GIS】Python多线程转换NC格式文件为TIFF

汇总 【GIS】使用cdsapi下载ERA5和ERA5_land逐小时数据 NC格式介绍 说明 NC文件读取使用netCDF4,NC文件转换为TIF使用rasterio或者GDAL。 一些细节: 格点数据转换为TIFF文件时候,计算六参数时候,应该要考虑,格点数据存储的坐标属于栅格中心点的位置,转换为TIFF时候,…

Vue3中使用async-validator进行表单校验

官方文档&#xff1a;mirrors / yiminghe / async-validator GitCodevalidate form asynchronous &#x1f680; Github 镜像仓库 &#x1f680; 源项目地址 ⬇https://gitcode.net/mirrors/yiminghe/async-validator?utm_sourcecsdn_github_accelerator 注意&#xff1a;当…