Python版-LeetCode 学习:518. 零钱兑换 II

给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。 

示例 1:

输入: amount = 5, coins = [1, 2, 5]
输出: 4
解释: 有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/coin-change-2

方法1: 动态规划

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        coin_len=len(coins)
        dp=[ [0 for _ in range(amount+1)] for _ in range(coin_len+1) ]

        for i in range(coin_len+1):
            dp[i][0]=1

        # 扫描全部coins和amount的组合
        for  i in range(1,coin_len+1):
            for j in range(1,amount+1):
                # 如果你不把这第 i 个物品装入背包,也就是说你不使用 coins[i] 这个面值的硬币,
                # 那么凑出面额 j 的方法数 dp[i][j] 应该等于 dp[i-1][j],继承之前的结果。
                # 如果你把这第 i 个物品装入了背包,也就是说你使用 coins[i] 这个面值的硬币,那
                # 么 dp[i][j] 应该等于 dp[i][j-coins[i-1]]
                # 
                if j-coins[i-1]>=0:
                    dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]]
                else:
                    dp[i][j]=dp[i-1][j]
        
        return dp[coin_len][amount]

方法2:缩两维数组为1维数组

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        coin_len=len(coins)
        # 压缩两维数组为1维数组
        dp=[0 for _ in range(amount+1)]
        dp[0]=1

        for i in range(0,coin_len):
            for j in range(1,amount+1):
                if (j-coins[i-1])>=0:
                    dp[j]=dp[j]+dp[j-coins[i-1]]

        return dp[amount]

 方法3:

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        coin_len=len(coins)
        
        # 特殊条件判断
        if amount == 0:
            return 1
        # 根据Python特性重新构建新的迭代关系,并修改原有的状态转移公式
        dp = [0] * (amount + 1)
        dp[0] = 1
        for coin in coins:
            for i in range(coin, amount + 1):
                dp[i] = dp[i] + dp[i - coin]
        return dp[amount]

猜你喜欢

转载自blog.csdn.net/guyu1003/article/details/107799521
今日推荐