给定一个整数,问题在于找到长度为3的可能算术系列的数量。整数集可能会也可能不会被排序。
我可以实现一个简单的暴力算法,花费时间O(n ^ 3),但时间效率很重要,整数集可以大到10 ^ 5。这意味着暴力显然不起作用。任何人都可以在c ++中建议一些算法/伪代码/代码吗?
一个例子:有4个数字5,2,7,8。显然,只有一种可能性 - (2,5,8),其中共同的区别是3,所以我们的答案是1。
编辑:我忘了提及一个重要的属性 - 每个给定的数量都在1到30000之间(含)。
答案 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]与自身卷积。