【问题标题】:How do I reduce the time complexity of this code snippet in Python?如何在 Python 中降低此代码段的时间复杂度?
【发布时间】:2021-05-29 06:05:46
【问题描述】:

我在这里有一个 compare 函数,它比较 2 个 4 位数字(非重复数字)并给出 xn1n2 中的位数,并且在同一位置),和yn1n2 中的位数,但位置不同)。我所做的是使用for 循环将数字存储为results 字典的键,并将相应的位置存储为results 字典的值。然后,我使用另一个for 循环遍历字典,得到xy。有什么办法可以降低这个函数的时间复杂度?

def compare(n1, n2):
    x, y = 0, 0
    result = {}
    s1, s2 = str(n1), str(n2)
    for i in range(0, 4):
        result[s1[i]] = i 
    for i in range(0, 4):
        if s2[i] in result:
            if result[s2[i]] == i:
                x += 1
            else:
                y += 1

【问题讨论】:

  • 这个任务的改进不能超过 O(n)。
  • @DeGo 所以我的代码的当前复杂度是 O(n)?抱歉,因为我对时间复杂度的概念不是很熟悉...
  • 重复你自己的问题:@Jover Tay:这个月你已经问了 3 次几乎相同的问题,请避免在 StackOverflow 上重复问题,你甚至不开车重复所需的细节和约束,如 aolny 4 位非重复数字:stackoverflow.com/questions/67345736/…stackoverflow.com/questions/67748271/…

标签: python algorithm loops for-loop time-complexity


【解决方案1】:

看起来你不可能在不访问整个列表的情况下获得 x 和 y。虽然您可以使用 nlogn 对列表进行排序,

【讨论】:

  • O(n logn)O(n) 差。我不确定你的建议是什么。
【解决方案2】:

Numpy 提供更好的矢量化解决方案。所以两个循环都被一个矢量解决方案替换,如下所示:

  1. 对于x,我们直接将每个索引值与其他相同的索引值进行比较,然后使用np.sum计算相同的数字。
  2. 对于y,我们只需要在数组中检查值,这可以使用np.in1d 作为矢量化解决方案来完成。

import numpy as np

def compare(n1, n2):
    s1, s2 = str(n1), str(n2)

    l1 = np.array(list(s1))
    l2 = np.array(list(s2))
    x = np.sum(l1 == l2)
    y = np.sum(np.in1d(l2, l1)) - x
    print(x, y)
    
compare(1023, 2024)

输出:

2 1

【讨论】:

    【解决方案3】:

    @DeGo 说你不能比 o(n) 更好。但是,您的代码可以改进,因为您正在做一些绝对没有必要的事情。我会将代码重写为

    from collections import Counter
    
    def compare(n1, n2):
        digits_at_same_position, digits_at_diff_position = 0, 0
        s1, s2 = str(n1), str(n2)
        l1 = list(map(lambda x, y: x == y, s1, s2))
        digits_at_same_position = sum(l1)
        l2 = list((Counter(s1) & Counter(s2)).elements())
        digits_at_diff_position = len(l2) - digits_at_same_position
        return digits_at_same_position, digits_at_diff_position
    
    print(compare(1234, 2435))
    

    效率等级是一样的。不过,这段代码会比你的更快。

    输出:

    >> (1, 2)
    

    【讨论】:

    • 此代码在数字为 1234 和 2435 时不起作用,因为else
    • @JoverTay 我更新了代码。现在应该可以了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多