【问题标题】:How do i calculate the time complexity of this function?我如何计算这个函数的时间复杂度?
【发布时间】:2016-06-21 22:55:49
【问题描述】:

大家好,我试图计算这个函数的时间复杂度,但我真的不明白如何计算那个“for循环”的复杂度

01    int* f(int a[], int n) {
02    int i = 1;
03    int *s;
04    s = calloc(n, sizeof(int));
05    while (i < n) {
06        for (j=0; j < i; j++)
07           s[i] = s[i] + a[j];
08        i = i*2;
09    }
10    return s;
11    }

练习要求与数组的维度“n”相关的时间复杂度

我不认为第 02,03,04 行是个大问题,因为它们的复杂度应该是 O(1)

对于while循环,如果我暂时将“for循环”放在一边,因为“i”每次乘以2,时间复杂度应该是2^k&lt;n --&gt; k= log_2(n)

但是 for 循环呢?它应该被执行“i”次,但是我该如何表达与“n”相关的呢?

P.S : 我如何写数学符号?我在编辑器中找不到任何东西

【问题讨论】:

    标签: c time-complexity


    【解决方案1】:

    外层循环执行log(n) 次,i 取值 1, 2, 4, 8, ...

    对于i的每个值,内部循环执行i次。

    所以你有 1 + 2 + 4 + 8 ... +

    其他人认为这是 O(n*log(n)),但他们犯的错误是将外部行程计数乘以内部循环的最大行程计数。要获得正确答案,您需要考虑到内部循环的行程次数每次都会翻倍,因此后面的行程次数会比之前的行程次数相形见绌。

    【讨论】:

      【解决方案2】:

      第一次迭代内循环运行一次,第二次迭代两次,第三次迭代内循环运行4次,依此类推。所以

       2^0 + 2^1 + 2^2 + 2^3 +.....+2^i where 2^i < n
      

      我们可以通过在2^i &lt; n 的两边取log 找到i,得到i=log2(n)

      2^0 + 2^1 +...+2^(log2(n)) ie 2^0 + 2^1 + ...+ n
      

      但是

      i < log2(n) and not i=log2(n).
      

      所以n 的先前值将是n/2

      所以我们终于有了

      2^0 + 2^1...+n/2
      

      主要术语是n/2,所以它的 O(n/2) 是 O(n)

      【讨论】:

        【解决方案3】:

        这实际上是一个棘手的问题。从技术上讲,您的观察是正确的。内部循环最多会执行n 次,所以看起来复杂度是O(n*log2(n))

        但这并不完全正确。问题是对于while 的第一次执行,内部for 循环执行一次、下一次两次、下一次四次等等,直到n/2(四舍五入到下一个2 的幂,所以最多到@ 987654326@)。所以总起来就是1+2+...n/2,也就是O(n)。 IE。线性复杂度。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多