【发布时间】:2020-02-20 01:34:00
【问题描述】:
给定两个列表,假设 A = [1, 3, 2, 7] 和 B = [2, 3, 6, 3]
找出可以通过将 A 中的数字与 B 中的数字相乘来形成的所有产品的集合。(通过集合,我的意思是我不想要重复)。我正在寻找最快的运行时间。 不允许使用哈希函数。
第一种方法是蛮力,我们将 A 中的每个数字与 B 中的每个数字相乘,如果我们找到一个不在列表中的产品,则将其添加到列表中。查找所有可能的产品将花费O(n^2),并且要验证该产品是否已经存在于列表中,我将花费O(n^2)。所以总数达到O(n^4)。
我正在寻求优化此解决方案。我想到的第一件事是删除列表 B 中的重复项。在我的示例中,我有 3 个作为重复项。我不需要再次计算 A 中所有元素与重复 3 的乘积。但这仍然无助于减少整体运行时间。
我猜如果 A 和 B 中的所有数字组合起来都是唯一的 AND 素数,那么最快的运行时间可能是 O(n^2)。这样可以保证不会有重复,我不需要验证我的产品是否已经出现在列表中。所以我在想我们是否可以预处理我们的输入列表,以保证产品价值的唯一性(预处理的一种方法是像我上面提到的那样删除列表 B 中的重复项)。
这在O(n^2) 时间是否可行?如果我只关心可能的唯一产品的数量而不是实际产品的数量,这会有所不同吗?
for i = 1 to A.length:
for j = 1 to B.length:
if (A[i] * B[j]) not already present in list: \\ takes O(n^2) time to verify this
Add (A[i] * B[j]) to list
end if
end for
end for
print list
上述输入的预期结果:2、3、6、9、18、4、12、14、21、42
编辑:
我可以想到一个O(n^2 log n) 的解决方案:
1) 我生成所有可能的产品值而不用担心重复\这是O(n^2)
2) 对这些产品值进行排序\这将是O(n^2 log n),因为我们有 n^2 个数字要排序
3) 由于元素现在已排序,因此在线性时间内删除重复项
【问题讨论】:
-
"如果 A 和 B 中的所有数字组合都是唯一的。这样可以保证不会有重复",这是不正确的,A 和 B 中的所有数字都必须是唯一的 AND 素数
-
@FrançoisHuppé Omg 是的,你是对的。如果 A = [4, 6, 10] - B = [8, 20] 那么 (4, 20) 和 (10, 8) 是 80。我将编辑我的帖子。感谢您指出这一点。
-
您可以使用二叉搜索树/b-trees(一些语言,如 Rust 已经在标准库中具有基于 b-tree 的集合结构)将查找时间缩短到
log n以使您的整体算法n^2 log n. -
@EvilTak 如果我想要整体
n^2 log n我也可以想一个更简单的方法而不使用tress?我最后用那个解决方案编辑了我的帖子。这有意义吗? -
那么我认为你已经有了最好的时间复杂度,除非你会使用像基数排序这样的东西(猜测位数是恒定的,因为你处理的是 int 或 long),所以时间复杂度排序是 O(n^2),整体时间复杂度也是 O(n^2),这显然是你能达到的最好的。
标签: algorithm list performance runtime