最近的一对点(CLRS第1043页):将已排序的数组拆分为两个已排序的数组的运行时间

时间:2016-12-26 05:48:04

标签: arrays algorithm sorting closest-points

在O(nlgn)时间内找到最接近的点对时,用于将排序列表拆分为两个排序列表(CLRS 3rd ed pg 1043)的伪代码据说在O(n)时间内运行。

algorithm from CLRS pg 1043

然而,这假设第4行在恒定时间内运行,我很难相信(我假设它在O(lgn)时间运行,如果它存储为二叉树,总运行时间为O (nlgn)。

Y是一个排序数组,YL和YR是两个新的子数组。 PL是随机顺序的Y的子集,YL是相同的子集,但是按排序顺序。

我的推理在哪里出错?

2 个答案:

答案 0 :(得分:0)

为简单起见,我们假设列表是整数而不是字符串或整数,这可能会使事情变得复杂。

这里有两个计算要考虑:

  1. for循环:这运行Y次的长度,我假设这里是N
  2. 棘手的部分 - Y [i]与PL的比较(注意:如果我们认为它们是单词大小,则两个数字的比较是不变的)。现在,访问Y [i]是不变的,因为我们正在处理随机访问机器。但是,要将它与长度为PL的数组进行比较,比如k将花费k时间。如果这个k非常小并且与输入数组Y的大小无关,那么理想情况下这将是恒定的。
  3. 以更高的精度写入它意味着你考虑k比较所花费的时间(PL的长度),因此,这个伪代码的总时间将是O(Nk)。但是,如果假设k是随机且独立于N的假设为真,那么它实际上是O(N)

答案 1 :(得分:0)

我不知道它应该如何在本书中运行,但考虑算法的外观,你可以提出以下想法:

  • Y[i]X[i]YL[i]XL[i]YR[i]XR[i]是整数,对应于{{1的索引th-point(所以你只需要存储一些全局数组,给定索引,返回ix坐标)。
  • y是一个布尔值,如果第PL[i]点位于左侧,则为true,否则为i

在每个递归步骤中,您可以使用false坐标(PL[i]时间)计算y。然后使用书中的算法将“左”和“右”两组中的点集分开,将行O(n)替换为if Y[i] in PL(此类访问为if PL[Y[i]],因此,总的来说,我们得到O(1))。

这具有O(n)时间复杂度并使用O(n)内存。

因此,最近的对问题在O(n)中以这种方式解决。