不。考虑到时间复杂度渐近地描述时间——我们将较低的时间复杂度吸收到较高的时间复杂度中。
O(n²)
意味着k × n² + c
假设它c
是如此之低以至于我们不关心它。
这些是恒定的影响,整个事物(c)的一定数量的开销以及无论我们的复杂性是什么的一定数量的成本。如果一个算法有一个 lower ,或者如果它们相等,一个 lower ,它n²
就会击败另一个算法。此外,对于足够低的 n 值,O(n²) 与 O(1) 相同(我们通常不会在意,但每个可能会有很大不同,而且如果我们每做一次 m 次,那么 O( n²m) 优于 O(m),如果 n 很低,那不是真正比较的)..n²
k
c
k
无论如何,这是故意的过度简化,因为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 log n 次而不是 n² 次,那么就做,否则减少你正在做 n² 次而不是你正在做 n 次的其他事情的成本)。
换句话说,它帮助我们专注于通常重要的事情。