根据我的分析,这个算法的运行时间应该是N 2 ,因为每个循环都会遍历所有元素。我不确定if
语句的存在是否会改变时间复杂度?
for(int i=0; i<N; i++){
for(int j=1; j<N; j++){
System.out.println("Yayyyy");
if(i<=j){
System.out.println("Yayyy not");
}
}
}
答案 0 :(得分:6)
总运行时间 Tc + N x(To + NxTi + N / 2xTp)。
这等于 Tc + NxTo +(Nx(N / 2))x(2Ti + Tp),其由 K x(N ^ 2)界定对于 K>的值Ti + Tp / 2 为 N 变为无穷大。这个边界使得时间复杂度仍然 O(N ^ 2)。
不, if 语句不会改变此示例中的时间复杂度。
答案 1 :(得分:3)
没有。考虑时间复杂度渐近地描述时间 - 我们将较低的时间复杂性吸收到更高的时间。
O(n²)
表示k × n² + c
,假设c
非常低,我们不关心它。
这些是常数效应,整个事物(c)的一定开销和每个复杂性的一定数量的成本。如果n²
算法具有较低的n²
,或者如果它们相等,则k
算法会低于c
算法。另外,对于足够低的n值,O(n²)与O(1)相同(我们通常不会关心,但每个的k
可能会大不相同,而且如果我们每个都做然后,当O(n²m)击败O(m)时,如果n很低,那不是真正比较的那些)..
无论如何,这是一种刻意的过度简化,因为k
和c
可能不是真正的常数,就像常数一样好。因此,如果某事真的是O(n² + log(n))
,我们称之为O(n²)
,因为当我们担心log(n)
时,谁会关心那个小n²
?
因此。看着你的情况。我们做外循环,n
次。对于其中的每一个,我们进行内循环n-1
次。对于每个内部循环,我们进行第一次打印(任何成本差异都与n
无关,因此基本上不变)和测试。测试大约一半时间成功,导致第二次打印的成本经常上升。
所以总费用是:
cost of setting up everything +
n × cost of looping +
(n - 1) × cost of loop +
(n × (n - 1)) × cost of print +
(n × (n - 1)) × cost of test +
(n × (n - 1)) / 2 × cost of print.
将值分配给上面的常量,我们得到:
k +
n × a +
(n - 1) × b +
(n × (n - 1)) × c +
(n × (n - 1)) × d +
(n × (n - 1)) / 2 × e.
=
k +
n × a +
(n - 1) × b +
(n × (n - 1)) × (c + d + (e / 2))
现在,由于c + d + e / 2
本身是常数,因此可以成为:
n × a + (n - 1) × b + (n × (n - 1)) × c + k
或者按照最高订单的顺序重新订购:
(n × (n - 1)) × c + (n - 1) × b + n × a + k
如果n足够高,我们可以给出一个该死的,那么n按比例接近n-1,我们也可以认为它们是相同的(时间复杂度的另一个方面是渐近描述事物,就像n接近∞因此n²和(n×(n-1))之间的差异接近0)。因此:
n² × c + n × b + n × a = n² × c + n × (b + a) + k
同样,b + a本身是常数,所以它相当于:
n² × k + n × c + a
现在我们做了前面提到的吸收较低时间订单的事情,谁关心n × c
,没关系?如果n足够高,我们可以完全关心,那么它就是n²
。相比之下,我们可能只考虑作为噪声的总体开销的差异并将其视为:
n² × k + c
或换句话说,如:
O(n²)
所以,是的,你开始就开始使用它,if语句不会影响复杂性。
考虑到这一点,我们可以注意到时间复杂性可能会隐藏我们真正关心的内容。例如,如果我们有一个O(n²)算法,那么这种分析发现n² × k + n × c
的时间成本是k达到200μs而c达到15s,那么直到n大于750000它实际上是n比特成本,而不是每n比特。在较低的n,它更接近我们对O(n)的期望,而不是O(n²)。
时间复杂性有用的原因是,如此大的差异是罕见的组合,我们关心时间,因此关于时间复杂性,当n变高时更多(你可以隐藏一些可怕的O(n) !)你的代码中的怪物,你在蓝色的月亮中召唤一次,有三个元素,而且不在乎)。因此,为了实现真实世界的改进,我们理想地希望减少时间复杂度,或者不能降低最高级别常数k(或者换句话说,如果你可以开始做n次n而不是n次,那么不然降低你做n次的事情的成本,而不是你做了n次的其他事情。
换句话说,它有助于我们专注于通常使用的东西。
答案 2 :(得分:0)
当然,如果你正在使用基于比较的算法,那你算什么呢?
所以在你的情况下,你正在看O(n 2 ),因为你的if语句正在执行几乎n 2 次。
对于非比较算法,您可以计算任何主要操作。
答案 3 :(得分:0)
不,if不会影响复杂性。
答案 4 :(得分:0)
时间复杂度相同,你会打印Yayyyy N ^ 2次。
答案 5 :(得分:0)
简短回答:运行时仍为O(N ^ 2)。
长答案:条件检查的成本可以安全地“加”到println操作的权重,就像没有做一个println()一样,你有两个println()。 (关于这个例子,请记住像println这样的I / O操作的成本远远超过简单的整数比较。)
也许您可以说println()调用成本为“1操作”,并且比较为“0.0001操作”,因此总成本将是“(1.0001 * N)^ 2次操作而不是仅仅N ^ 2。你也将println()的数量减少了一半,所以我们可以说你在(1.0001 * N)^ 2/2次操作。这仍然是O(N ^ 2),即使是如果给定N值,则只需打印一半条目就可以将运行时间减半。
通常,比较的成本应该加到由该比较产生的分支内的操作成本中。当if(){}和else {}都存在时,测量运行时可能会更加困难。这里的一个策略是估计运行时,好像每次都发生最昂贵的操作 ;或者,如果单个分支的运行时间不易知道,则估计每次循环迭代都会发生两个操作。如果这些操作都是O(1),则运行时的顺序保持为O(N ^ 2),因为您是线性扩展的。