在整数数组中查找子数组和

时间:2013-07-06 21:43:01

标签: algorithm arrays

给定一组N个正整数。它可以有n*(n+1)/2个子数组,包括单个元素子数组。每个子数组都有一个总和S。对于所有子阵列,查找S's显然为O(n^2),因为子阵列的数量为O(n^2)。许多总和S's也可能重复。有没有办法在O(n logn)中找到所有不同总和的计数(不是总和的确切值,只是计数)。

我尝试了一种方法,但坚持不懈。我将数组从索引1迭代到n 假设a[i]是给定的数组。对于每个索引ia[i]将添加a[i-1]所涉及的所有总和,并将其自身也包含为单个元素。但是如果在涉及a[i-1]的总和中,两个总和的差异为a[i],则会出现重复。我的意思是,总和SpSq最终为a[i-1],两者的差异为a[i]。然后Sp + a[i]等于Sq,将Sq作为副本。

C[i]是结束于a[i]的不同总和的计数 所以C[i] = C[i-1] + 1 - numbers of pairs of sums in which a[i-1] is involved whose difference is a[i]

但问题是在O(log n)中找到对数的一部分。请给我一些关于此的提示,或者如果我的方法不对,需要完全不同的方法问题请指出。

2 个答案:

答案 0 :(得分:10)

当S不太大时,我们可以用一个(快速)多项式乘法来计算不同的和。当S较大时,N有望小到足以使用二次算法。

设x_1,x_2,...,x_n为数组元素。设y_0 = 0且y_i = x_1 + x_2 + ... + x_i。令P(z)= z ^ {y_0} + z ^ {y_1} + ... + z ^ {y_n}。计算多项式P(z)* P(z ^ { - 1})的乘积; z> k的系数,其中k>当且仅当k是子阵列和时,0是非零的,所以我们只需要读取正幂的非零系数的数量。此外,z的幂在-S到S的范围内,因此乘法在S log S的顺序上花费时间。

答案 1 :(得分:0)

您可以将子数组视为一种树。从某种意义上说,子阵列[0,3]可以分为[0,1][2,3]

因此构建一个树,其中节点由子数组的长度定义,并且它在原始数组中保持偏移,并且每当计算子数组时,将结果存储在此树中。

计算子数组时,可以检查此树是否有现有的预先计算的值。

此外,在划分时,如果重要的话,可以在不同的CPU内核上计算部分数组。

此解决方案假设您不需要同时使用所有值,而是临时。 对于前者,可能会有一些更智能的解决方案。

另外,我假设我们正在谈论10000多个元素的计数。否则,这样的工作是一个很好的练习,但没有多大实际价值。