我们假设我们有一个二维数组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)更快地完成它?
答案 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仍然有用。在完全理解之前,您无法解决问题。