找出所有给定数组中公共元素的最佳算法
Best algorithm to find out common elements in all the given arrays
假设有 10 个数组,我们必须找出给定数组中的所有公共元素。
目前我正在选择第一个数组,对于第一个数组中的每个元素,我遍历所有剩余的数组,但这会增加时间复杂度。
有没有好的算法可以在最少的比较下做到这一点?
我假设你想要数组的交集。
基于哈希的方法:
这假定每个单独的数组中都有唯一的元素。
将第一个数组中的所有元素插入到要计数的元素的哈希映射中,计数从 1 开始。
然后遍历其余数组,增加每个遇到的元素的计数。
最后,输出计数等于数组数的所有元素。
可以在 C# 中使用Dictionary
,也可以在 C++11 中使用unordered_map
。您也可以在此处使用排序后的地图(例如map
在C++)。
基于排序的方法:
对所有数组进行单独排序。
同时遍历所有数组,维护一个堆或二叉搜索树,其中包含每个数组中的一个元素。在每个步骤中,从结构中删除最小值,并从该元素所在的数组中添加下一个元素。
每当最小值 = 最大值时,输出该值。
我的猜测是,这可能与set_intersection
所做的非常相似。
处理每个数组中的非唯一值:
(即1 2 2 3 4
和2 2 4 5
的"交集"应该输出2 2 4
-
您需要记住上次输出值的时间是,并且仅在插入大于或等于数组数的元素数后才输出值。
如果你不这样做,你会得到很多倍的结果。看一个交叉
在结构中:1, 1
和1, 1
和1, 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, 2
和1, 1, 1
,你可以碰巧从第一个数组中反复删除,分 3 步到达2
,但是,由于上述一点,我们只输出每 2 步,因此我们只有 2 个而不是 3 个1
。
在 c++ 中有一个标准的算法 std::set_intersection。它适用于排序的两个序列。我想你几乎不会比这更好。对所有数组进行排序,然后按顺序调用set_intersection
以获取结果。整体复杂度将O(N*log(N))
其中 N 是数组的长度(如果它们具有不同的长度,则为最大长度)。
如果你是关于 C#,有一个很棒的东西叫做语言集成查询,它尽可能简化了查询集合,并提供并行执行 (PLINQ)。在 C# 中,只需为多个数组编写内部联接查询。
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 求最大元素位置的分治算法
- 为什么这个选择排序算法仍然切换一个元素,当它已经是其他元素中最小的元素时?
- C++线性搜索算法,确定数组中元素的数量
- 打印所有儿童树元素的最佳算法?
- 使用 Rcpp 加速替换迭代算法中的列表和向量元素是否合法?
- 如何使用cpp编写选择排序算法以降序对元素列表进行排序?
- 找到对称矩阵的最大元素的最有效算法是什么
- 使用简单的暴力算法找到数组中最大的4个元素
- C++ 查找算法:如何找到元素的最后一次出现?
- 对数组进行排序的算法,先是第一个元素,然后是前 2 个元素,然后是前 3 个元素,依此类推
- 如何在不使用标准算法的情况下在排序向量中添加 c 元素?
- C++ std::向量插入两个元素替代算法失败
- 编写递归算法以从链表中删除元素.编写递归算法以将元素添加到链表中
- 使用算法中的插入函数将元素插入空容器中,未给出预期的结果
- 算法在容器中查找具有给定值的元素之一的成员
- 并行算法将向量的元素分配到另一个元素的元素
- 我如何在C 中制作算法,以在不重复的情况下查找集合的变化(即n元素,选择k)
- 删除元素的算法
- 在两个列表中匹配元素算法