二维数组之前缀和中篇

news2025/1/11 6:20:35

        在此之前,可以先看看这篇二维数组之二维前缀和-首篇。

和为K的子数组

    给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。子数组是数组中元素的连续非空序列。

示例 1:
    输入:nums = [1,1,1], k = 2
    输出:2
示例 2:
    输入:nums = [1,2,3], k = 3
    输出:2

class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        int pre = 0;
        map.put(pre, 1);
        int ans = 0;
        for(int i = 0;i < nums.length;i++){
            pre += nums[i];
            if(map.get(pre - k) != null){
                ans += map.get(pre - k);
            }
            map.put(pre, map.getOrDefault(pre, 0) + 1);
        }
        return ans;
    }
}

        需要用到一维数组的前缀和。先给出一个示例数组和对应的前缀和数组。
请添加图片描述
        给定数组nums,和前缀数组pre_nums,如果子数组和为target(K),那么前缀和数组就需要满足pre_nums[j] - pre_nums[i] = target(K)。移项之后得,pre_nums[i] = pre_nums[j] - target(K)。也就是说,当得到一个前缀和为pre_nums[j]时,减去target(K),如果之前的前缀和中出现过pre_nums[i],说明从下标i到下标j的子数组满足和为target(K)。例如target为6,以上述图片中数组为例,pre_nums数组有一个前缀和为13,13 - target,也就是13 - 6 = 7,在13这个前缀和之前,有一个前缀和为7,说明从nums数组中从下标2到下标4的这段子数组的和为target,7 + 2 + (-3) = 6。
        可以先计算前缀和,之后减去target(K),判断之前是否出现pre_nums[i],pre_nums[i]就是首元素到下标为i的元素的前缀和(i < j),所以需要保存之前元素的前缀和。要想较快的定位到对应pre_nums[i],可以用哈希表,key为前缀和,value为有多少个这样的前缀和,因为在下标j之前可能有多个值相同的前缀和,只是起始下标不同,但是都可以使得起始下标到下标j对应的子数组的和为target。
         下面以图片示例为例,走一遍代码,设target(K)为7,首先将初始化前缀和pre等于0,这里不用使用数组来保存前缀和,因为已经使用哈希表对前缀和进行保存,所以只需要定义一个变量pre来保存当前首元素到当前元素的前缀和。map,put(pre, 1),意思就是前缀和为0的元素有1个。
         之后进入for循环,首先pre += nums[0],等于3,3 - 7 = -4不在map中不进入if,map放入(3, 1)。此时map中有(0, 1),(3, 1)。
         pre += nums[1],等于7,7 - 7等于0,所以说明[3, 4]这段子数组的和为target,由于初始化时将前缀和0放入在map中,进入if,ans += map.get(pre - k),ans += map.get(0),ans的值为1。此时map中有(0, 1),(3, 1),(7, 1)。
         pre += nums[2],等于14,14 - 7等于7,说明[7]这个子数组的和为target。进入if,ans += map.get(7),ans等于2。此时map中有(0, 1),(3, 1),(7, 1),(14, 1)。
         pre += nums[3],等于16,16 - 7 = 11,不在map中,此时map中有(0, 1),(3, 1),(7, 1),(14, 1),(16, 1)。
         pre += nums[4],等于13,13 - 7等于6,不在map中,此时map中有(0, 1),(3, 1),(7, 1),(14, 1),(16, 1),(13,1)。
         pre += nums[5],等于14,14 - 7等于7,在map中,且数量为1,ans += map.get(7)等于3。同时需要更新map中前缀和为14的value值为2。此时map中有(0, 1),(3, 1),(7, 1),(14, 2),(16, 1),(13,1)。
         pre += nums[6],等于18,18 - 7等于11,不在map中,此时map中有(0, 1),(3, 1),(7, 1),(14, 2),(16, 1),(13,1),(18, 1)。
        pre += nums[7],等于20,20 - 7等于13,在map中,ans += map.get(13),ans值为4。此时map中有(0, 1),(3, 1),(7, 1),(14, 2),(16, 1),(13,1),(18, 1),(20,1)。
        for循环结束,返回ans等于4。

元素和为目标值的子矩阵数量

    给出矩阵 matrix 和目标值 target,返回元素总和等于目标值的非空子矩阵的数量。
    子矩阵 x1, y1, x2, y2 是满足 x1 <= x <= x2 且 y1 <= y <= y2 的所有单元 matrix[x][y] 的集合。
    如果 (x1, y1, x2, y2) 和 (x1’, y1’, x2’, y2’) 两个子矩阵中部分坐标不同(如:x1 != x1’),那么这两个子矩阵也不同。

