如何检查所有可能的数组矩形的总和

时间:2016-10-29 17:51:00

标签: arrays algorithm

我们假设我们有一个二维数组A(n X n)。 A的所有元素都是O或1.我们还有一个给定的整数K.我们的任务是找到A中所有可能的“矩形”的数量,其中包含总和K的元素。

To give an example , if A = 
0 0 1 0 
1 0 0 1
1 1 1 1
1 0 0 1   and k=3 ,

0 0 1 0
1 0 0 1  holds the property ,

1 1 1 holds the property ,

  1 1 1 holds the property ,

0 0 
1 0 
1 1 holds the property ,

1 1
1 0  holds the property ,

    1 1
    0 1  holds the property ,

1
1
1  holds the property

1
1
1 holds the property 

所以除非我错过了什么,否则这个例子的答案应该是8。

换句话说,我们需要检查A中所有可能的矩形,看看它们的元素之和是否为K.有没有办法比O(n ^ 2 * k ^ 2)更快地完成它?

2 个答案:

答案 0 :(得分:5)

您可以在O(n ^ 3)中执行此操作。

首先请注意,summed area table允许您在给定O(n ^ 2)预处理时间的情况下计算O(1)时间内任何矩形的总和。

在这个问题中我们只需要对列进行求和,但一般技术值得了解。

然后,对于每个起始行和结束行组合,您可以在矩阵中进行线性扫描,以使用两个指针方法计算解决方案,或者仅通过存储先前的总和。

示例Python代码(找到您示例的14个解决方案):

from collections import defaultdict
A=[[0, 0, 1, 0],
[1, 0, 0, 1],
[1, 1, 1, 1],
[1, 0, 0, 1]]
k=3

h=len(A)
w=len(A[0])

C=[ [0]*w for i in range(h+1)]
for x in range(w):
    for y in range(1,h+1):
        C[y][x] = C[y-1][x] + A[y-1][x]
# C[y][x] contains sum of all values A[y2][x] with y2<y

count=0
for start_row in range(h):
    for end_row in range(start_row,h):
        D=defaultdict(int) # Key is sum of columns from start to here, value is count
        D[0]=1
        t=0 # Sum of all A[y][x] for x <= col, start_row<=y<=end_row
        for x in range(w):
            t+=C[end_row+1][x] - C[start_row][x]
            count += D[t-k]
            D[t] += 1
print count

答案 1 :(得分:4)

我认为它比你计算的更糟糕。我发现总共有14个矩形,有3个1(绿色方块)。我使用的方法是将数组中的每个{row,column}位置作为矩形的左上角,然后考虑宽度和高度的每种可能组合。

由于宽度和高度不受k约束(至少不是直接约束),因此搜索时间为O(n^4)。当然,对于任何给定的{row,column,width},当高度大于k时,搜索结束。但这并没有改变最坏的情况。

不需要考虑右下角的三个起点,因为从这些位置开始构建包含k 1的矩形是不可能的。但同样,这并没有改变时间复杂性。

注意:我知道这不仅仅是一个评论,而是一个答案。但是,它并不适合评论,我相信它对OP仍然有用。在完全理解之前,您无法解决问题。

enter image description here