我很难理解如何估算Big-O。我们已经有两个关于这个主题的讲座,我唯一不确定的是从函数中最大的多项式中取出前导系数,并用O替换它,所以它看起来像O(...)
在第一次演讲中,显示了
int i = length;
while (i>0) {
i--;
int j = i -1;
while (j >= 0) {
if (a[i] == a[j]) {
return 1;
}
j--;
}
}
return 0;
在下面的幻灯片中跟着这个
int i = length; // Counts as 1
while (i>0) { // Counts as N+1
i--; // Counts as N
int j = i -1; // Coutns as N
while (j >= 0) { // Counts as i+1
if (a[i] == a[j]) { // Counts as i
return 1;
}
j--; // Counts as i
}
}
return 0; // Counts as 1
由此,我想知道为什么
return 1;
不算作一步。
在幻灯片之后,它告诉我们
外环计数为3N + 1 内环计数为3i + 1;对于所有可能的我从0到N-1
据我所知,第二个[while]循环将出现N次并且在此之后,[if]将出现i次,其中i等于N-1,因为如果j< 0,第二个while循环仍将被读取,但之后不会发生其他任何事情。
幻灯片显示Inner循环的Total等于 3N ^ 2 - 1 / 2N
并且总计等于3 / 2N ^ 2 + 5 / 2N +3。
想知道是否有人有时间指导我如何获取Big-O估算中使用的函数,如上例所示;我不知道3i + 1如何翻译成3N ^ 2 - 1 / 2N以及如何计算总计。
答案 0 :(得分:1)
我将尝试解释您的示例复杂性的计算。
首先我们注意到,每个操作只需要恒定时间,写为O(1)
,这意味着运行时间不依赖于输入。
int i = length; // O(1), executed only one time
while (i > 0) { // outer loop, condition needs O(1)
i--; // O(1)
int j = i - 1; // O(1)
while (j >= 0) { // inner loop, condition needs O(1)
if (a[i] == a[j]) { // O(1)
return 1; // first return statement
}
j--; // O(1)
}
}
return 0; // second return statement, executed only one time
每个循环中的操作数是不变的,因此我们只需计算它们执行的频率。
外部循环从i = n
到i = 1
。对于每个i
,内循环执行一次并执行i
恒定时间操作本身。我们总得到
3 + Σi=0,...,n-13 + 3i + 1 = 3 + 4n + 3/2⋅(n-1)⋅n = 3/2⋅n² + 5/2⋅n + 3 (1) (2) (3) (4) (5)
说明:
n
次为true
次,一次评估为false
。3
包含对外循环条件和外循环中前两行的一种评估。3
前面的因子i
包含对内循环条件的评估,if语句的评估和内循环的最后一行。1
用于内部循环条件评估为false
的附加评估。1
to n
评估为1/2⋅n⋅(n+1)
。请注意,此处的总和来自0
到n-1
,因此评估为1/2⋅(n-1)⋅n
。不计算frist(内部)return语句,因为如果执行,算法将终止。但是我们想要计算最大步数,即所谓的最坏情况。这种情况是算法尽可能晚地终止。
注意:步骤的计算非常精确。这不是获得大O复杂性所必需的。可以说,每个循环都在O(n)中运行,并且因为它们是嵌套的,所以复杂度必须乘以所以得到O(n)⋅O(n) = O(n²)
。