在数组中查找三元组,其总和为整数X.

时间:2015-02-15 14:30:08

标签: algorithm

给定一个排序数组[1..n],其中每个元素的范围从1到2n。有没有办法找到三元组,其和为整数x。我知道O(n ^ 2)解决方案。有没有比n ^ 2更好的算法。

2 个答案:

答案 0 :(得分:4)

使用该事实可以实现O(n log n)时间复杂度,每个元素的最大值为O(n)

  1. 对于每个1 <= y <= 4 * n,让我们找到总计为y的元素对数。我们可以创建2 * n幂的多项式,其中该多项式的i - 系数是给定数组中数字i的出现次数。现在我们可以使用傅立叶的快速变换在s时间内找到此多项式的平方(我称之为O(n log n))。 i系数s恰好是总计i的元素对数。

  2. 现在我们可以迭代给定的数组。我们假设当前元素是a。然后我们只需要检查总计为X - a的对数。我们已经在步骤1)中完成了它。

  3. 如果所有三元组必须由不同元素组成,我们需要减去总计为X但包含重复项的此类三元组的数量。我们也可以在O(n log n)时间内完成(对于由三个相等元素组成的三元组,我们只需要减去给定数组中X / 3的出现次数。对于有一个重复的三元组,我们可以迭代重复两次的元素(a)并减去X - 2 * a的出现次数。

    如果我们需要找到一个三元组,而不仅仅是计算它们,我们可以执行以下操作:

    1. 按照上面的建议计算三胞胎和对的数量。

    2. 找到这样一个元素,即它与X总和为一对。

    3. 找到两个元素,总计达到该对的所需总和。

    4. 所有这些步骤都可以在线性时间内完成(使用所有总和为O(n)的事实)。

答案 1 :(得分:0)

您的问题显然是non-zero sum variant3SUM problem

因为您事先知道整数的可能范围,所以根据文章的第二段,您可以达到比一般情况更低的界限:

  

当元素是 [ - N,...,N] 范围内的整数时,3SUM可以是   通过将输入集 S 表示为 O(n + N log N)时间来解决   位向量,使用discrete convolution将所有成对和的集合 S + S 计算为Fast Fourier transform,最后比较   这设置为 -S

在您的情况下,您必须在运行算法之前通过减去 n + X / 3 来预处理数组。

有一点需要注意的是,该算法假设您正在使用 set 数字,并且我不确定如果您的<运行时间可能会产生什么影响(如果有的话) em> array 可能包含重复项。