【问题标题】:Fastest way to find sum of any rectangle in matrix在矩阵中找到任何矩形之和的最快方法
【发布时间】:2014-02-28 13:06:05
【问题描述】:

我有一个 m x n 矩阵,并且希望能够计算任意矩形子矩阵的总和。对于给定的矩阵,这将发生多次。我应该使用什么数据结构?

例如我想在矩阵中找到矩形的总和

1   2   3   4
5   6   7   8
9   10  11  12
13  14  15  16

总和是 68。

我要做的是逐行累积:

1   2   3   4
6   8   10  12
15  18  21  24
28  32  36  40

然后,如果我想找到矩阵的总和,我只需累积 28,32,36,40 = 136。只有 4 次操作而不是 15 次。 如果我想找到第二行和第三行的总和,我只需累积 15,18,21,24 并减去 1, 2, 3, 4. = 6+8 +10+12+15+18+21+24 = 68。 但在这种情况下,我可以使用另一个矩阵,按列累加:

1   3   6   10
5   11  18  26
9   19  30  42
13  27  42  58

在这种情况下,我只是将 2642 = 68 相加。只有 2 次操作而不是 8 次。对于更宽的子矩阵,使用第二种方法和矩阵是有效的,对于更高的 - 第一种。我可以以某种方式将其拆分为一个矩阵的方法吗?

所以我只是对角求和并减去另外两个?

【问题讨论】:

    标签: algorithm math matrix


    【解决方案1】:

    你的方法快到了。解决方案是使用求和面积表(又名积分图像):

    关键的想法是你做一次通过你的矩阵并累积,这样“求和区域表中任意点 (x, y) 的值就是 (x) 上方和左侧所有像素的总和, y), 包括在内。”。

    然后,您可以通过四次查找在恒定时间内计算任何矩形内的总和。

    【讨论】:

    • 如果几个求和查询在整个或部分矩阵上运行,这是有利的。
    • 在我的情况下,金额很大
    • 有快速的Java实现吗?如果我这样做蛮力=>递归 - 它非常慢。
    • 用两个循环迭代地做,而不是递归地做。您还可以重复使用现有功能:summed_table = accumulate_rows(accumulate_columns(matrix))
    【解决方案2】:

    为什么不能使用 For 循环来添加它们?

    int total = 0;
    for(int i = startRow; i = endRow; i++)
    {
        for(int j = startColumn; j = endColumn; j++)
        {
            total += array[i][j];
        }
    }
    

    您的子数组(“矩形”)从 startRow 到 endRow(宽度)和 startColumn 到 endColumn(高度)的位置。

    【讨论】:

    • 如果我想在 N = 1000 的矩阵 NxN 中找到 100 个子矩阵的总和怎么办?
    • 然后将上面的代码放入一个名为 SumSubarray(int startRow, int endRow, int startCol, int endCol) 的函数中,并为每个子矩阵调用它,然后添加你的结果。
    • @JohnDow 一次性计算 Cyber​​ 是正确的。如果您想针对多个子项进行优化,请在您的问题中提及(我在那里看不到)
    • 嗯,我现在在标题中看到了。
    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多