Algorithm 使用分治法检测阵列中的重复项

Algorithm 使用分治法检测阵列中的重复项,algorithm,Algorithm,我在一次考试中被问到了下面的问题,似乎这是不可能的。有什么我遗漏的吗 给定一个由n个对象组成的数组,该数组只能进行相等比较,并且不知道数组中的值的范围,给出一个分而治之的解决方案,用于检测数组中是否存在任何重复项。这必须是O(nlogn)解决方案。 由于问题的性质,我们可以安全地假设解决方案可能与数据结构或基数排序无关,那么这可以在适当的位置完成吗 如果是,如何使用?如何使用哈希集。将每个项目添加到集合中。然后检查尺寸。然而,这不是分而治之 比较是否相等的结果是否会告诉您被比较的两个对象中哪一

我在一次考试中被问到了下面的问题,似乎这是不可能的。有什么我遗漏的吗

给定一个由n个对象组成的数组,该数组只能进行相等比较,并且不知道数组中的值的范围,给出一个分而治之的解决方案,用于检测数组中是否存在任何重复项。这必须是O(nlogn)解决方案。

由于问题的性质,我们可以安全地假设解决方案可能与数据结构或基数排序无关,那么这可以在适当的位置完成吗


如果是,如何使用?

如何使用哈希集。将每个项目添加到集合中。然后检查尺寸。然而,这不是分而治之


比较是否相等的结果是否会告诉您被比较的两个对象中哪一个“更大”


如果您可以创建对象集的总排序,我认为您可以使用一种就地divide和conq排序算法,但添加一些额外的逻辑来检测重复项。(打开如果您不能订购物品,则无法在
O(nlogn)
中检查重复项,如果您只能比较是否相等,则无法订购


事实上,除非你比较每一对,否则你不能确定没有重复的,而且有
n(n-1)/2
这样的对。

因为是O(nlogn),基本上你可以对数组排序并找到重复的。因为你想使用分治,我建议使用快速排序。

在nlogn时间内,你能做的唯一方法就是“欺骗”

在.NET和Java中,接口的任何实现,如.NET的IEquatable,它只公开一个Equals()方法,也是一个基本级别的对象。在.NET和Java中的对象都有一个哈希函数(在.NET中是GetHashCode();在Java中是hashCode()因此,无论接口限制您使用何种方法,您始终可以访问将生成数值的哈希函数

这将允许您散列每个对象并比较散列的相对大小。这反过来允许您按散列对数组进行排序,然后在线性时间内扫描它以检测重复项。您可以就地执行此操作,也可以将每个项插入到红黑树、哈希表或键入h的字典中,从而保持原始数组完好无损ash值(所有这些值都具有logN或更好的访问时间和logN或更好的插入时间)


如评论中所述,这些方法中的任何一种都可以并行化到多个线程,从而满足“分而治之”的要求;排序可以通过并行合并排序来完成,而根据您在环境中访问的对象,您可以使用线程安全的“并发”集合,从而允许您将数组拆分为多个线程插入到集合中的子数组。如果您通过一个元素将给定给每个线程的子数组重叠,则扫描已排序列表也可以并行化,以防止重复对中的一项意外地出现在一个子数组中,而另一项出现在下一个子数组中。

还有另一种方法来考虑分析吗?

同意,O(N^2)中的最坏情况。但最好的情况是O(1)

单纯地看一看只有
相等
,并且值的范围未知的事实,那么可以公平地说,只有一种方法可以得到N^2,即当所有值都不同或不相等时

类似地,只有一种方法可以保证在1个测试中找到重复项,即当所有值相等时

有许多方法不可能在找到一对相同的对象之前比较所有对象。如果有N/2对、N/3对三元组、N/4对四元组、N/sqrt(N)组sqrt(N)重复项等,那么在找到一对(即重复项)之前必须比较多少

我认为这就像“从一个袜子抽签中选择一双袜子,抽签中有未知数量的相同袜子,一套中有两个或更多相同的袜子”。抽签的所有者通过购买未知数量的相同袜子来补充抽签。当袜子上有洞时,他们会把袜子扔掉。我们不知道有多快袜子磨损了,或者说主人买袜子的速度有多快


平均而言,我们不希望性能比N^2好得多吗?

您可以使用修改后的快速排序解决此问题。如果不使用“比较”,您只需将其替换为相等运算符。修改后的快速排序会将项目分组在一起

然后,你所要做的就是寻找条纹来寻找重复

看看这个例子


所以这并不是要求所有的副本,只是要求任何副本(即两个或多个测试相等的对象)?如果所有元素都不同怎么办。我认为您需要检查每一对。@kilotaras是正确的,您必须比较每一对,这是O(n^2)@gbulmer是的,我们正在测试是否存在任何重复项。如果您可以比较LessThan或类似项,我认为这是可行的,但不能仅与相等项进行比较。您只能根据问题来比较相等项。我关于相等项检查的问题来自字符串相等项检查的结果,其中结果为-x、0或x以及所有让您创建一个完全有序的set.String.Compare()基本上是IComparer接口的一个实现,它比较的是相对大小,而不仅仅是相等。假设您对对象本身的访问权限是相等()方法接受另一个对象并返回true或false。创建哈希集本身需要检查重复项。您无法对数组进行排序,因为您只能比较是否相等……而且N(N+1)/2复杂度的算法不会真正受益于“分而治之”方法。请看下面我的答案。我认为它相应地解决了问题。正如科林的答案一样,将项目添加到字典(没有重复项)是
O(n)
,而不是