【问题标题】:Need help analyzing O(n) complexity需要帮助分析 O(n) 复杂度
【发布时间】:2020-09-07 21:46:48
【问题描述】:

我一直在努力完成我的算法和数据结构分析作业。使用 COVID-19 和电子学习,这很困难!特别是因为我的教科书被延期了 :(。我想知道是否有好心人可以帮助我分析这些 O(n) 问题。

我基本上理解它,但我在计算循环上的原始操作时遇到了很大的困难,例如 for( i = 0; i

不管怎样,我会把它们放在下面。顺便说一句,我将把我有根据的猜测放在下面。对我来说最重要的部分就是了解原始操作。即使我得到了正确的复杂性,我仍然很难从数学上得出那个解决方案。非常感谢您!

// #1 O(n)
sum = 0;
for( i = 0; i < 2n; i++ )
      sum++;
// #2 O(n^2)
sum = 0;
for( i = 0; i < 2n; i++ )
    for( j = 0; j < i; j++ )
         sum++;
// #3 O(n^4)
sum = 0;
for( i = 0; i < n2; i++)
    for( j = 0; j <  i; j++)
          sum++;
// #4 O(n^5)
sum = 0;
for( i = 0; i < n; i++)
   for( j = 0; j <  i*i; j++)
      for( k = 0; k <  j; k++)
          sum++;

【问题讨论】:

标签: algorithm time-complexity big-o space-complexity notation


【解决方案1】:

简单地说,时间复杂度是指我们的代码在更改输入时将花费多少时间,并以 n(输入大小)来衡量。

// #1 O(n)
sum = 0;
for( i = 0; i < 2n; i++ )
      sum++;

时间复杂度为 O(n),因为您只运行 1 个循环。如果 n 值为 10,则运行 20 次,如果 n 值为 20,则运行 40 次,以此类推。虽然时间复杂度随着2n的增加而增加,但是我们舍弃了这个常数,说时间复杂度是O(n),即时间复杂度会相对于n线性变化。

// #2 O(n^2)
sum = 0;
for( i = 0; i < 2n; i++ )
    for( j = 0; j < i; j++ )
         sum++;

这里外循环运行 2n 次,每 2n 次内循环将运行 i 次。如果您计算不同 n 值的操作,您将看到循环运行的次数改变了 n^2,而不仅仅是 n。 所以时间复杂度是O(n^2)。

// #3 O(n^4)
sum = 0;
for( i = 0; i < n2; i++)
    for( j = 0; j <  i; j++)
          sum++;

这里的外循环运行 n^2 次,对于每个外循环,内循环将运行 i 次(平均为 n^2)。所以外 n^2 X 内 n^2 是 n^4。所以时间复杂度是O(n^4)。

// #4 O(n^5)
sum = 0;
for( i = 0; i < n; i++)
   for( j = 0; j <  i*i; j++)
      for( k = 0; k <  j; k++)
          sum++;

第一个循环运行 n 次,第二个循环平均运行 n^2 次(ii 是 nn),第三个循环平均运行 n^2 次(j 将保持由于第二个循环,n^2 差异值)。所以总时间复杂度将是 O(n x n^2 x n^2) = O(n^5)

【讨论】:

    【解决方案2】:

    在分析时间复杂度的时候,可以忽略n之前的所有数字,比如2n就和n一样。因为当n变得无限大时,2就和1一样了。(这也是分析O()复杂度时很重要的一点)

    以#4为例,i是O(n),j是O(n^2),k也是o(n^2)。那么总复杂度将是所有这些的乘积,答案将是 O(n^5)。另一个例子#2,i就是O(n),和j一样,那么答案就是O(n^2)

    【讨论】:

      【解决方案3】:

      尝试从最内层循环开始预测每个循环如何变化sum。您应该能够以这种方式得出精确的表达。例如。对于您的第二个示例(我添加了一个显式乘法标记,希望这是正确的解释):

      sum = 0;
      for( i = 0; i <  in pretty much the same way, except for the different series.2 * n; i++ )
          for( j = 0; j < i; j++ )
              sum++;
      

      先替换内循环:

      sum = 0;
      for(i = 0; i < 2 * n; i++)
          sum += i;
      

      这很简单。有i 迭代,每次将sum 递增1,因此完整的循环可以用sum += i 替换。外循环有点棘手。我们正在总结从 0 到 2 * n 的所有整数,所以

      sum += 0 + 1 + 2 + ... + 2 * n - 1 + 2 * n
      

      现在有一个众所周知的公式(或者只使用 google 或 wolframalpha,两者都足以为像这样的简单案例找到封闭公式)

      1 + 2 + ... + n = n * (n + 1) / 2
      

      使用它,我们现在还可以减少外循环:

      sum = 0
      sum += 2 * n * (2 * n + 1) / 2 = 2*n^2 + n
      

      现在剩下要做的就是从表达式中删除所有低阶项和系数:

      sum = 2 * n^2 + n = O(n^2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 1970-01-01
        • 1970-01-01
        • 2021-05-13
        • 1970-01-01
        • 2018-05-13
        相关资源
        最近更新 更多