计算一段代码的大O表示法复杂度

时间:2012-12-28 10:13:06

标签: big-o pascal

您能解释一下如何计算以下细分市场的Big O复杂性:

i := n;
while i > 1 do
  begin
    for j:= i div 2 + 1 to i do
      begin
        k := 2;
        while n >= k do
          k := k * k
      end;
    i := i div 2
  end;

(这是Pascal,但这里的语言并不重要。) 正确答案是n*log(log(n)),但我不知道如何到达那里。

1 个答案:

答案 0 :(得分:2)

从内部循环开始:

    k := 2;
    while n >= k do
      k := k * k

这将值2,2 2 ,2 4 ,2 8 ,..分配给k,直到达到n。这是O(log(log(n)),因为,如果我们调用迭代次数m,它会迭代直到

22m > n   →   log(22m) > log(n)   →   log(log(22m)) > log(log(n))   →

→   m > log(log(n))   →   m = log(log(n)) + 1

然后

for j:= i div 2 + 1 to i do
  begin
    //O(log(log(n))
  end;

这有i / 2次迭代,所以它是O((i / 2)log(log(n)))

i := n;
while i > 1 do
  begin
    // (i / 2) log(log(n))
    i := i div 2
  end;

这有O((i / 2)log(log(n)))的O(log(n))次迭代,总计为

  O( (n/2) log(log(n)) + (n/4) log(log(n)) + (n/8) log(log(n)) + (n/16) log(log(n)) + ... ) =
= O( (1/2 + 1/4 + 1/8 + 1/16 + ...)  n log(log(n)) ) =
= O( 0.1111111…2 n log(log(n)) ) =
= O( n log(log(n)) )

(0.11111 ... 2 = 1,就像0.999 ... 10 = 1,但无论如何都在O()无关紧要)