查找具有相同总和且长度相同的子阵列

时间:2015-01-21 03:37:26

标签: algorithm

假设有两个相同长度的数组[an]和[bn],找到[an]和[bn]的两个子数组,以便子数组具有相同的总和并且长度相同。例如:[an] = [5,4,17,10,29],[bn] = [1,22,23,4,15],程序将返回"是"因为[an]中的[17,10]和[bn]中的[23,4]具有相同的总和并且长度相同。有没有比O(n ^ 3)更好的算法?

2 个答案:

答案 0 :(得分:1)

(好吧,如果我指出一个O(n ^ 2)版本,或许我会向那些做得更好的人学习)。假设对于每个数组,你计算前k个元素的总和,对于所有k = 1到数组的长度,所以[5,4,17,10,29]变成[5,9,26,36,65] ]。显然,你可以通过保持一个运行总计来在O(n)中做到这一点。

现在你可以通过从另一个中减去一个运行总计来计算出该数组的任何部分的总和,例如17 + 10 = 36 - 9.因此,您可以在时间O(n ^ 2)中计算出所有连续子阵列的O(n ^ 2)和。将一个子数组的结果输入到哈希表中,然后计算另一个子数组的所有结果,并检查它们是否在哈希表中。哈希表操作是(probabalisticaly)O(1)所以总成本是O(n ^ 2)

答案 1 :(得分:0)

这是一个喜剧的答案,成本为n log n,为适当定义的n 。正如在我之前的回答中,我们将输入数据转换为部分和,让我们在部分和中找到位置的问题表示服从A - B = C - D的值。

现在让我们假设数组中的数字是小整数,并且n是任一数组中的最大和。对于每一侧,创建一个长度为n的数组,其中所有值都为0,除了位置i,其中i是部分和,您可以将其设置为1.使用FFT,计算每个数组与自身的卷积,及时O (n log n)。我们现在有两个长度为O(n)的数组(需要一些填充),偏移处的非零值对应于两个部分和的减法 - 所以我们要做的就是扫描两个数组以找到任何一个大小为O(n)

的两个数组中的非零值