【问题标题】:how i can find the time complexity of the above code我如何找到上述代码的时间复杂度
【发布时间】:2016-09-22 10:55:17
【问题描述】:
 for(i=0; i<n; i++) // time complexity n+1
{
    k=1;   // time complexity n
    while(k<=n) // time complexity n*(n+1)
    {
    for(j=0; j<k; j++) // time complexity ??
     printf("the sum of %d and %d is: %d\n",j,k,j+k); time complexity ??
    k++;
}

上述代码的时间复杂度是多少?我停留在第二个(for),我不知道如何找到时间复杂度,因为 j 小于 k 并且不小于 n。

我总是遇到与时间复杂度相关的问题,你们有什么好的文章吗? 特别是关于步数和循环。

【问题讨论】:

  • 复杂性在哪种情况下,最好的,最坏的,等等?
  • @WaqasShabbir 这有什么关系?据我所知,唯一的输入是n
  • 最糟糕的复杂性。我知道唯一的输入是 n,但第二个 for 取决于 k 而不是 n。
  • 它将是n*n*n,最后一个循环也通过kn相关

标签: algorithm time-complexity nested-loops


【解决方案1】:

来自问题:

因为j小于k且不小于n。

这完全是错误的,我想这是让你陷入困境的假设。我们知道 k 可以取什么值。在您的代码中,它的范围从 1 到 n(包括在内)。因此,如果 j 小于 k,它也小于 n。

来自 cmets:

我知道唯一的输入是 n,但第二个 for 取决于 k 而不是 n。

如果一个变量依赖于任何东西,它就依赖于输入。 j 依赖于 k,而 k 本身又依赖于 n,这意味着 j 依赖于 n

但是,这不足以推断复杂性。最后,你需要知道printf被调用了多少次。

无论如何,外部的 for 循环都会执行 n 次。我们可以考虑这一点。

内部for循环的执行次数取决于k,在while循环中修改。我们知道 k 从 1 到 n 的每个值都只取一次。这意味着内部 for 循环将首先执行一次,然后执行两次,然后执行 3 次,以此类推,直到 n 次。

因此,丢弃外部 for 循环,printf 被称为 1+2+3+...+n 次。这个总和是众所周知且易于计算的:1+2+3+...+n = n*(n+1)/2 = (n^2 + n)/2

最后,对printf 的调用总数为n * (n^2 + n)/2 = n^3/2 + n^2/2 = O(n^3)。这就是你的时间复杂度。

关于此类代码的最后说明。一旦您多次看到相同的模式,您很快就会开始认识到所涉及的复杂性。然后,当您看到这种带有因变量的嵌套循环时,您会立即知道每个循环的复杂性是线性的。

例如,在下面,f 被称为n*(n+1)*(n+2)/6 = O(n^3) 次。

for (i = 1; i <= n; ++i) {
    for (j = 1; j <= i; ++j) {
        for (k = 1; k <= j; ++k) {
             f();
        }
    }
}

【讨论】:

    【解决方案2】:

    首先,简化代码以显示主循环。所以,我们有一个结构:

    for(int i = 0; i < n; i++) {
        for(int k = 1; k <= n; k++) {
            for(int j = 0; j < k; j++) {
            }
        }
    }
    

    外循环运行n * n 次,但您对这些信息无能为力,因为内循环的复杂性会根据您所处的外循环迭代而变化,所以它没有那么简单计算外部循环运行的次数并乘以其他值。

    相反,我会发现从内循环开始,然后从最内层到最外层添加外层循环更容易。

    • 最内层循环的复杂度为k

    • 对于中间循环,它是k 的总和(上面的复杂性),其中k = 1 to n。所以1 + 2 + ... + n = (n^2 + n) / 2

    • 使用外部循环,它完成了n 次,所以再乘以n。所以n * (n^2 + n) / 2

    化简后我们一共得到O(n^3)

    【讨论】:

    • 我不知道你是怎么得到内循环运行的平均次数的,但不是(n^2 + n) / (2n + 2),它只是(n+1)/2。考虑到你最后得到了正确的结果,这有点奇怪。此外,第二个(中间)循环不会运行n * (n + 1) 次,只是运行n*n 次。
    • @Nelxost 我在稍后将总数除以n(n + 1) 的基础上添加了这一点,但我弄错了循环边界。改用n^2,就像你说的(n^2 + n) / 2n = (n + 1) / 2
    【解决方案3】:

    上述代码的时间复杂度为:n x n x n = n^3 + 1+ 1 = n^3 + 2 3 个循环加上两个常数。由于 n^3 的增长率最高,因此可以忽略常数值,因此时间复杂度为 n^3。

    注意:以每个循环为(n),并获得总时间,乘以每个循环中的(n)值。

    希望这会有所帮助!

    【讨论】:

    • 时间复杂度与n^3 + 2相差甚远,虽然是O(n^3)。此外,这并不能解释为什么您会将最内层的循环复杂度视为O(n)
    • "将每个循环作为 (n)" ??为什么??请解释。最内层循环取决于 k。你的答案是正确的。请正确解释答案背后的原因......
    • @User_Targaryen。上面我的解释已经很清楚了,如果你觉得不正确或者不完整,请提出一个更好的解释。发布此问题的人肯定需要像您这样的人的帮助。
    • 当最内层的循环依赖于k时,你从哪里得到n??如果将 2 个最内层的循环放在一起,您会发现 2 个内层循环运行 1 + 2 + 3 + .... + n 次 = n(n+1)/2,最外层循环运行 n 次。乘以所有,我们得到O(n^3)
    • @User_Targaryen 。谢谢开导。这是我所说的详细解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多