示例 1:
    输入:matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
    输出:4
    解释:四个只含 0 的 1x1 子矩阵。
示例 2:
    输入:matrix = [[1,-1],[-1,1]], target = 0
    输出:5
    解释:两个 1x2 子矩阵,加上两个 2x1 子矩阵,再加上一个 2x2 子矩阵。
示例 3:
    输入:matrix = [[904]], target = 0
    输出:0

class Solution {
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        int ans = 0;
        for(int i = 0;i < m;i++){
            int[] sum = new int[n];
            for(int j = i;j < m;j++){
                for(int k = 0;k < n;k++){
                    sum[k] += matrix[j][k];
                }
                ans += subarraySum(sum, target);
            }
        }
        return ans;
    }
    private int subarraySum(int[] nums, int target){
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);
        int pre = 0;
        int ans = 0;
        for(int num : nums){
            pre += num;
            if(map.get(pre - target) != null){
                ans += map.get(pre - target);
            }
            map.put(pre, map.getOrDefault(pre, 0) + 1);
        }
        return ans;
    }
}

        二维数组中元素和为目标值的子矩阵数量,就是将二维矩阵转化为一维矩阵,根据一维矩阵和为K的子数组的求解方法进行求解。那么现在的难点就是如果得到将二维矩阵转化为所有可能的一维矩阵。
请添加图片描述
        如上图所示,按行遍历所有可能的行组合,有6种,之后分别计算这6种组合的列和用sum数组表示,这样就得到了一维数组,每个一维数组和为K的子数组数量之和就是二维数组中元素和为目标值的子矩阵数量。

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

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

相关文章

cesium加载倾斜影像数据(模拟雨、雪、雾、无人机飞行、测距、箭头标绘、电子围栏等)

实现效果如下&#xff1a; 功能菜单如下&#xff1a; 加载倾斜影像核心代码&#xff1a; var palaceTileset new Cesium.Cesium3DTileset({url: http://127.0.0.1:9002/tileset.json,//控制切片视角显示的数量&#xff0c;可调整性能maximumScreenSpaceError: 0.1,maximumNum…

c++的学习之路:25、map与set

摘要 本文中说一下map与set的使用 目录 摘要 一、关联式容器 二、键值对 三、map 1、map的介绍 2、map的使用 1、map的模板参数说明&#xff1a; 2、map的构造 3、map的迭代器 4、map的容量与元素访问 5、map中元素的修改 6、代码使用 ​编辑 三、总结 四、se…

51单片机入门_江协科技_33~34_OB记录的自学笔记_LED呼吸灯与PWM直流马达调速

33. 直流电机驱动(PWM) 33.1. 直流电机介绍 •直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 •直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&…

winform 入门篇 -- 第15章 表格视图

表格控件 表格视图 DataGridView &#xff0c;即表格控件提行多行多列的表格状的数据展示 演示: 以表格控件来展示学生数据。。 每个单元格 都可以进行独立的编写 &#xff08;与上节得不同&#xff09; 基本操作: 1 添加一个表格控件 DataGridView 2 设置列数、列名 属…

HarmonyOS Next 视频弹幕功能

视频弹幕功能 介绍 本示例介绍如何使用ohos.danmakuflamemaster和ohos.gsyvideoplayer开发支持视频弹幕的播放器。可以自定义弹幕样式、占据屏幕宽度&#xff0c;发送弹幕&#xff0c;开关弹幕视图。 效果图预览 使用说明 点击播放按钮&#xff0c;进行视频播放&#xff0c…

STM32 USB虚拟串口

电路原理图 usb部分 晶振部分 usb与单片机连接 配置信息 sys配置信息 rcc配置信息 usb配置信息 虚拟串口配置信息 时钟配置信息 项目配置信息 代码 包含文件 主函数代码 实验效果 修改接收波特率依然可以正常接收&#xff0c;也就是说单片机可以自动适应上位机的波特率设置。…

2023年图灵奖揭晓:Avi Wigderson的辉煌成就与深远影响

2023年图灵奖揭晓&#xff0c;你怎么看&#xff1f; 2023年图灵奖&#xff0c;最近刚刚颁给普林斯顿数学教授 Avi Wigderson&#xff01;作为理论计算机科学领域的领军人物&#xff0c;他对于理解计算中的随机性和伪随机性的作用&#xff0c;作出了开创性贡献。 方向三&#xf…

免费泛域名SSL如何申请,和通配符有什么区别

-----让我们明确什么是泛域名。所谓泛域名&#xff0c;是指使用星号&#xff08;*&#xff09;作为子域名的占位符&#xff0c;它可以匹配任意子域名。-----而通配符在域名中&#xff0c;它可以出现在主域名的任何位置&#xff0c;它可以用于主域名和子域名的保护。 主要应用场…

