我的老师声称此代码块是在O(n)时间中运行的……为什么?

时间:2019-05-12 03:57:32

标签: c time-complexity

我的老师声称此代码块将花费O(n)时间来执行。我试图找出原因。我意识到捆绑在一起的两个for循环将是一个算术序列.....我的逻辑方法是,如果K = 3,则内部循环将运行3次,然后运行两次,然后运行一次。如果K = 2,则内部循环将运行两次,一次,然后停止。

在数学上,对于k = 3,它应该是N,N-1,N-2

后来我可以使用算术级数公式,得到N *(N +(N-(N-1))/ 2 ..

我不知道该如何处理while循环。

我可以推测的是,当N = 4时,循环运行两次,直到N = 9时,循环运行三次...我将如何在数学上进行设置?

最终结果是N *(N +(N-(N-1)))/ 2 + O(while循环)以获得O(N)?

任何建议将不胜感激。

void doit(int n) {
     int k = 0; int m = n; int s = 0;
     while (m <= n) {
         k = k + 1;
         m = k * k;
     }

     for (int i = 0; i < k; i++) {
         for (int j = i; j < k; j++) {
             s = s + m;
             m = m - 1;
         }
     }
 }

2 个答案:

答案 0 :(得分:5)

循环本身是O(k^2),但实际情况是循环之前。 while循环会找到比m = k^2大的最小平方数n,因此基本上是因为mn相关,最终结果实际上是{{1 }}。

答案 1 :(得分:1)

正如您所看到的,while循环和嵌套的for循环是相互独立的。因此,我们将分别计算每个时间的复杂度。

循环时

在while循环中,我们有独立于n的指令。这里的问题是我们如何计算while循环运行的次数。如果我们稍微作弊并以k而不是n的角度来看,我们会注意到,一旦退出循环,k将保持循环运行的次数对于。就像真的有柜台一样。此时k^2大致等于n,因此复杂度为O(sqrt(n))

用于循环

真正的魔术在这里发生,因为这部分将证明O(n)克服了while循环的O(sqrt(n))复杂性。


每个for循环所花费的时间可以看作是恒定数量的指令的总和。因此,我们将有一个嵌套的总和。我会尝试为您描述它,因为StackOverflow不会让我发布图片。您基本上有两个总和,一个以i=0开始并上升到(k-1),另一个是从j=1开始并上升到(k-1),并且您所加的都是一个常数命令数c

您可以轻松地计算出该总和,结果发现复杂度为O(k^2),但同样,我们必须考虑n,就像它变成O(n)一样。