在 O(mlogn) 时间内计算两个未排序数组的并集和交集

Posted

技术标签:

【中文标题】在 O(mlogn) 时间内计算两个未排序数组的并集和交集【英文标题】:Computing the union and intersection of two unsorted arrays in O(mlogn) time 【发布时间】:2016-03-08 20:56:19 【问题描述】:

好的,所以我需要设计以下算法(无需代码,只需步骤):

给定两个集合 AB,长度分别为 mn,其中每个集合中的数字是不同的、未排序的和 m<n。计算两个集合的交集和并集,在任一结果中都没有任何重复值。该算法应该在 O(mlog(n)) 时间内工作。

我很难找出具有如此时间复杂度的算法。最初,我想连接两个未排序的数组,然后对其执行合并排序并删除重复项,但这超出了很多复杂性。

【问题讨论】:

这对于普通的无序数组是不可能的。想象一个单项 A 被插入到一个大数组 B 中,那么您将至少在线性 (O(n)) 时间内检查 B 的每个条目一次。当然,对于存储在 in 数组中的哈希表,您平均可以在 O(m+n) 时间内完成,这是否允许? 嗯,我不确定。明天我会和我的教授一起去办公时间,看看她希望它如何发生,因为我同意这似乎不太可能。 【参考方案1】:

我错过了性能要求。解决方案在O(n log(m)) 中,而不是O(m log(n) ) 中要求的。

所需的运行时间是不可能的。证明已经在 cmets 中画出来了。基本思想是去极端情况下A 是单例集。然后性能要求归结为在运行时O(log(|B|)) 中检查给定元素是否包含在集合B 中。这是据我所知,但只有在 B 已排序或在 B 上存在某种索引结构时才有可能。


O(blog(m)) 解决方案

作为m<n,您可以对A 进行排序,结果是As。排序AO(m log(m)) < O(m log(n) )

在排序后的As 中找到一个元素是在O(log(m)) 中。所以你只需要检查B 的每个实例并确定它是否包含在As 中。

产生的运行时(滥用符号)是 O(n log(n))+ m* O(log(n)) = O(n log(n))+ O(n* log(m))=O(n log(m))

【讨论】:

关闭,但您混淆了mn。排序A 是 O(m log m),而不是 O(n log n)。在已排序的 A 中搜索一个项目是 O(log m),您需要这样做 n 次。所以结果是(m * log(m)) + (n * log(m))。此外,问题指出“每组中的数字是不同的”,因此您不必担心B 中存在重复。 感谢要排序的数组确实应该是B 如果m < n,那么n*log(n) > m*log(n)

以上是关于在 O(mlogn) 时间内计算两个未排序数组的并集和交集的主要内容,如果未能解决你的问题,请参考以下文章

以下算法在未排序数组中找到最小值的复杂性

未排序数组中累加和小于或等于给定值的最长子数组长度

为啥快速排序算法的时间复杂度是O(nlogn)而不是O(n²)?

长度为 N 的数组可以包含值 1,2,3 ... N^2。是不是可以在 O(n) 时间内排序?

中位数: 给定一个未排序的整数数组,找到其中位数。

如何以最有效的方式将两个未排序的数组合并成一个排序的数组?