在O(nlogn)时间内找到数组求和的条目的算法

时间:2015-02-13 04:24:34

标签: algorithm fft

我正在解决以下问题:

  

设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的存在并不意味着存在这样的条目。

有人可以建议对此算法进行修改以改进它吗?

1 个答案:

答案 0 :(得分:0)

如果我没记错,解决这个问题的方法是:

  1. 定义度60n + 1的多项式,其中术语x^k上的系数是数组中元素k - 10n的出现次数。例如,如果n=8x^5上的系数是-75-75 = 5 - 10x8)的出现次数
  2. 使用FFT将该多项式(度60n + 1)提高到第三个幂。
  3. 查看x^(30n)上的系数是否为非零。如果是,那就是答案。
  4. 这是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