1. 时间复杂度:某个算法的时间耗费,它是该算法所求解问题规模n的函数
2. 渐近时间复杂度: 指当问题规模趋向无穷大时,该算法时间复杂度的数量级。
3. 评价一个算法的时间性能时,主要标准就是算法的渐近时间复杂度
计算步骤
求解算法的时间复杂度的具体步骤是:
⑴ 找出算法中的基本语句;
算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。
⑵ 计算基本语句的执行次数的数量级;
只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。这样能够简化算法分析,并且使注意力集中在最重要的一点上:增长率。
⑶ 用大Ο记号表示算法的时间性能。
将基本语句执行次数的数量级放入大Ο记号中。
如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环,则将并列循环的时间复杂度相加。例如:
for (i=1; i<=n; i++)
x++;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
x++;
第一个for循环的时间复杂度为Ο(n),第二个for循环的时间复杂度为Ο(n2),则整个算法的时间复杂度为Ο(n+n2)=Ο(n2)。
常见的算法时间复杂度由小到大依次为:
Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)
Ο(1)表示基本语句的执行次数是一个常数,一般来说,只要算法中不存在循环语句,其时间复杂度就是Ο(1)。Ο(log2n)、Ο(n)、Ο(nlog2n)、Ο(n2)和Ο(n3)称为多项式时间,而Ο(2n)和Ο(n!)称为指数时间。计算机科学家普遍认为前者是有效算法,把这类问题称为P类问题,而把后者称为NP问题。
Python数据类型的内置方法的时间复杂度
List ('n'是容器中当前的元素数, 'k'需要操作的元素个数)
操作 |
操作说明 |
时间复杂度 (平均情况) |
时间复杂度 (最坏情况) |
index(value) |
找list元素的索引 |
O(1) |
O(1) |
list[:] 或 copy |
列表复制 |
O(n) |
O(n) |
append |
队尾添加 |
O(1) |
O(1) |
insert(index,value) |
插入某元素 |
O(n) |
O(n) |
list[index] |
去某个元素 |
O(1) |
O(1) |
list[index]=value |
赋值 |
O(1) |
O(1) |
pop |
队尾删除 |
O(1) |
O(1) |
pop(index) |
根据索引删除某个元素 |
O(n) |
O(n) |
[i for i in list] |
遍历/迭代 |
O(n) |
O(n) |
list[m:n] |
取切片 |
O(k) |
O(k) |
extend([]) |
迭代添加 |
O(k) |
O(k) |
sort() |
列表排序 |
O(nlogn) |
O(nlogn) |
list*n |
列表乘法 |
O(nk) |
O(nk) |
i in list |
列表搜索 |
O(n) |
|
min(list), max(list) |
最大和最小值 |
O(n) |
|
len(list) |
计算长度 |
O(1) |
O(1) |
del / remove |
删除 |
O(n) |
O(n) |
字典
关于字典需要了解的是hash函数和哈希桶。一个好的hash函数使到哈希桶中的值只有一个,若多个key hash到了同一个哈希桶中,称之为哈希冲突。查找值时,会先定位到哈希桶中,再遍历hash桶。在hash基本没有冲突的情况下get, set, delete, in方面都是O(1)。
字典的键是从所有可能的键的集合中随机选择的。
操作 |
操作说明 |
时间复杂度 (平均情况) |
时间复杂度 (最坏情况) |
copy |
复制 |
O(n) |
O(n) |
dict[key] |
取元素 |
O(1) |
O(n) |
dict[key]=value |
更新元素 |
O(1) |
O(n) |
del /pop /popitem |
删除元素 |
O(1) |
O(n) |
get |
取元素 |
O(1) |
O(n) |
i in dict |
搜索元素 |
O(1) |
O(n) |
[i for i in dict] |
遍历字典 |
O(n) |
O(n) |
集合
增删改查和字典一样
操作 |
操作说明 |
时间复杂度 (平均情况) |
时间复杂度 (最坏情况) |
i in set |
搜索元素 |
O(1) |
O(n) |
set1 | set2 |
并集 |
O(len(set1)+len(set2)) |
|
set1 & set2 |
交集 |
O(min(len(set1), len(set2)) |
O(len(set1) * len(set2)) |
set1 - set2 |
差集 |
O(len(set1)) |
|
set^t |
对称差集 |
O(len(set)) |
O(len(set) * len(t)) |
set.difference_update(set2) |
更新 |
O(len(set2)) |
|
空间复杂度
是用来评估算法内存占用大小的方式。定义一个或多个变量,空间复杂度都是为1;列表的空间复杂度为列表的长度。
a = 'Python' # 空间复杂度为1
num = [1, 2, 3, 4, 5] # 空间复杂度为5
num = [[1, 2, 3,4],[1, 2, 3, 4],[1, 2, 3, 4],[1, 2, 3, 4],[1, 2, 3, 4]] # 空间复杂度为5*4
num = [[[1, 2], [1, 2]], [[1, 2], [1, 2]] , [[1, 2], [1, 2]]] # 空间复杂度为3*2*2