《Python 每日一学》之短路法优化时间复杂度

昨天在 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)

常规优化思路:

  1. 降低遍历层级——经过分析觉得无法优化
  2. 降低遍历次数——引入短路法
  3. 快速查找到元素——引入二分法查找

经过分析,第一层遍历与第二层遍历次数无法进行减少,第三层引入短路法来减少遍历次数,具体实施:观察需要打印的元素都以 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 扫码一起学习:

《Python 每日一学》之短路法优化时间复杂度_第1张图片

你可能感兴趣的:(python)