这段代码的大O.

时间:2013-09-10 02:30:39

标签: algorithm time-complexity

我正在练习Skiena关于算法的书,我坚持这个问题:

我需要计算以下算法的大O:

      function mystery()
      r=0
      for i=1 to n-1 do
         for j=i+1 to n do
            for k=1 to j do
                r=r+1

这里,最外层循环的大O为O(n-1),中间循环为O(n!)。如果我错了,请告诉我。

我无法计算最里面循环的大O.

有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

分析如下:

  • 外部循环来自i = [1, n - 1],因此如果在此循环内仅执行常量操作,则程序将具有线性复杂度O(i) = O(n);
  • 但是,在第一个循环内,对于每个i,某些操作执行n次 - 从j = [i + 1, n - 1]开始。这使得总复杂度为O(i * j) = O(n * n) = O(n^2);
  • 最后,对于每个i以及每jk次执行最内层循环,k范围为k = [j, n - 1]。由于ji + 1 = 1 + 1开头,k渐近等于n,后者为O(i * j * k) = O(n * n * n) = O(n^3)

程序本身的复杂性对应于最内层操作的迭代次数 - 或者最内层操作的复杂性总和。如果你有:

for i = 1:n

    for j = 1:n

        --> innermost operation (executed n^2 times)

        for k = 1:n
            --> innermost operation (executed n^3 times)
        endfor

        for l = 1:n
            --> innermost operation (executed n^3 times)
        endfor

    endfor

endfor

总复杂度将以O(n^2) + O(n^3) + O(n^3)为单位,等于max(O(n^2), O(n^3), O(n^3))O(n^3)

答案 1 :(得分:2)

这是解决此问题的更严格方法:

将算法的运行时定义为f(n),因为n是我们唯一的输入。外循环告诉我们这个

f(n) = Sum(g(i,n), 1, n-1)

其中Sum(expression, min, max)是从expressioni = min的{​​{1}}的总和。请注意,在这种情况下,表达式是i = max的评估,其中包含固定的g(i, n)(求和索引)和in的输入)。我们可以剥离另一层并定义f(n)

g(i, n)

这是g(i, n) = Sum(h(j), i+1, n), where i < n h(j)范围ji+1的总和。最后我们可以定义

n

因为我们假设h(j) = Sum(O(1), 1, j) 需要时间r = r+1

此时请注意,我们还没有做过任何挥手,说“哦,你可以将这些循环加在一起。”'最里面的操作'是唯一重要的操作。“对于所有算法,该语句甚至不是 true 。这是一个例子:

O(1)

上述算法不是for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { Solve_An_NP_Complete_Problem(n); for (k = 0; k < n; k++) { count++; } } } ......它甚至不是多项式。

无论如何,既然我已经建立了严格评估的优越性(:D),我们需要向上工作,这样我们才能找出O(n^3)的上限。首先,很容易看出f(n)h(j)(只使用Big-Oh的定义)。由此我们现在可以将O(j)重写为:

g(i, n)

因此我们可以将g(i, n) = Sum(O(j), i+1, n) => g(i, n) = O(i+1) + O(i+2) + ... O(n-1) + O(n) => g(i, n) = O(n^2 - i^2 - 2i - 1) (because we can sum Big-Oh functions in this way using lemmas based on the definition of Big-Oh) => g(i, n) = O(n^2) (because g(i, n) is only defined for i < n. Also, note that before this step we had a Theta bound, which is stronger!) 重写为:

f(n)

您可以考虑证明下限以显示f(n) = Sum(O(n^2), 1, n-1) => f(n) = (n-1)*O(n^2) => f(n) = O(n^3) 。这里的技巧是简化f(n) = Theta(n^3)但在计算g(i, n) = O(n^2)时保持紧密限制。它需要一些丑陋的代数,但我很确定(即我实际上并没有这样做)你也可以直接证明f(n)(如果你真的那么直接f(n) = Omega(n^3)细致)。

答案 2 :(得分:1)

它不能是阶乘的。例如,如果你有两个嵌套循环,那么大的O将是n ^ 2,而不是n ^ n。所以三个周期不能超过n ^ 3。继续挖掘;)