【数据结构】差分数组

news2024/11/25 12:58:39

【数据结构】差分数组

    • 差分数组
    • 二维差分数组
      • 二维数组的前缀和

差分数组

如果给定一个包含1000万个元素的数组,同时假定会有频繁区间修改操作,但是不会有频繁的查询操作,比如对某个范围【l,r】内的数字加上某个数字,此时,如果直接在原数组上进行操作,无疑效率会十分低下。因此我们使用差分数组标记区间【l,r】的修改操作,然后在查询时根据差分数组还原即可,差分数组就是用来标记对数组修改记录的。

那么怎么操作呢?

假设我们存在数组arr[],我们使用另外一个数组diff表示arr数组中每个元素与前一个元素的差值,其中diff[i] = arr[i] - arr[i - 1]的值,对于diff[0] = arr[0],形式如下,其中diff就是我们的差分数组。
在这里插入图片描述

这个差分数组有什么用呢?

我们可以看到当我们要查询arr的时候,需要根据差分数组进行还原,对于arr[i],我们只需要计算arr[i] == arr[i - 1] + diff[i]即可,arr[0] = 0 + diff[0],可以看到在还原的过程中,diff[0,…,i - 1]的值会通过赋值给arr[0,…,i-1]间接影响到arr[i],这样,就只需要修改diff[l]和diff[r + 1]的值就可以达到区间修改的目的,因为修改diff[l],其后的元素都会在累加的过程中受到影响,在diff[r + 1]将修改还原,r之后的元素就不会受到影响。比如我们需要对arr区间【2,4】的元素加上2,可以看到diff中只有2和5的位置发生了改变,这样每次对区间操作,我们都只需要改变差分数组中两个值就可以了,这样可以大大提高效率。
在这里插入图片描述

了解差分数组的特性之后,我们可以看下leetcode中的一道题:
使数组中的所有元素都等于零
对于该题,我们需要每次选择一个长度为k的子数组,将其减去1,最终判断能否将数组的值全部置为0。由于数据范围很大,两层循环显然不太合适,我们可以使用差分数组。由于是子数组,且必须将所有的元素都置为0,所以我们需要从0的位置的第一个元素开始遍历,不能跳过任意一个元素,我们使用sumD表示前面已经累积需要减去的最大元素,如果当前元素大小不足以减去该元素,或者后面已经没有元素可以配合当前元素使之变为0,则返回false,否则返回true。

class Solution {
    public boolean checkArray(int[] nums, int k) {
        int n = nums.length, sumD = 0;
        var d = new int[n + 1];
        for (int i = 0; i < n; i++) {
            sumD += d[i];
            int x = nums[i];
            x += sumD;
            if (x == 0) continue; // 无需操作
            if (x < 0 || i + k > n) return false; // 无法操作
            sumD -= x; // 直接加到 sumD 中
            d[i + k] += x;
        }
        return true;
    }
}
作者:endlesscheng
链接:https://leetcode.cn/problems/apply-operations-to-make-all-array-elements-equal-to-zero/solution/chai-fen-shu-zu-pythonjavacgojs-by-endle-8qrt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二维差分数组

如果我们是对二维数组进行频繁修改,我们可以使用二维差分数组记录修改记录,对于arr[][] ,我们使用diff[][]标记二维数组,通过一维数组我们可以观察到一维数组的值是差分数组的前缀和,推广到二维数组,arr[i][j]也表示diff[i][j]的前缀和。

二维数组的前缀和

计算公式如下。
diff[i][j]=arr[i][j]−arr[i−1][j]−arr[i][j−1]+arrr[i−1][j−1]

对坐标点 (x1, y1) ~ (x2, y2)所围成的区间进行修改时,对应的4个端点的操作应为:

diff[x1][y1] += c;
diff[x1][y2 + 1] -= c;
diff[x2 + 1][y1] -= c;
diff[x2 + 1][y2 + 1] += c;

从二维前缀和的角度来看,对区域左上角 +1,会对所有右下位置产生影响,那么在区域右上角的右边相邻处和左下角的下边相邻处 −1,可以消除这个影响,但是两个 −1又会对区域右下角的右下所有位置产生影响,所以要在右下角的右下相邻处再 +1还原回来。

