我正在解决以下问题:
设A是长度为n的数组,每个元素-10n <= A [i] <= 10n。创建在O(nlog(n))时间运行的算法,该算法确定是否存在条目A [i],A [j]和A [k](i,j和k不一定是不同的),使得A [i] + A [j] + A [k] = 0。
我正以下列方式接近它。定义度数为n-1的多项式p,使得x ^ k项上的系数为A [k]。然后use the FFT to multiply p与其自身,然后再次将得到的多项式乘以p。如果结果多项式中的任何系数为0,则返回true。否则,返回false。由于FFT是O(nlog(n)),因此该算法为O(nlog(n))。
我遇到的问题是FFT结合了类似术语,可以这么说。因此,系数0的存在并不意味着存在这样的条目。
有人可以建议对此算法进行修改以改进它吗?
答案 0 :(得分:0)
如果我没记错,解决这个问题的方法是:
60n + 1
的多项式,其中术语x^k
上的系数是数组中元素k - 10n
的出现次数。例如,如果n=8
,x^5
上的系数是-75
(-75 = 5 - 10x8
)的出现次数60n + 1
)提高到第三个幂。x^(30n)
上的系数是否为非零。如果是,那就是答案。这是python上的示例实现,它似乎适用于我提出的所有案例:
import numpy as np
from numpy.fft import fft, ifft
def hasZeroSum(a):
n = len(a)
b = [0 for x in range(n * 60 + 1)]
for el in a: b[el + 10 * n] += 1
f = fft(b, n * 60 + 1)
f = np.power(f, 3)
res = ifft(f, n * 60 + 1)
return np.absolute(res[n * 30]) > 0.5
print hasZeroSum([-11, -5, 2, 3, 7])
print hasZeroSum([-11, -5, 2, 4, 8])
打印
True
False