预期时间复杂度为 O(n^2),但结果为 O(n)。有人可以解释为啥吗?

Posted

技术标签:

【中文标题】预期时间复杂度为 O(n^2),但结果为 O(n)。有人可以解释为啥吗?【英文标题】:Expected time complexity of O(n^2), but it results in O(n). Can some explain why?预期时间复杂度为 O(n^2),但结果为 O(n)。有人可以解释为什么吗? 【发布时间】:2020-04-07 05:58:37 【问题描述】:

以下代码的时间复杂度应该是多少? 我试图想出 O(n2),但输出显示它是 O(n)。有人可以通过代码解释一下吗?

for(int i = 0; i < n; i++)
    for(; i < n; i++)
        cout << i << endl;
    

【问题讨论】:

@RSahu 我认为因为 OP 说 the output says it to be O(n) 表明他已经运行了代码并且只想解释输出 内循环第一次运行后,i==n,所以外循环也将终止。 【参考方案1】:

你的代码的复杂度是 O(n)。

为什么?

因为,即使您编写了两个 for 循环,这可能让您认为复杂度为 O(n2),但您的代码实际上是一个 for 循环,例如:

for (i = 0; i < n; i++)
    std::cout << i << std::endl;

一旦内部for循环结束,i等于n,因此外部for循环i &lt; n的条件不再满足。

【讨论】:

【参考方案2】:

使用这种 for 循环时要注意的一点是,您使用的是单个变量。

无论您添加多少个外部循环,您的代码都将导致与i&lt;n 普遍存在的条件相同。最里面的循环将运行到i=n-1,其余的根本不满足条件。

for(int i=0; i<n; i++)
 for(; i<n; i++)
   for(; i<n; i++)
     for(; i<n; i++) // and so on.
       std::cout<<i<<"\n";
    
  

为此提供一个变体,如果您要观察一个这样的 O(n2) 复杂度的情况,您的条件将是i&lt;n*n

for(int i=0; i<n; i++)
 for(; i<n*n; i++)
    std::cout<<i<<"\n";

【讨论】:

【参考方案3】:

您的代码的时间复杂度是 O(n) 而不是 O(n^2) 因为当内部循环结束时,此时 i 的值已经达到 n 。所以外循环不能再运行了。

for(int i = 0; i < 2; i++)
    for(; i < 2; i++)
        cout << i << endl;
    
   //after loop run two times i has value 2.
   //and outer loop cannot run anymore

【讨论】:

以上是关于预期时间复杂度为 O(n^2),但结果为 O(n)。有人可以解释为啥吗?的主要内容,如果未能解决你的问题,请参考以下文章

Shell Sort(希尔排序)

如何在时间复杂度为大O(N)的循环内对数组部分求和

二叉树 + 递归 + 分治法总结

给定一个长度为N的数组,找出出现次数大于n/2,n/3的数,要求时间复杂度O(n),空间复杂度O

归并排序的时间复杂度O(n*log n)是怎么得来的,求大神详细的讲解一下

图总结