322 - Coin Change 换零钱

问题描述

You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.

Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

You may assume that you have an infinite number of each kind of coin.

动态规划中非常经典的换零钱,零钱数量不计,给定整数amount,求使用最少的零钱构成amount,求零钱数量。如果零钱没办法组成 amount,则返回-1

案例:

Input: coins = [1,2,5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
解析: 两个零钱5 叠加1,构成11,所以结果是3

基本思想

非常经典的换零钱,零钱数量不计。假设 coins的大小为m

构造数组 dp,长度为amount+1,其中dp[i] 表示 conis组成 i的最少零钱数。则、

dp[i] 取决于 \(dp[i - coins[0]]\) , \(dp[i - coins[1]]\),...... \(dp[i - coins[m-1]]\)

即 dp[i] = min( \(dp[i - coins[0]]\) , \(dp[i - coins[1]]\),...... \(dp[i - coins[m-1]]\)) + 1

时间复杂度: \(o(m*n)\)

代码

C++

    int coinChange(vector<int>& coins, int amount) {
        int n = coins.size();
        if (n<=0 || amount <=0) return 0;
        vector<int> dp(amount+1,-1);
        sort(coins.begin(), coins.end());
        for(int i=0;i<coins.size();++i) {
            if (coins[i]<=amount)
              dp[coins[i]] = 1;
        }
        for(int i=1;i<=amount;++i) {
            int t = INT_MAX;
            for(int j=0;j<coins.size();++j) {
                if ((i - coins[j]) <= 0 || (dp[i-coins[j]] == -1))
                  continue;
                if (dp[i]>0) continue;
                t = min(t, dp[i-coins[j]]+1);   
            } 
            
            if (t<INT_MAX) dp[i] = t;
        }
        return dp[amount];
    }

python

    def coinChange(self, coins: List[int], amount: int) -> int:
        if amount <=0: return 0;
        n = len(coins)
        dp = [-1] * (amount+1)
        coins.sort()
        for coin in coins:
            if coin > amount: continue
            dp[coin] = 1
        for i in range(1, amount+1):
            t = amount + 1
            for coin in coins: 
                if i <= coin or (dp[i-coin] == -1):
                    continue
                if dp[i] > 0: 
                    continue
                t = min(t, dp[i-coin]+1)
            if t < (amount+1): dp[i] = t
        return dp[amount]
posted @ 2024-05-16 21:15  金字塔下的蜗牛  阅读(1)  评论(0编辑  收藏  举报