查找给定数字集中可能的算术系列数3

时间:2012-11-10 18:25:45

标签: algorithm

给定一个整数,问题在于找到长度为3的可能算术系列的数量。整数集可能会也可能不会被排序。

我可以实现一个简单的暴力算法,花费时间O(n ^ 3),但时间效率很重要,整数集可以大到10 ^ 5。这意味着暴力显然不起作用。任何人都可以在c ++中建议一些算法/伪代码/代码吗?

一个例子:有4个数字5,2,7,8。显然,只有一种可能性 - (2,5,8),其中共同的区别是3,所以我们的答案是1。

编辑:我忘了提及一个重要的属性 - 每个给定的数量都在1到30000之间(含)。

2 个答案:

答案 0 :(得分:4)

您可以在O(N ^ 2)中执行以下操作:创建整数的哈希集,以便检查O(1)中是否存在元素。之后,在所有设置元素对{X, Y}上创建两个嵌套循环。这是在O(N^2)

中完成的

对于每对{X, Y},假设X < Y,并计算两个数字:

Z1 = X - (Y-X)
Z2 = Y + (Y-X)

如果{X, Y, Zi}

,则三Zi != X && Zi != Y && set.contains(Zi)形成算术序列

检查三元组{X, Y, Z1}{X, Y, Z2}。您可以使用哈希集在O(1)中执行此操作,算法的总运行时间为O(N^2)

答案 1 :(得分:2)

另一种解决方案是O(N + BlogB)(其中B是整数的最大大小 - 在你的情况下是30,000)是考虑直方图H,其中H [x]是x存在的次数顺序。

该直方图可以在时间N中计算。

您正在寻找元素a,b,c,使得b-a = c-b。这相当于2b = a + c。

因此,想法是为a + c计算第二个直方图G [x],然后遍历所有元素b并将H [b] * G [2b]加到总数中。这需要时间O(B)。

(G [x]是序列中存在一对值a,b的次数,使得x = a + b。)

唯一的困难是计算G [x],但这可以使用快速傅立叶变换在时间O(BlogB)中将H [x]与自身卷积。