我正在寻找一个快速的算法:
我有一个大小为n的int数组,目标是在数组中找到所有模式,x1,x2,x3是数组中不同的元素,这样x1-x2=x3
例如,我知道有一个大小为3的int数组是[1,2,3]
,那么只有一种可能性:12=3(考虑12=21)
我正在考虑实现对和Hashmap来使算法快速。(我现在得到的最快的仍然是O(n^2))
请分享你对这个问题的看法,谢谢
你基本上需要找到所有不同的值对和,所以我认为你不会比O做得更好(n2)。但您可以通过对列表进行排序并减少重复值来进行优化,然后只将一个值与任何相等或更大的值配对,当总和超过列表中的最大值时停止。
它必须至少是O(n^2),因为有n(n-1)/2个不同的总和可以检查其他成员。你必须计算所有这些元素,因为任何一对求和的元素都可能是任何其他成员(从一个例子开始,排列所有元素,让自己相信所有元素都必须被检查)。或者看看斐波那契的具体内容。
所以计算并在哈希表中查找成员会得到摊销的O(n^2)。或者如果你需要最好的最坏情况,使用有序树。
编辑:下面的答案适用于这个问题的一个版本,在这个版本中,你只需要一个这样加起来的三元组。当你想要所有这些元素时,因为可能至少有O(n^2)个可能的输出(正如ex0du5所指出的),甚至在重复元素的病理情况下,也有O(n^3),所以你无法击败基于散列(从一个值映射到具有该值的索引列表)的简单O(n^2)算法。
这基本上就是3SUM问题。在没有潜在无限大元素的情况下,最著名的算法大约是O(n^2)
,但我们只证明,对于大多数计算模型,它不可能比O(n lg n)
更快。
如果整数元素在[u,v]
范围内,则可以在O(n(v-u)lg(v-u))
中使用FFT执行稍微不同的版本。我将描述一个过程,将这个问题转化为那个问题,在那里解决它,然后根据这个转化找出问题的答案。
我知道如何用FFT解决的问题是在数组中找到长度为3的算术序列:即序列a
,b
,c
与c-b=b-a< /code>,或等价地
a c=2b
。
不幸的是,转变的最后一步并不像我希望的那么快,但是当我们到达那里时,我会谈论这个。
让我们调用原始数组
X
,它包含整数X_1。。。,x_n
。我们想找到索引i
,j
,k
,这样x_i x_j=x_k
。
>
在
O(n)
时间中找到X
的最小u
和最大v
。让u'
bemin(u,u*2)
和v'
bemax(v,v*2)
。
构造一个长度
将为真。这是要初始化的v'-u'1
的二进制数组(bitString)Z
;如果X
或其双[x_1*2,...,x_n*2]
包含u'i
,则Z[i]O(n)
;只需遍历X
的每个元素,并设置Z
的两个相应元素。
在构建这个数组时,我们可以将找到的任何重复项的索引保存到一个辅助列表Y
。一旦Z
完成,我们只需在Y
中为每个x_i
检查2*x_i
。如果有人在场,我们就完了;否则,重复项就无关紧要了,我们可以忘记Y
。(唯一稍微复杂一点的情况是,如果重复0
,那么我们需要它的三个不同副本来获得解决方案。)
现在,您的问题的解决方案,即x_i x_j=x_k
,将在Z
中显示为三个等距的一,因为一些简单的代数运算给我们提供了2*x_j-x_k=x_k-2*x_i
。注意,在endpoint上的元素是我们特殊的加倍条目(从<代码> 2x< /代码>),中间的条目是一个常规条目(从<代码> x< /html" target="_blank">代码>)。
考虑将Z
作为多项式p
的表示,其中度i
项的系数是Z[i]
。如果X是[1,2,3,5]
,那么Z是11110001
(因为我们有1, 2, 3, 4, 5, 6和10);p是1 x x2x3x4x5x9。
现在,请记住高中代数中,两个多项式乘积中xc的系数是所有a,b的和,其中a b=c是xa的第一个多项式的系数乘以xb的第二个多项式的系数。因此,如果我们考虑q= p
Z
是二进制的,这正是
Z
中三元组i,j,k的数量,它们是均匀分布的。注意,(j,j,j)总是这样的三元组,所以我们只关心有值的三元组
然后,我们可以使用快速傅立叶变换在O(|Z | log | Z |)时间中找到p2,其中
|Z |
是v'-u'1
。我们得到另一组系数;称之为W
。
循环遍历
X
中的每个x_k
。(回想一下,我们想要的均匀间隔的函数都以X
元素为中心,而不是2*X
。)如果这个元素的两倍对应的W
,即W[2*(x_k-u')]
为1,我们知道它不是任何非平凡级数的中心,我们可以跳过它。(如前所述,它应该只是一个正整数。)
否则,它可能是我们想要的级数的中心(所以我们需要找到
i
和j
)。但是,不幸的是,它也可能是没有我们想要的形式的级数的中心。所以我们需要检查。循环查看X
的其他元素x_i
,并检查是否有2*x_i
,x_k
,2*x_j
(通过检查Z[2*(x_k-x_j)-u']
)。如果是这样,我们就有了答案;如果我们通过所有的X
而没有命中,那么FFT只找到了虚假的答案,我们必须检查W
的另一个元素。
因此,最后一步是O(n*1(与W的x_k数[2*(x_k-u')]
我认为可以用一个有点不同的多项式来做这件事,但是我还没有让它真正起作用。我会再考虑一下......
部分基于这个答案。
我有一个浮点数的 MxN 数组 A,我想进行以下操作:对于 A 的每一列,计算小于某个阈值(例如 0.5)的元素数量。 Julia执行此操作的最快方法是使用零初始化结果向量,然后按列遍历数组A并在需要时递增结果向量。例如,使用for循环执行此操作很容易 这将按照与内存中的布局相同的顺序遍历 A,并且不会分配不必要的额外空间。但是,我不确定如何使用例如广播运营商来实现这一点。 但是这只是为了执行操作
问题内容: 我必须为重复对象的排列评估以下公式 其中和(总共有n个对象,其中r1类似于1种,r2类似于第二种,依此类推,该公式表示此类对象的排列数目)。 我需要一个有效的编码解决方案,因为在Java中使用大整数并不能证明在大情况下是有效的。 提前致谢。 问题答案: 您可以使用 设计来解决您的问题。 请参阅此链接以供参考 要么 像这样 : 资源
我有以下Obj-c声明: 什么是Swift等价物?
问题内容: 试图了解如何比较数组。 苹果表示,阵列拷贝背后存在优化。看起来有时(并非总是)结构实际上是否被复制。 那就是 1)==遍历所有数组以执行基于元素的比较吗?(看起来像)->那么在非常大的阵列上的性能/内存使用情况如何? 2)我们确定如果所有元素都相等,==会返回true吗?我对Java字符串的==记忆犹新 3)有没有一种方法可以检查myArray1和myArray2在技术上是否使用相同的
问题 你想快速计算某数的平方根倒数。 解决方案 在 Quake Ⅲ Arena 的源代码中,这个奇怪的算法对一个幻数进行整数运算,来计算平方根倒数的浮点近似值。 在 CoffeeScript 中,他使用经典原始的变量,以及由 Chris Lomont 发现的新的最优 32 位幻数。除此之外,还使用 64 位大小的幻数。 另一特征是可以通过控制牛顿迭代法的迭代次数来改变其精确度。 相比于传统的,该算
本文向大家介绍php 二维数组快速排序算法的实现代码,包括了php 二维数组快速排序算法的实现代码的使用技巧和注意事项,需要的朋友参考一下 php 二维数组快速排序算法的实现代码 二维数组排序算法与一维数组排序算法基本理论都是一样,都是通过比较把小的值放在左变的数组里,大的值放在右边的数组里在分别递归。 实例代码: 如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的