python各种内置函数的时间复杂度
最近在做题的时候常常遇到题目对于时间复杂度的控制,虽然暴力的方法可以通过OJ,但是这样做并没有达到题目本身的目的。虽然自己代码中循环结构的时间复杂度可以控制,但是却不是很清楚python各种内置函数和各种数据结构的可用方法的时间复杂度,所以查阅相关资料做个总结。
List
-
list.copy():copy操作需要将数组中的元素全部赋值给一个新的list,因此平均和最坏时间复杂度都是 O ( n ) O(n) O(n)
-
list.append(obj):append操作只需要在list尾部添加元素,不需要遍历整个list,因此平均和最坏时间复杂度都是 O ( 1 ) O(1) O(1)
-
list.pop(index):
- 当index = -1时,pop操作类似append,它只需要考虑list尾部的元素,因此平均和最坏时间复杂度都是 o ( 1 ) o(1) o(1)
- 当index位于 [ 0 , l e n ( l ) ] [0, len(l)] [0,len(l)]之内时,pop操作需要找到弹出元素的索引,因此平均和最坏时间复杂度都是 o ( k ) o(k) o(k)
-
list.insert(index, obj):插入元素需要遍历list先找到需要插入的位置,因此平均和最坏时间复杂度都是 o ( n ) o(n) o(n)
-
Get Item 、Set Item:获取或更新指定索引位置的元素只需要直接到该位置操作即可,因此平均和最坏时间复杂度都是 O ( 1 ) O(1) O(1)
-
list.remove(obj):移除指定的元素需要遍历整个list,因此平均和最坏时间复杂度都是 O ( n ) O(n) O(n)
-
list.extend(seq):extend操作在尾部扩展list,平均和最坏时间复杂度都是 O ( k ) O(k) O(k)
-
list.sort():sort操作这里使用的是归并排序(merge sort),因此平均和最坏时间复杂度都是 O ( n log n ) O(n \log n) O(nlogn)
-
x in s:最优情况是寻找的元素是list的第一个元素,最坏情况是寻找的元素是list的最后一个元素,因此平均时间复杂度 O ( n ) O(n) O(n)
-
min(s), max(s):时间复杂度为 O ( n ) O(n) O(n)
Set
集合(set)是一个无序的不重复元素序列。可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
set内置的各种函数:
- add():添加元素
- clear():清空集合
- copy():拷贝一个集合
- difference:返回多个集合的差集
- difference_update():移除集合中的元素,该元素在指定的集合也存在
- discard(obj):删除集合中指定的元素
- intersection(set1, set2 … etc):返回两个或更多集合中都包含的元素,即交集,返回一个新集合
- intersection_update():返回两个或更多集合中都包含的元素,在原始的集合上移除不重叠的元素
- set.isdisjoint(set2):判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False
- set.issubset(set2):判断指定集合是否为该方法参数集合的子集
- issuperset():判断该方法的参数集合是否为指定集合的子集
- pop():随机移除元素
- remove(obj):移除指定元素
- symmetric_difference():返回两个集合中不重复的元素集合
- symmetric_difference_update():移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中
- union():返回两个集合的并集
- update:给集合添加元素
各种操作的时间复杂度:
Operation | Average case | Worst Case | notes |
---|---|---|---|
x in s | O(1) | O(n) | |
Union s|t | O(len(s)+len(t)) | ||
Intersection s&t | O(min(len(s), len(t)) | O(len(s) * len(t)) | replace “min” with “max” if t is not a set |
Multiple intersection s1&s2&…&sn | (n-1)*O(l) where l is max(len(s1),…,len(sn)) | ||
Difference s-t | O(len(s)) | ||
s.difference_update(t) | O(len(t)) | ||
Symmetric Difference s^t | O(len(s)) | O(len(s) * len(t)) | |
s.symmetric_difference_update(t) | O(len(t)) | O(len(t) * len(s)) |
Dict
字典(dict)是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号(**{})**中
字典的两大特性:
- 不允许同一个键出现两次
- 键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行
dict内置的函数和方法:
- len(dict):计算字典元素个数
- str(dict):输出字典,一颗打印的字符串表示
- dict.clear():删除字典内的所有元素
- dict.copy():返回字典的浅复制
- dict.fromkeys():创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
- dict.get(key, default = None):返回指定键的值,如果值不在字典中返回default值
- key in dict:如果键在字典dict里返回true,否则返回false
- dict.items():以列表返回可遍历的(键, 值) 元组数组
- dict.keys():返回一个迭代器,可以使用 list() 来转换为列表
- dict.update(dict2):把字典dict2的键/值对更新到dict里
- dict.values():返回一个迭代器,可以使用 list() 来转换为列表
- dict.pop(key, default):删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值
- popitem():随机返回并删除字典中的最后一对键和值
各种操作的时间复杂度:
操作 | 平均时间复杂度 | 最坏时间复杂度 |
---|---|---|
Copy | O(n) | O(n) |
Get Item | O(1) | O(n) |
Set Item | O(1) | O(n) |
Delete Item | O(1) | O(n) |
Iteration | O(n) | O(n) |
Deque
deque是collection中表示双端队列的数据结构,它常用的方法有:
- append():在队列右端添加元素
- appendleft():在队列左端添加元素
- clear():清空队列
- copy():队列的浅拷贝
- count():返回指定元素的出现次数
- extend():从队列右端扩展一个列表的元素
- extendleft():从队列左端扩展一个列表的元素
- index():查找某个元素的索引位置
- insert():在指定位置插入元素
- pop():获取最右边一个元素,并在队列中删除
- popleft():获取最左边一个元素,并在队列中删除
- remove():删除指定元素
- reverse():队列反转
- rotate():把右边元素放到左边
各种方法的时间复杂度:
操作 | 平均时间复杂度 | 最坏时间复杂度 |
---|---|---|
Copy | O(n) | O(n) |
append | O(1) | O(1) |
appendleft | O(1) | O(1) |
pop | O(1) | O(1) |
popleft | O(1) | O(1) |
extend | O(k) | O(k) |
extendleft | O(k) | O(k) |
rotate | O(k) | O(k) |
remove | O(n) | O(n) |