昨天在 Python 实战交流群里发起一个讨论:
在如下这个常见的遍历场景中,如何优化代码降低时间复杂度?
def tips_everyday_example():
vector = ['apples', 'apple', 'banana', 'bananas',
'carrot', 'carrots', 'pear', 'pears']
for _ in range(10000):
for item in ['apples', 'pears', 'bananas']:
if item in vector:
print(item)
今天提供一下我的思路供大家参考:
上面的 example 中虽然表面上看是 2 层遍历,但其实是三层遍历,
for _ in range(1000) 第一层,for item in ['apples', 'pears', 'bananas'] 第二层,item in vector 第三层,每一层的时间复杂度都为:O(n)
常规优化思路:
- 降低遍历层级——经过分析觉得无法优化
- 降低遍历次数——引入短路法
- 快速查找到元素——引入二分法查找
经过分析,第一层遍历与第二层遍历次数无法进行减少,第三层引入短路法来减少遍历次数,具体实施:观察需要打印的元素都以 s 结尾(总之要找到共同的特征),采用 and (其他语言为:&&) 判断表达式短路的方式减少遍历的次数,例如:
def binary_search(needle, haystack):
min, max = 0, len(haystack) - 1
while min <= max:
midpoint = (min + max) // 2
guess = haystack[midpoint]
if guess == needle:
return midpoint
elif guess > needle:
max = midpoint - 1
else:
min = midpoint + 1
return None
def tips_everyday():
vector = ['apples', 'apple', 'banana', 'bananas',
'carrot', 'carrots', 'pear', 'pears']
targets = sorted(['apples', 'pears', 'bananas'], key=str.lower)
for _ in range(10000):
for item in vector:
# 此处如果 item 不以 s 结尾 and 后面的二分法查找将进行短路不执行,以此达到了减少遍历次数的目的
if item.endswith('s') and binary_search(item, targets):
print(item)
希望参加《每日一学》的同学可以加 QQ 群:
- 群号:397234385
- QQ 扫码一起学习:
网友评论