从(n log ^ 2 n)到(n log n)时间的最近对算法

时间:2016-12-30 22:39:34

标签: algorithm sorting recursion closest-points

我试图了解如何从壁纸对算法的n log ^ 2 n时间到n log n时间。我得到以下部分(来自http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html

  1. 用线l将组分成两个大小相等的部分,并递归计算每个部分的最小距离。
  2. 设d是两个最小距离的最小值。
  3. 消除远离l
  4. 的d点
  5. 根据其y坐标
  6. 对剩余点进行排序
  7. 扫描y顺序中的剩余点,并计算每个点与其五个邻居的距离。
  8. 如果这些距离中的任何一个小于d,则更新d。
  9. 步骤4是一种需要O(n log n)时间的排序,它占据所有其他步骤,这是需要减少到O(n)的时间,以便整个算法实现O(n log) n)时间。这是我很难理解的部分。作者提出

    步骤1:将集合划分为...,并递归计算每个部分的距离,按y坐标按排序顺序返回每个集合中的点。 第4步:在O(n)时间内将两个已排序的列表合并为一个已排序的列表。

    您仍然需要在递归步骤中按y坐标对点进行排序,这需要O(n log n)时间。我们怎能避免这种情况?合并是O(n),但我们仍然必须在某处进行排序。

3 个答案:

答案 0 :(得分:1)

O( n log n )出现问题的原因是我们一遍又一遍地这样做:如果我们将集合划分为两个子集,并将其中的每一个划分为两个子集,然后涉及七种类型(整个集合中有一个,两个上半部分,四个四分之一)。

所以提案通过重用以前的排序结果来解决这个问题:所以我们对最小的分区进行完全合并排序(每个分区都是O(1),总计为O( n )) ,但是对于较大的分区,我们只需要执行单个O( n )合并传递来组合这些结果。所以我们只需要支付O( n log n )价格一次,这很好。

答案 1 :(得分:0)

他们的建议是你有两个(已经排序的列表)A和B.可以使用merge sort将这些组合成一个排序列表(恰好是步骤(4)中的合并步骤中的合并步骤) 。

合并排序的结果是一个排序列表,包含A和B的所有成员。一旦合并,就不需要再对任何内容进行排序。

答案 2 :(得分:0)

我提供了一种可能更容易理解的替代解决方案。首先在y坐标上对所有点进行排序。这是一次使用O(n log n)。有n个点,并且在排序的数组中,每个点都有一些最多为n的索引。保存每个点的索引(为索引添加整数到点数据结构)。然后运行原始算法。这一次,在我们想要对点进行排序的那一刻,不要使用正常的比较排序对它们进行排序。但是根据他们的索引对它们进行排序我们可以根据它们的索引用O(n)中的基数排序对它们进行排序。所以总过程是O(n log n),因为我们只使用了比较排序一次,其余的是T(n)= 2T(n / 2)+ O(n)。但是常数不如问题中提出的修改那么好。

问题中建议的修改过程就像合并排序中的合并一样:当我们有两个排序列表时,我们不需要使用正常排序再次对它们进行排序,我们可以通过在O(n)中合并它们来对它们进行排序。