在 O(mlogn) 时间内计算两个未排序数组的并集和交集
Posted
技术标签:
【中文标题】在 O(mlogn) 时间内计算两个未排序数组的并集和交集【英文标题】:Computing the union and intersection of two unsorted arrays in O(mlogn) time 【发布时间】:2016-03-08 20:56:19 【问题描述】:好的,所以我需要设计以下算法(无需代码,只需步骤):
给定两个集合 A
和 B
,长度分别为 m
和 n
,其中每个集合中的数字是不同的、未排序的和 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
。排序A
是O(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))
【讨论】:
关闭,但您混淆了m
和n
。排序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²)?