首先。在最坏的情况下找到所有三元组是O(n^3). 假设你有n=3k数字。其中 K 为 3,k 为 4,k 为 5。
3,....,3,4,....,4,5,.....5
有k^3 = n^3/27 = O(n^3)这样的三胞胎。只是打印它们需要O(n^3)时间。
接下来将以这种形式解释 3SUM 问题:
它们每个都有数字s_1, ..., s_nrange [-u;u]。a,b,c那有多少个三胞胎a+b=c?
转变。获取 2*u 个数字a_-u, ..., a_0, a_1, ... a_u。a_i是数字的数量s_j,那s_j = i。这是在O(n+u)
res = a_0 * sum(i=-u..u, i=/=0, C(a_i, 2)) + C(a_0,3) a_0 = 0
建立一个多项式P(x) = sum(i = -u...u, a_i*x^(i+u)。
Q(x) = P(x)*P(x)使用FFT查找。
请注意Q(x) = sum(i=-2u..2u, b_i*x^(i+2*u)),其中b_i是对数s_u,s_k即s_u+s_k = i(这包括两次使用相同的数字)。
对于所有甚至i做b_i = b_i - a_(i/2)。这将使用相同的号码删除两次。
- 总和
b_i*a_i/2- 将其添加到 res 中。
示例:为了更简单,我将假设数字的范围是 [0..u],并且不会使用任何 x 次方的 +u。假设我们有数字1,2,3
-a_0 = 0, a_1 = 1, a_2 = 1, a_3 = 1
res = 0
P(x) = x + x^2 + x^3
Q(x) = x^2 +2x^3+3x^4+2x^5+x^6
减去后b_2 = 0, b_3 = 2, b_4 = 2, b_5 = 2, b_6 = 0
res += 0*1/2 + 2*1/2 + 2*0/2 + 2*0/2 + 6*0/2 = 1