【问题标题】:program speed/unnecessary double-counting程序速度/不必要的重复计算
【发布时间】:2013-01-12 05:46:29
【问题描述】:

我正在尝试在具有特定差异的数字列表中查找对数。说,用列表

1 2 3 4 5

和差异目标'2',我想打印数字'3',因为这个序列中有3对差异为'2'。但是,我的代码非常慢 - 它会重复计算所有对,因此我最终需要将我的解决方案除以 2 才能得到答案。有没有办法在不重复计算的情况下完成同样的任务?我很欣赏你可能有的任何见解。谢谢!代码打印在下面

    import sys


    def main():
        solutions=0
        pairs=[]
        for i in xrange(len(numbers)):
            for j in xrange(len(numbers)):
                if i!=j:
                    pairs.append([numbers[i], numbers[j]])

        for pair in pairs:
            if abs(pair[0]-pair[1])==k:
                solutions+=1
            else:
                continue
        return solutions/2



    if __name__ == '__main__':
        lines=sys.stdin.readlines()
        n,k=map(int, lines[0].strip().split())
        numbers=map(int, lines[1].strip().split())
        print main()

【问题讨论】:

  • 列表会一直排序吗?

标签: python performance cpu-speed


【解决方案1】:

对于a 中的每个元素i,您要检查i-diff 是否也在a 中。对于~O(1) 成员资格测试,我们可以使用一个集合。因此:

>>> a = [1,2,3,4,5]
>>> diff = 2
>>> a_set = set(a)
>>> sum(i-diff in a_set for i in a_set)
3

这是 O(len(a))。

[请注意,我使用了 i-diff in a_set,它是一个 bool,评估为 1 作为 int。这相当于sum(1 for i in a_set if i-diff in a_set)。]

更新:我突然想到我假设这些数字是唯一的。如果不是,那没关系,我们可以只使用collections.Counter 来保留多重性信息。

【讨论】:

    【解决方案2】:

    如果对数组进行排序,则只需遍历数组即可找到所有对,而不是进行 O(n^2) 搜索。重复计算的原因是您使用了abs,因此它不仅找到了 (1,3),还找到了 (3,1)。

    【讨论】:

    • 哦?你建议怎么做?
    • 很公平,但您确实需要构建一个完全独立的哈希表副本,因此需要考虑内存成本。
    【解决方案3】:

    首先对数组进行排序,然后为列表中的每个数字(num)查找num-2。我想最快的方法是通过binary search

    因此,通过二分搜索,您将获得O(n log(n)) 解决方案。

    【讨论】:

    • 这仍然是 O(n**2)。如果您使用set 而不是list,它会快很多。
    • @Tim 同意了,但我也建议他使用基于binary search 的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多