【问题标题】:How to check sums of all possible rectangles of array如何检查所有可能的数组矩形的总和
【发布时间】:2016-10-29 17:51:00
【问题描述】:

假设我们有一个二维数组 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) 更快的方法?

【问题讨论】:

  • 检查所有矩形的幼稚算法不会花费O(n^4) 时间吗?

标签: arrays algorithm


【解决方案1】:

你可以在 O(n^3) 中做到这一点。

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

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

然后,对于每个起始行和结束行组合,您可以对矩阵进行线性扫描,以使用两个指针方法或简单地存储之前的总和来计算解决方案。

示例 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

【讨论】:

    【解决方案2】:

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

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

    不需要考虑右下角的三个起点,因为不可能从这些位置构造一个包含k 1 的矩形。但同样,这不会改变时间复杂度。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多