给定大小为M x N的矩阵,需要大量查询才能找到子矩阵和。查询的输入是要求和的子矩阵的左上和右下索引。
如何预处理矩阵,以便可以在O(1)时间内执行子矩阵和查询。
例子:
tli : Row number of top left of query submatrix
tlj : Column number of top left of query submatrix
rbi : Row number of bottom right of query submatrix
rbj : Column number of bottom right of query submatrix
Input: mat[M][N] = {{1, 2, 3, 4, 6},
{5, 3, 8, 1, 2},
{4, 6, 7, 5, 5},
{2, 4, 8, 9, 4} };
Query1: tli = 0, tlj = 0, rbi = 1, rbj = 1
Query2: tli = 2, tlj = 2, rbi = 3, rbj = 4
Query3: tli = 1, tlj = 2, rbi = 3, rbj = 3;
Output:
Query1: 11 // Sum between (0, 0) and (1, 1)
Query2: 38 // Sum between (2, 2) and (3, 4)
Query3: 38 // Sum between (1, 2) and (3, 3)
天真的算法:
我们可以循环所有查询,并以O(q *(N * M))最坏的情况(对于大范围的数字而言太大)来计算每个查询。
// Pseudo code of Naive algorithm.
Arr[][] = input_matrix
For each query:
Input tli, tlj, rbi, rbj
sum = 0
for i from tli to tbi (inclusive):
for j from tlj to rbj(inclusive):
sum += Arr[i][j]
print(sum)
优化的解决方案:
汇总面积表可以将这种类型的查询减少为O(M * N)的预处理时间,并且每个查询都将在O(1)中执行。
求和面积表是一种数据结构和算法,用于快速有效地生成网格的矩形子集中的值之和。
求和面积表中任意点(x,y)的值就是(x,y)上方和左侧的所有值的总和,包括:
优化的解决方案在下面的文章中实现。
实施优化方法