LeetCode:322. Coin Change - Python

322. 零钱兑换

问题描述:

给定不同面额的硬币coins和一个总金额amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1

示例 1:

输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1

示例 2:

输入: coins = [2], amount = 3
输出: -1

说明:

  • 你可以认为每种硬币的数量是无限的。

问题分析:

动规题目,仔细看看,这个有点类似于上台阶问题了,意思就是最后到达总金额amount,有几个路径?废话不多说了,直接分析:

(1)可以这样思考,最后到达总金额amount,有几中可能?很显然有几种硬币就有几种可能。这就形成了从前一个状态到后一个状态的转变。可以得出动规方程式:

dp[i] = min(dp[i], dp[i - coins[j]] + 1)

解释:
dp[i]表示金额为 i 时的,最少硬币数,那么这个值怎么求?就是,把i - coins[j]此时的最少硬币数加一,就是当前的值,很显然有很多硬币,所以要选择出一个最小的值

Python3实现:

# @Time :2019/01/17
# @Author :LiuYinxing
# 动态规划


class Solution:
    def coinChange(self, coins, amount):
        """ :type coins: List[int] :type amount: int :rtype: int """

        dp = [0] + [amount+1] * amount  # 初始化dp

        for i in range(1, amount+1):
            for coin in coins:
                if i >= coin:  # 循环所有硬币,找到一个最少的一个
                    dp[i] = min(dp[i], dp[i - coin] + 1)

        return dp[-1] if dp[-1] != amount+1 else -1


if __name__ == '__main__':
    solu = Solution()
    coins,  amount = [1, 2, 5], 11
    print(solu.coinChange(coins,  amount))

声明: 总结学习,有问题或不当之处,可以批评指正哦,谢谢。

题目链接

点赞