以下算法的计算复杂度?

时间:2017-02-26 18:31:37

标签: arrays algorithm complexity-theory

我有一个大小为 n 的数组 arr ,其中包含以随机顺序排列的整数1到 n ;例如,它可能是arr = [4 5 3 6 2 1]

对于 arr 中的每个元素 e ,我需要找到小于 e k >。 ("最接近"就位置而言,而不是价值;所以在上面的例子中,5更接近于3而不是6)。如果在两个方向上有相同的近似较小的元素 - 就像在6中一样上面的例子,其直接邻居都小于它 - 那么选择这些元素中的哪一个并不重要。

因此,通过上面的示例arr = [4 5 3 6 2 1],一个有效的结果是[3 3 2 2 1 NIL]

我知道有一个O( n )算法来解决这个问题;它通过维护一个堆栈来找到每个元素左右两侧最近的较小元素。

但令人惊讶的是,简单的线性双向搜索比该算法表现更好,即使在最坏的情况下我似乎是O( n 2 ): / p>

for i = 1 to N
  right = i + 1
  left = i - 1
  while (left > 0 && right <= n)
    // ...find the closest element that is smaller than arr[i] and break while loop

上述情况的最坏情况是什么?我是对的O( n 2 )?

1 个答案:

答案 0 :(得分:1)

这是最坏情况Θ( n log n )时间(假设你实现了Daniel上面提到的修复 - 你需要确保你可以扫描所有每个方向的结束方式)。

首先,观察如果两个元素 a b 是邻居,那么 a &lt; b b &lt; 。在任何一种情况下,这些元素中的至少一个将需要仅“1”的“搜索距离”。

通过扩展,至少有一半的数组元素需要的搜索距离仅为1。

同样,如果四个元素[ a b c d ]都在一行中,其中一个比其他三个少。因此,这些元素中至少有三个需要最多3个搜索距离。如上所述,其中两个实际上只需要1的搜索距离,所以这意味着两个搜索距离为1,第三个搜索距离为1。搜索距离最多为3.总搜索距离最多为2·1 + 1·3 +( n -1)。

我们可以继续这个逻辑来增加长度2 k 的运行:我们最多有2个 k -1 ·(2 1 -1)+ 2 ķ -2 ·(2 2 -1)+ 2 ķ -3 ·(2 3 -1)+⋯+(名词 -1)。

如果 n 是2的幂,那么我们可以将其写为2 k ,总搜索距离最多为:
2 ķ -1 ·(2 1 -1)+ 2 ķ -2 ·(2 2 -1)+ 2 ķ -3 ·(2 3 -1)+⋯ + 2 0 ·(2 ķ -1)=
=(2 ķ -2 ķ -1 )+(2 ķ -2 ķ -2 )+(2 ķ -2 < EM>ķ -3 )+⋯+(2 ķ -2 0
= k ·2 k - 2 k + 1
= n log n - log n + 1
&LT; n log n

(如果 n 是2的幂,那么我们可以通过附加值 n +1来获得更大的数组, n +2等,直到我们确实具有2的幂,并且观察到所得到的总搜索距离小于2 log 2 n < / i>,仍然在Θ( n log n )。)

当然,上面只设置了一个上限( O 而不是Θ);但我认为它显示了如何真正实现最坏情况:我们希望尽可能多地以尽可能多的方式传播,以两种方式。例如,我们可以“扩展”这样的列表:

1       2
1   3   2   4
1 5 3 6 2 7 4 8

如上所述,上述搜索总距离为7 + 1 + 2 + 1 + 4 + 1 + 2 + 1 = 17 = 3·8 - 8 + 1。