该计划的时间复杂性?

时间:2016-06-08 20:29:19

标签: algorithm time complexity-theory

1 i ← 1
2  while i < n/4
3   do
4    j ← 2i
5     while j < n
6       do
7         j ← j + 1
8     i ← i + 1


b) 1 i ← n
   2 while i > 1
   3   do
   4    j ← i
   5    while j < n
   6      do
   7        j ← 2j
   8    i ← i − 1


 c) 1 i ← 1
    2 while i < n
    3   do
    4     j ← 0
    5     while j ≤ i
    6       do
    7         j ← j + 1
    8     i ← 2i

鉴于这三个程序,找到每个程序的时间复杂度最简单的方法是什么?我可以说第一个可能是O(n ^ 2)。但是,有一种简单的方法来解决这个问题吗?我明天有考试。

1 个答案:

答案 0 :(得分:3)

(我会在总和限制中忽略1,舍入等)

A)

在内循环中,您执行n - 2i - 1次操作。在外循环中,您执行n/4 - 1。所以复杂性是:

enter image description here

所以你对第一个的回答是正确的。

B)

在内部循环中,j每次都会加倍,因此会呈指数增长;因此内循环采用对数时间 - log (n / i)。 (基数2但忽略WLOG)。内部i的划分是因为ji开始,因此相当于从1开始并逐渐增长到n / i。在外部循环中,您执行n - 1操作。

enter image description here

(最后一步来自 Stirling的近似值)

C)

在内循环中,您执行i + 1操作。在外圈i从1增加到n,所以log n

enter image description here

N.B。我注意到TypeKazt的答案存在显着差异;这说明你不能简单地将内循环的复杂性与外循环的“复杂性”相乘,并且内循环的边界条件在确定上是重要的。

编辑:作为我对TypeKazt(hehe sorry buddy)的大胆指责的补充证明,这是我从C#实现获得的一些测试数据:

enter image description here enter image description here enter image description here

如您所见,A(线性标度)的复杂度为O(n^2),而B和C(对数标度)的复杂度为线性。

代码:

static int A(int n)
{
   int c = 0;
   for (int i = 0; i < n / 4; i++)
      for (int j = 2 * i; j < n; j++)
         c++;
   return c;
}

static int B(int n)
{
   int c = 0;
   for (int i = n; i > 1; i--)
      for (int j = i; j < n; j *= 2)
         c++;
   return c;
}

static int C(int n)
{
   int c = 0;
   for (int i = 1; i < n; i *= 2)
      for (int j = 0; j <= i; j++)
         c++;
   return c;
}

P.S。我知道SO的政策不是为了照顾别人,而是为了一个人通过实例学习,所以我希望这能帮助你理解复杂性分析的简单分析方法。