握手问题(蓝桥杯)

文章目录 握手问题【问题描述】答案&#xff1a;1204解题思路模拟 握手问题 【问题描述】 小蓝组织了一场算法交流会议&#xff0c;总共有 50 人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手&#…

OceanBase 4.3 列存存储格式和列存索引存储格式

以 t1 表和索引为例子&#xff0c;下面两张图说明了存储层如何存储数据。 create table t1 (id1 int, id2 int, name varchar(10), salary int, primary key(id1, id2)) with column group (each column);create index idx (name) storing(salary) with column group(each co…

突破“三个九”!离子阱量子计算再创新高

如果把量子计算比作一场球赛&#xff0c;Quantinuum无疑又打了一记漂亮的好球。实际上&#xff0c;结合今年春季在量子体积、逻辑量子比特和布线问题等方面的进展&#xff0c;这个团队已经接近于完成一场完美的比赛。 3月&#xff0c;Quantinuum的研究人员证明了QCCD架构的可扩…

MYSQL08_页的概述、内部结构、文件头、文件尾、最大最小记录、页目录、区段表

文章目录 ①. 页的概述、大小②. 页的内部结构③. 第一部分 - 文件头④. 第一部分 - 文件尾⑤. 第二部分 - 空闲、用户记录、最大最小⑥. 第三部分 - 页目录⑦. 第三部分 - 页面头部⑧. 从数据页角度看B树⑨. 区、段和表、碎片区 ①. 页的概述、大小 ①. 数据库的存储结构&…

小行星碰撞

题目链接 小行星碰撞 题目描述 注意点 两个小行星相互碰撞&#xff0c;较小的小行星会爆炸如果两颗小行星大小相同&#xff0c;则两颗小行星都会爆炸每一颗小行星以相同的速度移动正负表示小行星的移动方向&#xff08;正表示向右移动&#xff0c;负表示向左移动&#xff09…

day81 session会话 文件上传

知识点&#xff1a; session 文件上传 一 session 1&#xff09;session&#xff1a;会话 在服务器端存储信息 指客户与服务器的会话 当用户通过浏览器访问服务器的某个页面时&#xff0c;在服务器开辟一个内存空间session 每个session 有唯一的id 2&#xff09;session过期 …

安全开发实战(3)--存活探测与端口扫描

目录 安全开发专栏 前言 存活探测 端口扫描 方式一: 1.3.1 One 1.3.2 Two 1.3.3 批量监测 方式二: 1.3.1 One 1.3.2 Two 1.3.3 Three 1.3.4 扫描ip地址,提取出开放端口和协议 ​编辑 1.3.5 批量扫描(最终完成版) 总结 安全开发专栏 安全开发实战​http://t.csd…

javaee前后端交互

1.选择Java Enterprise创建项目 2.勾选Web Profile 3.项目名称 4.创建包和类 5.继承HttpServlet并重写方法doGet和doPost 6.在web.xml里添加代码 7.点击Add Configuration,进去后点击加号 8.选择选项 9.调整如图&#xff0c;后选择Deployment进入 10.点击加号选择第一个 11.…

【GoWeb框架初探————Gin篇】

1. Gin 1.1 下载相应依赖 创建go项目&#xff0c;在项目下建立go.mod文件&#xff08;若有则跳过&#xff09; 命令行运行 go get github.com/gin-gonic/gin1.2 启动一个简单Web服务 package mainimport ("github.com/gin-gonic/gin""github.com/thinkerou/…

如何正确查看容器的CPU使用率

进入容器中top&#xff0c;虽然看到的PID是容器的&#xff0c;但是%Cpu的统计信息却是宿主机的。 如图 原理 进程的cpu使用率是如何计算出来的&#xff1f; 每个进程的状态是放在文件里的&#xff0c;在/proc目录下&#xff0c;每个进程有自己pid命名的文件夹&#xff0c; …

vscode 如何支持点击函数跳转

一、配置方式 我要配置的是 python 语言&#xff0c;以 python 语言为例来设置 1、在扩展商店搜索 python 并安装 2、安装完成后点击设置按钮&#xff0c;进入扩展设置 3、在扩展设置中搜索 go to definition&#xff0c;将下面红框的两项设置为 goto 4.连接远程服务器后还需…

基于go+vue的多人在线聊天的im系统

基于govue的多人在线聊天的im系统 文章目录 基于govue的多人在线聊天的im系统一、前端部分二、后端部分1、中间件middleware设计jwt和cors2、配置文件设计3、Mysql和Redis连接4、路由设计5、核心功能设计 一、前端部分 打算优化一下界面&#xff0c;正在开发中。。。 二、后端…