zoukankan      html  css  js  c++  java
  • [LeetCode] 518. Coin Change 2 硬币找零 2

    You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.

    Note: You can assume that

    • 0 <= amount <= 5000
    • 1 <= coin <= 5000
    • the number of coins is less than 500
    • the answer is guaranteed to fit into signed 32-bit integer

    Example 1:

    Input: amount = 5, coins = [1, 2, 5]
    Output: 4
    Explanation: there are four ways to make up the amount:
    5=5
    5=2+2+1
    5=2+1+1+1
    5=1+1+1+1+1 

    Example 2:

    Input: amount = 3, coins = [2]
    Output: 0
    Explanation: the amount of 3 cannot be made up just with coins of 2.
    

    Example 3:

    Input: amount = 10, coins = [10] 
    Output: 1

    给定一些不同面值的硬币,和一个钱数。编写函数计算要得到目标金额有多少种不同的硬币组合方式。

    322. Coin Change 的变形,322题是求最少能用几个硬币组成给的钱数,而这题求的是组成给定钱数总共有多少种不同的方法。

    解法:动态规划DP, 建立dp数组,保存能到达当前amount的步数。逐个金额遍历,看只用前i个金额能到达j的步数有多少,实现方法是累加起来dp[当前amount - 第i个金额],最后返回dp[amount]。

    State: dp[i], 表示总额为i时的方案数

    Function: dp[i] = Σdp[i - coins[j]],  表示总额为i时的方案数 = 总额为i-coins[j]的方案数的加和

    Initialize: dp[0] = 1, 表示总额为0时方案数为1

    Retrun: dp[n] or dp[-1]

    Java:

    public class Solution {  
        public int change(int amount, int[] coins) {  
            if (coins == null || coins.length == 0) {  
                return amount == 0? 1: 0;  
            }  
            int[] dp = new int[amount + 1];  
            dp[0] = 1;  
            for (int i = 0; i < coins.length; i ++) {  
                for (int j = 1; j <= amount; j ++) {  
                    if (j >= coins[i]) {  
                        dp[j] += dp[j - coins[i]];  
                    }  
                }  
            }  
            return dp[amount];  
        }  
    }   

    Python:

    class Solution(object):
        def change(self, amount, coins):
            """
            :type amount: int
            :type coins: List[int]
            :rtype: int
            """
            dp = [0] * (amount + 1)
            dp[0] = 1
            for c in coins:
                for x in range(c, amount + 1):
                    dp[x] += dp[x - c]
            return dp[amount] 

    扩展思考:将上述代码中的循环顺序对调,即为求不同硬币的排列数(Permutation)

    class Solution(object):
        def change(self, amount, coins):
            """
            :type amount: int
            :type coins: List[int]
            :rtype: int
            """
            dp = [0] * (amount + 1)
            dp[0] = 1
            for x in range(amount + 1):
                for c in coins:
                    if c > x: continue
                    dp[x] += dp[x - c]
            return dp[amount]  

    C++:

    class Solution {
    public:
        int change(int amount, vector<int>& coins) {
            vector<int> dp(amount + 1, 0);
            dp[0] = 1;
            for (int coin : coins) {
                for (int i = coin; i <= amount; ++i) {
                    dp[i] += dp[i - coin];
                }
            }
            return dp[amount];
        }
    };

    类似题目:

    [LeetCode] 322. Coin Change 硬币找零

    [CareerCup] 9.8 Represent N Cents 组成N分钱

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    A Node Influence Based Label Propagation Algorithm for Community detection in networks 文章算法实现的疑问
    Fast Newman-FN算法以及模块度定义介绍
    Label Propagation Algorithm LPA 标签传播算法解析及matlab代码实现
    设计一个smartnic
    Intel GEN11 GPU
    Intel GEN9 GPU
    Shared Virtual Memory (SVM) Functions
    connect via ssh to virtualbox guest vm without knowing ip address
    smartnic
    技术精品翻译
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8674222.html
Copyright © 2011-2022 走看看