【发布时间】:2023-03-10 14:28:02
【问题描述】:
我被一个问题困住了,我只需要一个大方向的提示/点(不要求答案)
该问题询问分治算法的详细信息,该算法给定一个几乎已排序的序列,在 O(n) 时间内产生正确的顺序。
他们所说的几乎排序的意思是给定列表
x_1, x_2, .... x_n
如果排序列表由
表示y_1, y_2, ... y_n
对于每一个 i, j
x_i == y_j && |i-j|
我想到的唯一一件事是将列表划分为每个级别的 root(n) 组(这将导致它们在第一次拆分时最多为 root(n)),但我不是太确定从那里去哪里,因为你必须在递归备份时一次加入 root(n) 个元素。
我还发现递归复杂度方程是:
T(n) = root(n) * T(n/root(n)) + d * root(n)
master's theorem 可以证明是 O(n) 时间。
所以看起来我在拆分方面走在正确的轨道上,我只是不确定是否应该以特殊方式拆分或比较某种方式或什么。
编辑:所以应该这是正确的答案。
我们的算法如下:如果 n > 1,那么我们递归地对序列的两半(近似)进行排序;现在所有元素都在正确的位置,除了中间的√n个位置(你明白为什么这是真的吗?);所以我们现在对这些位置的元素进行合并。如果我们让 T(n) 是用于对 n 个元素进行排序的时间,那么对于 n > 1,我们有
T(n)≤2T(⌈n=2⌉) +c * √n
由于 √(n) = n.5 和 .5 22,分治递归主定理告诉我们 T(n) ∈O(n)。
我不确定我是否同意,因为排序两半的时间是 O(n⁄2 * log(n ⁄2)) 结果为 O(n*logn),最终合并为 O(√n * √n),即 O(n),总共为 O(n *logn + n) -> O(n*logn)
【问题讨论】:
-
有点不对劲——每个比较排序都需要 Ω(n log n) 次比较来对 √n 个包含 √n 个元素的列表进行排序。
-
条件 x_i == x_j 看起来很可疑......
-
更正版本:列表 x(1), ..., x(n) 几乎已排序 如果存在排列 pi 使得 x(pi(1) )
-
@WolframH 你说得对,应该是 x_i == y_j,我现在已经更正了
-
我可能使问题过于复杂,并且可能暗示对问题有更严格的限制。但是你不能用合并排序来做到这一点。我们知道,在最坏的情况下,一个元素只需要与 2*root(n) 个其他元素进行比较。然后我们得到 T(n) = 2*T(n/2) + 2*root(n) 的修改归并排序递归,由 masters 定理给出 O(n)。还是我错过了什么?
标签: algorithm divide-and-conquer