我们看一题
子矩阵元素加 1

class Solution {
    public int[][] rangeAddQueries(int n, int[][] queries) {
        int[][] diff = new int[n + 1][n + 1],  ans = new int[n][n];
        for (int[] q : queries) {
            int r1 = q[0], c1 = q[1], r2 = q[2], c2 = q[3];
            ++diff[r1][c1];
            --diff[r1][c2 + 1];
            --diff[r2 + 1][c1];
            ++diff[r2 + 1][c2 + 1];
        }
        ans[0][0] = diff[0][0];
        for (int i = 1; i < n; ++i) {
            ans[0][i] = diff[0][i] +=  ans[0][i - 1];
            ans[i][0] = diff[i][0] +=  ans[i - 1][0];
        }

        for (int i = 1; i < n; ++i) {
            for (int j = 1; j < n; ++j) {
                ans[i][j] = diff[i][j] += diff[i - 1][j] + diff[i][j - 1] - diff[i - 1][j - 1];
            }
        }

        return ans;
    }
}

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

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

相关文章

Java基础-->异常

什么是异常&#xff1f; 异常&#xff1a;异常就是代表程序出现的问题 误区&#xff1a;不是让我们以后不出现异常&#xff0c;而是程序出了异常之后该如何处理 Error 代表系统级别的错误&#xff08;属于原重问题&#xff09; 系统一旦出现问题&#xff0c;sun公司会把这些…

数据库应用:Mycat实现读写分离

目录 一、理论 1.Mycat 2.Mycat安装启动 3.Mycat搭建读写分离 4.垂直分库 5.水平分表 6.Mycat高可用 7.Mycat安全设置 8.Mycat监控工具 二、实验 1.Mycat读写分离 2.Mycat监控安装 三、问题 1.Mycat命令无法补全 2.Mycat启动失败 3.zookeeper启动报错 四、总结…

基于SpringBoot+Vue的冬奥会科普平台设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

Java通过URL对象实现简单爬虫功能

目录 一、URL类 1. URL类基本概念 2. 构造器 3. 常用方法 二、爬虫实例 1. 爬取网络图片&#xff08;简易&#xff09; 2. 爬取网页源代码 3. 爬取网站所有图片 一、URL类 1. URL类基本概念 URL&#xff1a;Uniform Resource Locator 统一资源定位符 表示统一资源定位…

动态规划--回文串问题

一)回文子串: 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; 思路1:暴力枚举: for(int i0;i<array.length;i) for(int ji;j<array.length;j) 我们的中心思路就是枚举出所有的子字符串&#xff0c;然后进行判断所有的子串是否是回文串 思路2:中心扩散: 我们从左向…

​MySQL高阶语句(三)

目录 1、内连接 2、左连接 3、右连接&#xff1a; 二、存储过程⭐⭐⭐ 4. 调用存储过程 5.查看存储过程 5.1 查看存储过程 5.2查看指定存储过程信息 三. 存储过程的参数 3.1存储过程的参数 3.2修改存储过程 四.删除存储过程 MySQL 的连接查询&#xff0c;通常都是将来…

ElasticSearch学习--RestClient及案例

目录 RestClient查询文档 快速入门 总结 全文检索&#xff08;match&#xff09;查询 精确查询 复合查询 查询总结 排序&#xff0c;分页 高亮 RestClient查询文档 快速入门 总结 全文检索&#xff08;match&#xff09;查询 多种查询的差异都在做类型和条件上&#x…

JS 自定义的悬浮窗被浏览器遮挡问题解决方案

遮挡问题解决思路&#xff0c;首先拿到外层的DOM元素div的宽高&#xff0c;然后根据鼠标悬浮事件的元素e e.clientX表距离页面窗口宽的位置 e.clientY代表距离页面窗口高的位置 然后设置这个悬浮窗为200px 那个这个div的宽高 dom.getElementById(xxxx).cliengHeight dom.g…

FutureTask

