一、算法复杂度
-
什么是算法复杂度?
算法复杂度一般分为2个维度:时间复杂度和空间复杂度;针对空间复杂度的问题,现在的我们很少去关心了,因为磁盘内存等变得越来越廉价,我们以后说的复杂度一般只针对 时间复杂度
二、如何计算复杂度
估算如下计算次数
-
第 1 题
# 只执行了 1 次 , 时间复杂度为 O(1) def func(): a = 1
-
第 2 题
# 执行了 10 次 , 有一层循环,时间复杂度为O(n) def func(): for i in range(10): a = 1
-
第 3 题
# 执行了 10*10 = 100 次 , 有两层循环,时间复杂度为O(n^2) def func(): for i in range(10): for j in range(10): a = 1
-
第 4 题
# 执行了 10+ 9 + 8 + ... + 1 = 55 次 def func(): for i in range(10): for j in range(i, 10): a = 1
-
第 5 题
''' 用变量代替执行次数, 执行了 n+ (n-1) + (n-2) + ... + 1 = n * ((n+1) / 2) 次 化简后后:1/2 * n^2 + 1/2 * n 时间复杂度为:O(1/2 * n^2 + 1/2 * n) 由于我们一般只保留最高次的项,并且不保留系数,时间复杂度为:O(n^2) ''' def func(): n = 10 for i in range(n): for j in range(i, n): a = 1
-
第 6 题
''' 用变量代替执行次数, 执行了 2*(n+ (n-1) + (n-2) + ... + 1) = n * (n+1) 次 化简后后:n^2 + n 时间复杂度为:O(n^2 + n) 由于我们一般只保留最高次的项,并且不保留系数,时间复杂度为:O(n^2) ''' def func(): n = 10 for i in range(n): for j in range(i, n): a = 1 b = 2
-
7.比较5、6 两者时间复杂度相同,但是两者速度不同,不同之处是系数不同, 在n很大的情况下, 系数和非最高次项都是可以省略的
-
8.如果程序跑得太慢,有可能是一下两方面的原因:
①、时间复杂度过大 ②、常数项过大
算法复杂度常数
- 两个算法的时间复杂度均为O(n2),但也要区分跑几个n2, 速度是完全不一样的
- 系数和非最高此项均可视为常数
- 复杂度与速度没有必然联系,常数项在中间起了很大作用
- 如果n值越大,常数项的作用越小, 将n看成非常大,常数项便可以被忽略不计
三、常见的时间复杂度示例
-
时间复杂度为: O(1) 也就是常数复杂度
def func(): a = 1
-
空间复杂度为: O(N) 也就是线性复杂度 (通常特征是一层循环)
def func(): n = 10 for i in range(n): a = 1
-
多项式复杂度O(N^2) (通常特征是双层循环)
def func(): n = 10 for i in range(n): for j in range(i, n): a = 1
-
指数复杂度O(2^n)
def func(n): if n <= 1: return n return func(n-1) + func(n-1)
-
对数复杂度O(log(N))
# 此项时间复杂度为以2为底的log(N) 即 log2(N) def func(n): if n <= 1: return n return func(n // 2) + 1
-
渐进复杂度O(N)
def func(n): if n <= 1: return mid = n // 2 for i in range(mid+1, n): a = 1 func(mid)
相关数学计算公式如下:
f(n) = f(n/2) + n/2
f(n) = f(n/4) + n/4 + n/2
f(n) = f(n/8) + n/8 + n/4 + n/2
…推导出:
f(n) = n/2 + n/4 + n/8 + … <= n