矩阵中矩阵最大的正方形

时间:2012-04-20 19:15:48

标签: algorithm

我认为我有一个非常典型的问题。我知道这里有类似的主题但是要明白我是初学者并且不区分这个问题的不同版本。有时文本和算法的差异可能完全不同。所以问题是:

For a given 2<=a,b<=1000 and 1<=c<=Min(a,b) find in matrix a x b square c x c 
with the largest sum of elements. The elements in matrix are from -1000 to 1000.

我可以编写一个运行整个矩阵的算法,并且在每个点(x,y)上它计算平方(x,y),(x + c,y),(x,y + c)的和, (X + C,Y + C)。然后我选择了最大的金额。有了这些限制,我认为它可能会非常快,但有没有更快的算法?我不擅长计算算法复杂度,但似乎是O(a * b * c * c)。如果我在最坏的情况下没有错,它可能不会停止..

3 个答案:

答案 0 :(得分:6)

我认为正确的方法是首先进行积分变换:对于原始矩阵M的每个元素(i,j),计算积分变换矩阵I(i,j) = sum[0..i, 0..j](M)。通过在行和列方向上运行总和,您可以在O(a * b)时间内执行此操作。

一旦进行了积分变换,就可以在恒定时间内计算任何子块的总和:

sum[i0..i1, j0..j1](M) = I(i1,j1) - I(i0 - 1, j1) - I(i1, j0 - 1) + I(i0 - 1, j0 - 1)

所以你可以在恒定时间内计算和比较每个c x c平方和,总共为O(a * b)。

答案 1 :(得分:1)

您的解决方案将起作用,您对时间复杂性是正确的,实际上它是* b * c * c。 加速一点点的一种方法是,当你滑动c * c窗口时,你不会重新计算所有内容,而只是减去那些正在移出窗口的内容,并添加那些正在移动的内容。窗户。由于您可以在x方向和y方向上执行此操作,因此您可能需要记住列(或行)中所有c * c方块的总和,以便将来查找。

答案 2 :(得分:1)

我认为通过这里提到的滑动方法,您的复杂性会降低。 因此,假设在您的情况下,a,b,c在每个优化问题中都是常数(意味着c不是优化变量)。

1)从左上角开始,O(c * c)

2)在移除最左边的柱并添加最右边的柱

后向右滑动O(c)

3)重复(2)(a-c)次,所以O(c *(a-c))

4)(1) - (3)成本约为O(c * c + c *(a-c))

5)你还需要向下滑动并为其他(bc)行执行此操作,每个行花费O(c)向下滑动,O(c * a)用于完成一行,总共为O (c * c + c *(ac)(bc)+ c (ac)+ c *(bc))

6)假设a,b>&gt; c,它可以简化为O(b * c * a)

让我知道是否有任何错误!

相关问题