Future接口 Future接口&#xff08;FutureTask实现类&#xff09;定义了操作异步任务执行一些方法&#xff0c;如获取异步任务执行的结果、取消任务的执行、判断任务是否取消、判断任务执行是否完成等。它提供了一种并行异步计算的功能。比如主线程让子线程去执行任务&#xff…

C语言两种方法求证大小端存储

目录 什么是大小端存储&#xff1f; 字节序的概念&#xff1a; 小端字节序存储&#xff1a; 大端字节序存储&#xff1a; 什么是低位字节、高位字节&#xff1f; 记忆技巧&#xff1a; C语言求证大小端存储 法一&#xff1a; 法二&#xff1a; 总结&#xff1a; 什么是…

CAXA中.exb或者.dwg文件保存为PDF

通常CAXAZ中的文件为.exb或者.dwg格式&#xff0c;我们想打印或者保存为PDF文件格式&#xff0c;那么就用一下的方法&#xff1a; CAXA文件如图所示&#xff1a; 框选出你要打印的图纸&#xff01;&#xff01;&#xff01;&#xff01; 我们选择"菜单"->"…

用户订单信息案例

需求: 用户输入商品价格和商品数量&#xff0c;以及收货地址&#xff0c;可以自动打印订单信息 分析: ① 需要输入3个数据&#xff0c;所以需要3个变量来存储price num address ② 需要计算总的价格total ③ 页面打印生成表格, 里面填充数据即可 ④ 记得最好使用模板字符串 【…

java.io.InputStreamReader的read()函数返回值是字符对应的Unicode码点

java.io.InputStreamReader的read()函数定义&#xff1a; https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/io/InputStreamReader.html#read() 这个返回的值其实就是解码后的字符对应的Unicode码点&#xff08;Unicode code point&#xff09;。 举例 例如…

MySQL表的管理

目录 1.mysql中&#xff0c;数据存储过程分为四步 2.数据库命名规则 3.创建数据库 4.管理数据库的方法 5.修改数据库&#xff08;一般不改&#xff0c;最多改字符集&#xff09; 6.删除数据库 7.如何创建数据表 8.修改表 9.重命名表 10.删除表&#xff08;注意⚠️无…

Java日志slf4j+logback

一、maven依赖 在pom文件增加slf4jlogback依赖 <!-- 版本配置 --> <properties><slf4j.version>1.7.21</slf4j.version><logback.version>1.1.7</logback.version> </properties><dependencies><!-- slf4j依赖包 -->&…

JVM源码剖析之达到什么条件进行JIT优化

版本信息&#xff1a; jdk版本&#xff1a;jdk8u40 思想至上 技术经过数百年的迭代&#xff0c;如今虚拟机中都存在JIT模块&#xff0c;JVM中Hotspot&#xff0c;Android虚拟机中dalvik、Art等等。并且存在一个共性&#xff0c;全部都是解释器和JIT共存。当然&#xff0c;如今…

六、模型融合

目录 1 构建模型多样性1.1 特征多样性1.2 样本多样性1.3 模型多样性 2. 训练过程融合2.1 Bagging2.2 Boosting 3. 训练结果融合3.1 加权法3.2 Stacking 融合3.3 Blending 融合 4. 实战案例 本章主要分为构建多样性、训练过程融合和训练结果融合三部分。模型融合常常是竞赛取得胜…

神州通用数据库Linux安装

神舟通用1.安装包下载地址 神舟通用 操作系统、数据库 1、官方下载链接 2、windows客户端下载链接 3、官方安装手册 4、安装前准备 3.1、创建安装用户 3.2、以root 用户修改神通数据库安装包的所有者为shentong 用户 3.3、以root 用户创建神通数据库主目录并修改所有者为shent…

欧姆龙cx系列plc串门通讯设置串口转以太网通讯处理器

捷米特JM-ETH-CX 串口转以太网通讯处理器是为满足日益增多的工厂设备信息化需求&#xff08;设备网络监控和生产管理&#xff09;而设计&#xff0c;用于欧姆龙 CPM、CQM、C200、C1000、C2000 等多个系列 PLC 的以太网数据采集&#xff0c; 非常方便构建生产管理系统。 捷米特J…