共计 1393 个字符,预计需要花费 4 分钟才能阅读完成。
时间复杂度一直很迷。。。。在网上找了看了一些博客,一句话,看不懂。。。。于是自己去学了一下,总结为下面的。
算法的效率,就是说一个算法的执行时间,它始终还是由我们执行每一行代码的次数来决定。我们可为每一个算法编写一个测试程序,然后拿到机器上去跑,但是由于除了算法本生,测试结果还受到很多其他因素的影响,列如 cpu 的执行速度等不确定因素,而且我们也不可能为了每一个算法去编写一个测试程序这样也不现实。
所以后来人们采用事前估算的方法,依据统计学。这种情况下抛开了其他所有的不确定因素,一个算法的好坏由一个算法的好坏和输入规模来决定。
例如:
当 n 很大的时候,两种算法的差距就打了起来,第一个是 2n+ 2 次,第二个始终都是 2 次。上面的两个算法分别可以看做时间复杂度为 n 和 1,下面来解释为什么是这样。
时间复杂度
研究算法的复杂度,侧重的研究输入规模很大的情况,在这种情况下我们就可以忽略一个复杂度中的一些小项,也就是执行次数特别大的情况,因为这样才能判定一个算法的在某种场景下的好与坏,这个时候就需要利用统计学知识。我们接下来通过大量的例子来解释。通过这几个例子为后面的算法时间复杂度做铺垫。
例一
将设 A 算法要做 2n+ 3 次计算,B 需要做 3n+ 1 次操作,你觉得哪一个更快一点呢。下面来看看统计的结果。
从结果来看最开始算法 A1 不及 B1,当 n 等于 5 的时候,慢慢超过它,到后面完全胜过它,这就是输入规模的重要性,而且我们看 A2、B2 发现当输入规模很大的时候常数项可以完全忽略。函数的渐进增长: 给定两个函数,f(n)、g(n),如果存在一个整数 N 当 n >N 的时候,f(n) 总是比 g(n) 大, 那么我们说 f(n) 的渐进增长比 g(n) 大。当
例二
算法 C 为 4n+8, 算法 D 为 2n^2 + 8
图上有错,第二张图为 C1、C2, D1,D2。从观察当中可以可以发现,当 n 很大的时候,相乘的系数,影响也很小了,比如 4n+ 8 和 n,在图上都重叠到一块儿去了,但是对于 C1、C2,系数有影响,但是对比 C、D 算法的时候,可以看出系数并不影响比较。可以得出结论系数不影响两个算法之间的比较,因此也可以去掉。
例三
算法 E 为 2n^2+3n+1,算法 F 为 2n^3+3n+1
通过图中对比 E、F 两个算法,可以看到指数对于测试结果影响很大。
例四
算法 G 为 2n^2,算法 H 为 3n+1, 算法 I 为 2n^2+3n+1
因此我们可以得出结论: 判断一个算法的效率的时候,函数中的常数和次要项都可以忽略,而更应改关注最高项的介数。
时间复杂度的计算
用大写 O() 来作为时间复杂度的记法,称为大 O 记法
那么我们怎么来推导大 O 阶呢。首先我们需要计算出程序执行的次数,再按照下面总结出来的方式来求解,这里的总结均来自前面的例子
只有常数项,将常数看做 1, 得到 O(1)
对于多项表达式,只保留最高项,且去除与这个项相乘的常数
其实就是这么简单。。。。,我在网上看到的其他文章语言实在太官方,明明简单的东西被这些糟老头子给整复杂了。下面来看几个计算的例子:
上面的时间复杂度为 O(1)
时间复杂度为 O(n)
时间复杂度为 o(n^2)
上面的例子为对数阶。假设程序执行 x 次退出循环,那么可以得到等式 2^x=n, 所以当 x =log(2 底数)n 的时候推出循环,执行次数为 log(2)n + 1,所以可以得到最终结果为 O(logn)
还有一个空间复杂度,空间可以换取时间,时间也可以换取空间,在实际当中往往要在二者之间达到一个平衡