二维差分与二维前缀和

简介: 二维差分与二维前缀和

二维差分

二维差分是一种数据处理技术,应用于二维数组或矩阵中,用来快速计算和更新子矩阵元素的和。它是对一维差分概念的自然扩展,旨在简化对二维数据结构中特定区域元素进行加减操作的过程,同时保持较高的计算效率。通过计算原数组中相邻元素的差异,形成差分数组,从而支持对原数组中任意子矩阵元素进行快速的加法或减法操作,特别适用于需要频繁修改子区域元素值且需要频繁查询子区域和的应用场景,如动态规划问题、图像处理等。

二维差分的定义

给定一个二维数组 A[i][j],其对应的二维差分数组 D[i][j] 可以定义为:

D[i][j] = A[i][j] - A[i-1][j] - A[i][j-1] + A[i-1][j-1]

这里的差分数组 D 尺寸与原数组 A 相同,但其元素值表示了原数组中当前位置 (i, j) 与其上方、左侧和左上方相邻元素之间的数值差异。通过这样的定义,差分数组存储了原数组局部区域的“增量”信息。

二维差分的用途

主要用途在于,当我们需要对原数组 A 中某个子矩阵区域(例如,以 (i, j) 为左上角,(x, y) 为右下角的子矩阵)的所有元素同时加上或减去一个常数 d 时,使用差分数组 D 可以实现 O(1) 时间复杂度的快速更新,而无需遍历整个子矩阵。具体操作如下:

  • 对差分数组 D 中的四个角元素进行更新:

D[i][j] += d

D[x][j] -= d

D[i][y] -= d

D[x][y] += d

完成上述操作后,原数组 A 中指定子矩阵区域内所有元素的总和实际上已经增加了 d * (x - i + 1) * (y - j + 1),即完成了对子矩阵所有元素的加法操作。要还原这些变化以得到原数组 A 的实际值,通常会结合使用二维前缀和(也称为累加和矩阵),通过双重累积的方式快速计算出任意子矩阵的和。

二维前缀和

二维前缀和(又称二维累加和或二维累计和)是一种预处理技术,用于快速计算二维数组或矩阵中任意子矩阵的元素和。它通过对原矩阵进行逐行、逐列的累加,生成一个新的二维数组,其中每个元素存储了原矩阵中从原点(通常是左上角 (0, 0))到当前位置 (i, j) 的所有元素之和。有了二维前缀和矩阵,可以以常数时间复杂度 O(1) 快速求解原矩阵中任意矩形区域的元素和,极大地提高了计算效率。

二维前缀和的计算过程

假设我们有一个二维数组 A[i][j],目标是计算其对应的二维前缀和矩阵 P[i][j]。计算过程如下:

  1. 初始化前缀和矩阵 P 的第一个行和第一个列:
P[0][0] = A[0][0];
for (int j = 1; j < N; ++j)
    P[0][j] = P[0][j - 1] + A[0][j];  // 计算第一行的前缀和
for (int i = 1; i < M; ++i)
    P[i][0] = P[i - 1][0] + A[i][0];  // 计算第一列的前缀和
  1. 计算剩余部分的前缀和:
for (int i = 1; i < M; ++i)
    for (int j = 1; j < N; ++j)
        P[i][j] = P[i - 1][j] + P[i][j - 1] - P[i - 1][j - 1] + A[i][j];
二维前缀和的应用

二维前缀和主要应用于需要频繁计算二维数组或矩阵中子矩阵元素和的场景,如动态规划、图像处理、统计分析等。具体应用示例包括

sum = P[i2][j2] - P[i1][j2] - P[i2][j1] + P[i1][j1];
  • 这里通过相减操作消除了不需要计算的区域和。
  • 快速更新子矩阵:结合二维差分技术,可以在常数时间内对原矩阵中的子矩阵元素进行增减操作,并保持二维前缀和的有效性。
  • 解决特定问题:在一些基于子矩阵操作的算法中,如最大子矩阵和、连续子数组的最大和等,二维前缀和可以显著提高算法的效率。

二维差分与二维前缀和的关系

二维差分和二维前缀和是互补的概念。二维前缀和数组 S[i][j] 存储了原数组从 (1, 1)(i, j) 所有元素的累计和。二者之间存在一定的互逆关系,即可以通过差分数组和前缀和数组相互转换或配合使用来高效地进行数据查询和更新。


目录
相关文章
|
Linux iOS开发 UED
Linux简介和比较:开源操作系统的优势与差异
Linux简介和比较:开源操作系统的优势与差异
1277 0
|
数据采集 自然语言处理 搜索推荐
图文详解 DFS 和 BFS | 算法必看系列知识二十四
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在高频面试题中。
38430 6
图文详解 DFS 和 BFS | 算法必看系列知识二十四
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)
|
编解码 人工智能 缓存
通义万相上新,登顶!
通义万相上新,登顶!
659 0
|
关系型数据库 MySQL 数据安全/隐私保护
docker应用部署---MySQL的部署配置
这篇文章介绍了如何使用Docker部署MySQL数据库,包括搜索和拉取MySQL镜像、创建容器并设置端口映射和目录映射、进入容器操作MySQL,以及如何使用外部机器连接容器中的MySQL。
docker应用部署---MySQL的部署配置
使用 Java 文件流读取二进制文件
【10月更文挑战第5天】通过以上步骤,我们能够有效地使用 Java 的文件流来读取二进制文件,获取其中的信息。你在实际操作中是否遇到过一些问题或有什么特殊的技巧可以分享呢?我们可以一起交流,共同提高对文件流操作的理解和应用能力。
【Qt 学习笔记】Qt常用控件 | 布局管理器 | 空白项Spacer
【Qt 学习笔记】Qt常用控件 | 布局管理器 | 空白项Spacer
1088 2
|
人工智能 IDE 测试技术
探索嵌入式系统:快速入门指南概览
探索嵌入式系统:快速入门指南概览
531 2
|
开发框架 人工智能 前端开发
【GitHub】github学生认证,在vscode中使用copilot的教程
【GitHub】github学生认证,在vscode中使用copilot的教程
8393 4
|
存储 搜索推荐 算法
【数据结构入门精讲 | 第九篇】考研408排序算法专项练习(一)
【数据结构入门精讲 | 第九篇】考研408排序算法专项练习(一)
1950 1