返回

揭秘二维前缀和:高效解决二维查询难题

前端

在计算机科学中,前缀和是一种极具价值的预处理技术,它能显著提升查询效率,尤其适用于一维数组。而二维前缀和则是这一概念的延伸,它将同样的思想应用于二维数组,进一步拓展了其适用范围。

二维前缀和的定义

二维前缀和的思想与一维前缀和类似,都是在原数组的基础上构建一个新的数组,其中每个元素存储的是原数组中对应子数组的和。具体而言,二维前缀和数组的前缀和计算公式为:

psum[i][j] = sum(a[k][l]) for all k <= i and l <= j

其中,psum[i][j]表示二维前缀和数组中(i, j)位置的元素,a表示原始二维数组。

二维前缀和的构建

构造二维前缀和数组的步骤如下:

  1. 初始化: 创建一个与原数组大小相同的二维数组psum
  2. 第一行和第一列:psum[0][0]初始化为a[0][0], 并将psum[i][0]psum[0][j]分别初始化为a[i][0]a[0][j]
  3. 后续元素: 对于psum[i][j](i > 0 && j > 0),计算其值为psum[i - 1][j] + psum[i][j - 1] - psum[i - 1][j - 1] + a[i][j]

二维前缀和的应用

二维前缀和主要用于高效计算二维数组中子矩阵的和。具体步骤如下:

  1. 确定子矩阵范围: 确定需要求和的子矩阵的左上角和右下角坐标。
  2. 使用二维前缀和: 根据子矩阵的范围,使用二维前缀和公式计算子矩阵的和。
sub_matrix_sum = psum[r2][c2] - psum[r2][c1 - 1] - psum[r1 - 1][c2] + psum[r1 - 1][c1 - 1]

其中,(r1, c1)(r2, c2)分别表示子矩阵的左上角和右下角坐标。

示例

考虑以下二维数组:

a = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

构建二维前缀和数组:

psum = [
    [1, 3, 6],
    [5, 12, 21],
    [12, 24, 45]
]

计算子矩阵(1, 1)(2, 2)的和:

sub_matrix_sum = psum[2][2] - psum[2][0] - psum[0][2] + psum[0][0] = 12

结论

二维前缀和是一种功能强大的数据结构,它可以通过预处理将二维数组中子矩阵的和查询到常数时间复杂度。在处理涉及二维数组求和的问题时,二维前缀和是一个不可或缺的工具,它能显著提升算法效率,节省大量计算时间。