找出所有给定数组中公共元素的最佳算法

Best algorithm to find out common elements in all the given arrays

本文关键字:元素 算法 最佳 数组      更新时间:2023-10-16

假设有 10 个数组,我们必须找出给定数组中的所有公共元素。

目前我正在选择第一个数组,对于第一个数组中的每个元素,我遍历所有剩余的数组,但这会增加时间复杂度。

有没有好的算法可以在最少的比较下做到这一点?

我假设你想要数组的交集。

基于哈希的方法:

这假定每个单独的数组中都有唯一的元素。

将第一个数组中的所有元素插入到要计数的元素的哈希映射中,计数从 1 开始。

然后遍历其余数组,增加每个遇到的元素的计数。

最后,输出计数等于数组数的所有元素。

可以在 C# 中使用Dictionary,也可以在 C++11 中使用unordered_map。您也可以在此处使用排序后的地图(例如map在C++)。

基于排序的方法:

对所有数组进行单独排序。

同时遍历所有数组,维护一个堆或二叉搜索树,其中包含每个数组中的一个元素。在每个步骤中,从结构中删除最小值,并从该元素所在的数组中添加下一个元素。

每当最小值 = 最大值时,输出该值。

我的猜测是,这可能与set_intersection所做的非常相似。

处理每个数组中的非唯一值:
(即1 2 2 3 42 2 4 5的"交集"应该输出2 2 4

  • 您需要记住上次输出值的时间是,并且仅在插入大于或等于数组数的元素数后才输出值。

    如果你不这样做,你会得到很多倍的结果。看一个交叉1, 11, 11, 1的简单例子。预期的输出是1, 1,但会发生这种情况:

    在结构中:1, 1, 1最小值 = 最大值 = 1,输出1删除第一个数组中的 1 个,并在结构中插入第二个 1:1, 1, 1最小值 = 最大值 = 1,输出1

    删除第二个数组中的 1 个,并在结构中插入第二个 1:





    1, 1, 1
    最小值 = 最大值 = 1,输出1
    删除第 3 个数组中的 1 个,并在
    结构中插入第二个 1:
    1, 1, 1最小值 = 最大值 = 1,输出1

    现在输出是1, 1, 1, 1.

  • 插入时,请确保始终将其插入所有其他相等值之后(即将其视为大于它们)。为此,您只需使用自动递增的唯一 ID 作为辅助比较值即可。

    如果你不这样做,你可以继续从同一个数组中删除元素,这会很快让你得到一个不同的元素,因此你不一定会输出正确数量的非唯一值。

    例如,如果我们相交1, 1, 1, 21, 1, 1,你可以碰巧从第一个数组中反复删除,分 3 步到达2,但是,由于上述一点,我们只输出每 2 步,因此我们只有 2 个而不是 3 个1

在 c++ 中有一个标准的算法 std::set_intersection。它适用于排序的两个序列。我想你几乎不会比这更好。对所有数组进行排序,然后按顺序调用set_intersection以获取结果。整体复杂度将O(N*log(N))其中 N 是数组的长度(如果它们具有不同的长度,则为最大长度)。

如果你是关于 C#,有一个很棒的东西叫做语言集成查询,它尽可能简化了查询集合,并提供并行执行 (PLINQ)。在 C# 中,只需为多个数组编写内部联接查询。