给定一个排序数组[1..n],其中每个元素的范围从1到2n。有没有办法找到三元组,其和为整数x。我知道O(n ^ 2)解决方案。有没有比n ^ 2更好的算法。
答案 0 :(得分:4)
使用该事实可以实现O(n log n)
时间复杂度,每个元素的最大值为O(n)
。
对于每个1 <= y <= 4 * n
,让我们找到总计为y
的元素对数。我们可以创建2 * n
幂的多项式,其中该多项式的i
- 系数是给定数组中数字i
的出现次数。现在我们可以使用傅立叶的快速变换在s
时间内找到此多项式的平方(我称之为O(n log n)
)。 i
系数s
恰好是总计i
的元素对数。
现在我们可以迭代给定的数组。我们假设当前元素是a
。然后我们只需要检查总计为X - a
的对数。我们已经在步骤1)中完成了它。
如果所有三元组必须由不同元素组成,我们需要减去总计为X
但包含重复项的此类三元组的数量。我们也可以在O(n log n)
时间内完成(对于由三个相等元素组成的三元组,我们只需要减去给定数组中X / 3
的出现次数。对于有一个重复的三元组,我们可以迭代重复两次的元素(a
)并减去X - 2 * a
的出现次数。
如果我们需要找到一个三元组,而不仅仅是计算它们,我们可以执行以下操作:
按照上面的建议计算三胞胎和对的数量。
找到这样一个元素,即它与X
总和为一对。
找到两个元素,总计达到该对的所需总和。
所有这些步骤都可以在线性时间内完成(使用所有总和为O(n)
的事实)。
答案 1 :(得分:0)
您的问题显然是non-zero sum variant的3SUM problem。
因为您事先知道整数的可能范围,所以根据文章的第二段,您可以达到比一般情况更低的界限:
当元素是 [ - N,...,N] 范围内的整数时,3SUM可以是 通过将输入集 S 表示为 O(n + N log N)时间来解决 位向量,使用discrete convolution将所有成对和的集合 S + S 计算为Fast Fourier transform,最后比较 这设置为 -S 。
在您的情况下,您必须在运行算法之前通过减去 n + X / 3 来预处理数组。
有一点需要注意的是,该算法假设您正在使用 set 数字,并且我不确定如果您的<运行时间可能会产生什么影响(如果有的话) em> array 可能包含重复项。