找到与给定数字相乘的数字的有效方法

Posted

技术标签:

【中文标题】找到与给定数字相乘的数字的有效方法【英文标题】:Efficient way to find numbers that multiply to given numbers 【发布时间】:2020-05-24 07:34:42 【问题描述】:

我得到了2 列表、ab。它们都只包含整数。 min(a) > 0max(a) 最高可达1e10max(abs(b)) 最高可达1e5。我需要找到元组的数量(x, y, z),其中xa 中,y, zb 中,这样x = -yzab 中的元素个数最多可达1e5

我的尝试:

我想出了一个幼稚的n^2 算法。但是,由于大小可以达到 1e5,我需要提出一个nlogn 解决方案(最大)。我所做的是:

    b 拆分为bpbn,其中第一个包含所有正数,第二个包含所有负数并创建它们的映射。

    然后:

    2.1 我遍历 a 以获取 x 的。

    2.2 遍历bnbp 中较短的一个。检查当前元素是否除以x。如果是,请使用map.find() 查看z = -x/y 是否存在。

什么是有效的方法?

【问题讨论】:

也许您可以分解x 以获得它的所有质因数。如果只有一个,那么只有y = a, z = 1 是一个解决方案。如果有两个或更多,您将不得不搜索所有因子对 x0, x1 其中 x0*x1 = x 并找到您在步骤 2 中已经完成的那些。至少这样,您不只是暴力破解所有值的a(其中可以有很多)。 可以,但远低于10000000000 您可以为amap[a[i]] = true 创建map hash-container,据我所知b 可以是正数和负数,因此您可以通过快速排序对数组进行排序。因此,您可以找到“中性”元素 - 负数或零之后的第一个正数。在您可以对多个数字使用嵌套for循环后(外部循环只有负数,内部只有正数),乘法的结果用于检查映射map[b1*b2] == true中是否有这个结果@ @AyratArifullin 这与我所做的非常相似。复杂性仍然存在O(n^2) @AyratArifullin b 可以有1e5 元素,它们可以和1e5 一样大。这些数字不能相乘,会导致溢出 【参考方案1】: 第 1 步:对列表 b 中的元素进行排序(比如 bsorted) 第 2 步:对于 a 中的值 x,遍历列表 bsortedbsorted 中的每个值 y,并在 bsorted 上对 (-x/y) 进行二进制搜索以找到 z

复杂度 |a|=m 和 |b|=n 复杂度为 O(mnlogn)

【讨论】:

【参考方案2】:

没有 O(n*logn) 因为:z = -x/y log(z) = log(-x) - log(y)

正如https://***.com/users/12299000/kaya3 所提到的,它是3SUM#3_different_arrays。根据***:

Kane、Lovett 和 Moran 表明 3SUM 的 6 线性决策树复杂度为 O(n*log^2n)

【讨论】:

【参考方案3】:

这是一个未经验证的想法。从b 的元素创建trie,其中“字符”是有序的素数。对于a 中的每个元素,遍历trie 中的所有有效路径(DFS 或 BFS,其中测试能够被当前节点进一步划分),并且对于到达的每个叶子,检查剩余元素(在划分后每个节点)都存在于b 中。 (我们可能需要通过存储每个“单词”的计数并使用简单的组合来处理重复项。)

【讨论】:

以上是关于找到与给定数字相乘的数字的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode - 字符串数字相乘与相加

Swift - 将两个 NSDecimal 数字相乘

Java中 两个double型数字相乘的问题,想不明白是怎么回事

如何将两个数组与每个元素相乘作为数字c ++

如何实现两个数字相乘。在JS中

与 long 相乘时,数字的输出如何变化?