【问题标题】:Closest pair of points (CLRS pg 1043): Running time of splitting a sorted array into two sorted arrays最近的点对(CLRS pg 1043):将排序数组拆分为两个排序数组的运行时间
【发布时间】:2016-12-26 05:48:03
【问题描述】:

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

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

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

我的推理哪里出了问题?

【问题讨论】:

  • 向PL添加Y的元素时,标记为属于PL。 (只是猜测,不知道PL是怎么形成的)。
  • 如果 PL 像相当大的 hashmap/hashset 一样,预期的平均查找时间可能是 O(1),但最坏的情况是另一回事......
  • @AlexanderAnikin 实际上,我们正在处理大 O 表示法的最坏情况。
  • @n.m. PL(为了这个算法)可以被假设为随机顺序的 Y 的子集。
  • 问题不在于它是什么,而在于用什么样的工艺来形成它。它是通过按某种顺序选取 Y 的元素形成的吗?

标签: arrays algorithm sorting closest-points


【解决方案1】:

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

这里有两个计算需要考虑:

  1. for 循环:运行 Y 次,我假设这里是 N
  2. 棘手的部分 - Y[i] 与 PL 的比较(注意:如果我们认为两个数字具有字长,则比较两个数字是恒定的)。现在,访问 Y[i] 是不变的,因为我们正在处理随机访问机器。但是,要将其与长度为 PL 的数组进行比较,例如,k 将花费 k 时间。如果这个 k 非常小并且与输入数组 Y 的大小无关,理想情况下这将是一个常数。

要以更高的精度编写它意味着您需要考虑 k 次比较所花费的时间(PL 的长度),因此,此伪代码的总时间将为 O(Nk)。但是,如果 k 是随机的且与 N 无关的假设成立,那么它确实是 O(N)

【讨论】:

  • PL 取决于 N - 你可以假设 k = N/2,但那是
【解决方案2】:

我不知道书里应该怎么做,但是想想算法的样子,你可以想出如下思路:

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

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

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

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

【讨论】:

  • 我同意它有 O(n log n) 时间,但本书声称它有 O(n) 时间。
  • @max_max_mir:我的意思是O(n log n) 总体上是针对整个最接近对问题的(这个特定的步骤确实是O(n))。
  • 你能举个例子吗?假设 Y = [(3,1), (2,2), (4,3), (1,4), (6,5)] 并按 y 坐标排序。 PL 为 [(1,4), (3,1)] 并按 x 坐标排序。如果我在 Y 中查找任何点的列表 PL,我需要 O(n) 时间。但是,我认为您是说有一种方法可以进行某种反向查找以确定一个点是否在 PL 中,这需要 O(1) 时间 - 但我不太明白如何。
  • @max_max_mir:我稍微改变了YPL的定义。假设我们有一些全局数组xof = [2, 3, 4, 1, 6]yof = [2, 1, 3, 4, 5](任意顺序的点)。然后Y = [2, 1, 3, 4, 5] 是排序数组的 indices 数组(此处为 1-indexed)。 PL = [1, 0, 0, 1, 1] 表示例如(2, 2)(1, 4)(6, 5) 属于左侧部分。
猜你喜欢
  • 2023-01-19
  • 2015-10-06
  • 1970-01-01
  • 2017-05-27
  • 2012-06-28
  • 1970-01-01
  • 2019-12-02
  • 2017-07-16
  • 2021-03-05
相关资源
最近更新 更多