请帮我查一下以下代码的复杂性:
public static int method(int[] array, int n) {
for (i = 1; i < n; i++)
for (j = 1; j <= i; j++)
if (array[j] < array[j+1])
for (k = 1; k <= n; k++)
array[k] = array[k] * 2;
}
我需要知道如何以最佳和最坏的情况计算BIG-O,以此代码为例
答案 0 :(得分:2)
最好的情况是O(n ^ 2)最坏的情况是O(n ^ 3)。
无论如何,外部2个循环都会执行。
第一个循环运行i
= 1到n。它执行n次。
第二个循环向上运行j
= 1到i
。它执行n *(n - 1)/ 2次,这使它
为O(n ^ 2)。
第三个循环落后于if句子。因此,在最好的情况下,它永远不会执行,在最坏的情况下它始终执行。对于每次执行第二个循环,第三个循环执行n次。
所以O(n ^ 3)是最坏的情况(如果每次都评估为真)。
假设n是11;
第一个循环执行10次。
第二次循环执行(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)次,即10 * 9/2 = 45次。
这是1/2 * 10 ^ 2 - 5 - > O(n ^ 2)因为二次函数是最大的。
如果总是求值为true,则最内层循环执行:
45&amp; 10次= 450 = 1/2 * 10 ^ 3 - 50 - > O(n ^ 3),立方因子是最大的。
答案 1 :(得分:2)
对于这类问题,你能做的最好的事情就是画一张桌子。
让n
成为某个数字,由于最坏情况情景,我们假设始终满足if
:
i | j | k
-----+-----+-----
1 | 1 | 1
1 | 1 | 2
1 | 1 | ...
1 | 1 | n
2 | 1 | 1
2 | 1 | 2
2 | 1 | ...
2 | 2 | n
2 | 2 | 1
2 | 2 | 2
2 | 2 | ...
2 | 2 | n
.. | .. | ..
如果你继续这样做,你会直觉“内循环执行的次数取决于n
”,你会得到它是O(n 3 ) - 我强烈建议您在表格中填入更多值,以便更好地了解复杂性。
对于最佳方案,您将假设相反(if
永远不会满足),因此您将得到一个简单的嵌套循环,它将是O(n 2 )。
答案 2 :(得分:0)
O(n ^ 2)最佳情况:对于反向排序的数组;和
O(n ^ 3)最坏情况:对于排序数组。
补充说明:
java中的数组是零索引的。将计数器初始化为1通常是不好的做法,你应该将它们初始化为0;否则您可能会无意中跳过array[0]
。
如果有array.length == n
,您将获得2 ArrayIndexOutOfBoundsException
s:
(1st)array[j+1]
时j==i==n-1
(2nd)array[k]
时的k==n
。
如果ArrayIndexOutOfBoundsException
array.length < n
array[j]
,您将获得另一个{{1}}。