变量相互依赖的三个代码的时间复杂度

时间:2017-09-08 04:42:17

标签: c++11

1) i=s=1;
while(s<=n)
{
   i++;
   s=s+i;
}            

2) for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j+=i)
      cout<<"*";

3)   j=1;
      for(int i=1;i<=n;i++)
          for(j=j*i;j<=n;j=j+i)
                cout<<"*";

有人可以解释这三个代码的时间复杂度吗?    我知道答案,但我无法理解它是怎么来的

1 个答案:

答案 0 :(得分:0)

1)为了解决这个问题,我们需要弄清楚s'循环迭代中x的大小。然后我们将知道在达到条件s > n之前会发生多少次迭代。

x'次迭代中,变量i的值为x + 1 并且变量s的值等于所有先前值的i之和。因此,在该迭代中,s的值等于

sum_{y = 1 .. x} (y+1) = O(x^2)

这意味着我们在s = n次迭代中有x = O(\sqrt{n})次。这就是循环的运行时间。

如果您不确定为什么总和是O(x^2),我会在here之后给出这样的另一个问题的答案,并采用相同的技巧。在这种特殊情况下,您还可以使用身份

sum_{y = 1 .. x} y = y choose 2 = (y+1)(y) / 2

这种身份可以通过y上的归纳轻松证明。

2)尝试分析内部循环的运行时间,作为in的函数。由于我们从一开始,以n结束,并按i计算,因此它会运行n/i次。所以外循环的总时间是

sum_{i = 1 .. n} n/i = n * sum_{i = 1 .. n} 1 / i = O(n log n)

系列sum_{i = 1 .. n} 1 / i称为谐波系列。众所周知,它收敛于O(log n)。我不能在这里附上一个简单的证据。虽然可以用微积分来证明。这是一个你必须知道的系列。如果你想看一个简单的证明,你可以在“比较测试”上查看维基百科。那里的证明只显示系列是&gt; = log n,但是同样的技术可以用来表示它也是<= O(log n)

3。)这看起来像是一个棘手的问题。内部循环将运行一次,但是一旦它以j = n + 1退出,我们就永远不会重新进入此循环,因为没有后续行会再次生成j <= n。我们将多次运行j = j * i,其中i为正数。因此,j最终将至少与n!一样大。对于n的任何重要值,这将导致溢出。忽略这种可能性,代码将总共执行O(n)次操作。