【问题标题】:Three nested for loops slow down performance三个嵌套的 for 循环会降低性能
【发布时间】:2019-12-13 19:54:58
【问题描述】:

我想知道是否有另一种方法来解决这个问题,而无需像我在这里所做的那样使用 3 个嵌套的 for 循环?我知道,如果要在足够大的列表上测试该方法,那么以这种方式嵌套循环很可能会导致很多问题。

问题来了:

from typing import List

def can_pay_with_three_coins(denoms: List[int], amount: int) -> bool:
    """Return True if and only if it is possible to form amount, which is a
    number of cents, using exactly three coins, which can be of any of the
    denominations in denoms.

    >>> can_pay_with_three_coins([1, 5, 10, 25], 36)
    True
    >>> can_pay_with_three_coins([1, 5, 10, 25], 37)
    False

    """

这是我的解决方案:

for i in range(len(denoms)):
    one_coin = denoms[i]
    for j in range(len(denoms)):
        another_coin = denoms[j]
        for k in range(len(denoms)):
            last_coin = denoms[k]
            if one_coin + another_coin + last_coin == amount:
                return True
return False

我确信还有另一种方法可以解决这个问题,只是我真的想不出来。
感谢您的帮助!

【问题讨论】:

  • 如果你已经测试过(1,5,10),下面的任何一个都不需要测试:(1,10,5),(5,1,10),(5 ,10,1)、(10,1,5) 或 (10,5,1)。
  • 如果前两个硬币的总和已经超过金额,那么检查第三个硬币的任何内容都是没有意义的。
  • 我完全忘记了这种可能性。谢谢!

标签: python performance


【解决方案1】:

这是一个著名的问题,名为 3 sum。

这个解决方案的时间复杂度是O(n^3),你可以实现一个O(n^2)的算法,在下面的链接中用多种语言解释和实现:

Find a triplet that sum to a given value

【讨论】:

    【解决方案2】:

    好吧,让我们用 itertools 作弊吧:)

    import itertools
    from typing import List
    
    
    def can_pay_with_three_coins(denoms: List[int], amount: int) -> bool:
        """Return True if and only if it is possible to form amount, which is a
        number of cents, using exactly three coins, which can be of any of the
        denominations in denoms.
    
        >>> can_pay_with_three_coins([1, 5, 10, 25], 36)
        True
        >>> can_pay_with_three_coins([1, 5, 10, 25], 37)
        False
    
        """
    
        for variant in itertools.permutations(denoms, len(denoms)):
            if sum(variant[:3]) == amount:
                return True
    
        return False
    
    
    print(can_pay_with_three_coins([1, 5, 10, 25], 36))
    print(can_pay_with_three_coins([1, 5, 10, 25], 37))
    print(can_pay_with_three_coins([1, 1, 5, 10, 25], 37))
    print(can_pay_with_three_coins([1, 3, 5, 10, 25], 37))
    print(can_pay_with_three_coins([20, 20, 20, 50], 60))
    

    输出

    True
    False
    False
    False
    True
    

    【讨论】:

    • 不应该 print(can_pay_with_three_coins([1, 1, 5, 10, 25], 37)) 是假的吗?您的代码为 True。
    • 代码错误。例如,输入 [20, 20, 20, 50], 60 失败。这笔钱显然可以用三个硬币支付,但您的函数返回False。像这样的贪心算法不能用于求解 3SUM。
    • 哦,还有三个硬币。好的,我要删除答案 :D 绝对不正确。对不起
    • 无法删除已批准,因此我使用生成器对其进行了更新,它们在 python 中非常棒! @RobKennedy ;)
    • 您的解决方案的时间复杂度还不是很好,如果答案为真,则为 O(n^3),如果答案为假,则为 O(n!),如果您替换“len (denoms)" 乘以 3,您的时间复杂度将始终为 O(n^3),并不比 @Flavio Esposito 的解决方案好
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    相关资源
    最近更新 更多