我怎么会误解这些Java函数的Big-O?

时间:2017-03-15 14:22:56

标签: java loops big-o asymptotic-complexity

对于第一个例子,结果是:O(n),但不确定为什么。

例1:

for (k = 0; k <= n / 8; k++) // will be O(n/8) thus, O(n)
     System.out.println(k); // will be O(n)
System.out.println("Hello World!"); // will be O(1) because not in a loop
for (p = n; p >= 1; p--) // will be O(n-1) thus, O(n) 
     System.out.print(p % 2); // not sure what % will do here, but I think it's still O(n)
     // Overall I think it's O(n)

对于第二个例子。事实证明这是O(n ^ 2),不知道为什么。

例2:

for (k = 0; k < n - 1; k++) // will be O(n-1) or O(n)
     for (m = k + 1; m < n; m++) // will be O(n^2) because nested loop
        System.out.println(k * m); // not sure what this will do but I think it will be O(n^2)
     // Overall I think it's O(n^2)

对于第三个例子,结果是O(n),但不确定原因。

示例3:

for (i = n - 3; i <= n - 1; i++) { // not sure here, maybe O(n-1), thus O(n)
     System.out.println(i); // since it is nested then O(n)
     for (k = 1; k <= n; k++) // since this is the second loop, then O(n^2)
        System.out.println(i + k); // not sure what this will do, but I think it will be O(n^2)
} // Overall I think it's O(n^2)

最后的例子结果是O(n ^ 2),也不确定原因。

范例4:

for (a = 1; a <= n / 3; a++) // will be O(n/3) thus O(n)
     for (b = 1; b <= 2 * n; b++) // since it's a nested loop it will be O(2n^2) thus O(n^2)
        System.out.println(a * b); // not sure what this will do, but I think it will be O(n^2)
     // Overall I think it's O(n^2)

有人可以通读这些并解释我做错了什么。我的理由是我们跟踪“&#39; n&#39;变量,因为用户输入了什么,我们看到它是如何增长的。如果它是一个单一的陈述,那就是常数时间O(1),如果它在一个循环中默认为O(n),如果它在一个循环中嵌套循环“O(n ^ 2)。

请帮忙 谢谢

3 个答案:

答案 0 :(得分:3)

由于您在示例1,2和4中的猜测与您的解决方案相同,我假设您只遇到示例3的问题。

当您仔细查看第一行for (i = n - 3; i <= n - 1; i++)时,您会看到它从n-3转到n-1(包括),因此它不依赖于{{n 1}}。

for (i = n - 3; i <= n - 1; i++) { // O(3), so O(1) (since it'a a constant factor)
    System.out.println(i); // nested, O(1)
    for (k = 1; k <= n; k++) // O(n)
        System.out.println(i + k); // nested, so O(n)
} // Overall O(n)

答案 1 :(得分:2)

首先,你的推理似乎是正确的。

例如1,你迭代到n。使用Big O表示法,您只关心运行时复杂性的限制。因此,2n变为n,因此O(n)

例如2,您的运行时复杂度大于n,因为您基本上会迭代直到达到n,并且在每次迭代期间迭代,直到您达到该迭代的次数。所以它超过n,但它不到n^2。但是Big O是一个上限,所以你写下O(n^2)

例如3,在第一个for循环中进行闭环。无论n是什么,你只会执行4次块内的内容(这是一个恒定的次数)。嵌套for循环与示例1类似,因此O(n)

例如4,第一个for循环是O(n)(就像你说的那样,O(n/3)变为O(n))。嵌套的for循环大致相同。 O(n*2)变为O(n)。因此,它是O(n^2)

答案 2 :(得分:2)

让我查看你的每个例子,并尝试解释时间复杂性背后的原因。

你的例子:

for (k = 0; k <= n / 8; k++) // will be O(n/8) thus, O(n)
     System.out.println(k); // will be O(n)
System.out.println("Hello World!"); // will be O(1) because not in a loop
for (p = n; p >= 1; p--) // will be O(n-1) thus, O(n) 
     System.out.print(p % 2); // not sure what % will do here, but I think it's still O(n)
     // Overall I think it's O(n)

说明:
这是O(n),因为我们看到第一个循环运行n次,第二个循环运行n次。在计算复杂度时,我们得到O(n + n) => O(2n)。现在我们简化了删除常量的答案,因为它们不相关&#34; (&lt; =他们并非完全不相关,我们只是不计算它们。)

你的例子:

for (k = 0; k < n - 1; k++) // will be O(n-1) or O(n)
     for (m = k + 1; m < n; m++) // will be O(n^2) because nested loop
        System.out.println(k * m); // not sure what this will do but I think it will be O(n^2)
     // Overall I think it's O(n^2)

说明:
现在我们有一个运行n次的外循环,以及一个运行n次的内循环。这意味着我们的总时间为O(n*n) => O(n^2)。这非常不言自明。

你的例子:

for (i = n - 3; i <= n - 1; i++) { // not sure here, maybe O(n-1), thus O(n)
     System.out.println(i); // since it is nested then O(n)
     for (k = 1; k <= n; k++) // since this is the second loop, then O(n^2)
        System.out.println(i + k); // not sure what this will do, but I think it will be O(n^2)
} // Overall I think it's O(n^2)

说明:
由于第一个for循环从n - 3运行到n - 1,因此您的循环不依赖于n的值。所以我们只计算产生O(n)

的内循环

你的例子:

for (a = 1; a <= n / 3; a++) // will be O(n/3) thus O(n)
     for (b = 1; b <= 2 * n; b++) // since it's a nested loop it will be O(2n^2) thus O(n^2)
        System.out.println(a * b); // not sure what this will do, but I think it will be O(n^2)
     // Overall I think it's O(n^2)

说明:
这个和上面的代码之间的区别在于这个外部for循环依赖于n的值。随着n的增长,n/3也会增长(与n - 3n - 1相对。这使得O(n^2)