【LeetCode】322. 零錢兌換

Curryxin發表於2021-08-16

322. 零錢兌換

知識點:動態規劃

題目描述

給你一個整數陣列 coins ,表示不同面額的硬幣;以及一個整數 amount ,表示總金額。

計算並返回可以湊成總金額所需的 最少的硬幣個數 。如果沒有任何一種硬幣組合能組成總金額,返回 -1 。

你可以認為每種硬幣的數量是無限的。

示例
輸入:coins = [1, 2, 5], amount = 11
輸出:3 
解釋:11 = 5 + 5 + 1:

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

輸入:coins = [1], amount = 0
輸出:0

輸入:coins = [1], amount = 1
輸出:1

輸入:coins = [1], amount = 2
輸出:2

解法一:動態規劃

  • 1.確定dp陣列和其下標的含義;dp[i]表示金額為i時所需要的最少硬幣個數;
  • 2.確定遞推公式,即狀態轉移方程;有兩種可能,1.有coin[i],也就是說如果某個小於當前金額i的j加上一個硬幣值coin就等於現在要求的金額,即j+coin=i,那dp[i] = dp[j] + 1;也就是金額為j時的最小值+這次的coin。2.不存在這一個coin面值,那要兌換的硬幣數量就是dp[i];
  • 3.dp初始化;base case; 最上面的元素,也就是dp[0]=0;同時對其他dp填充為amount+1,因為這是不可能的情況,其實就相當於初始化為正無窮,便於後面取最小值;
class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        Arrays.fill(dp, amount+1); //dp初始化為正無窮;
        dp[0] = 0;
        for(int i = 1; i < amount+1; i++){
            for(int coin:coins){
                if(i - coin < 0){
                    continue;  //湊不出這個i,無解;
                }
                dp[i] = Math.min(dp[i], dp[i-coin]+1);  //狀態轉移;
            }
        }
        return (dp[amount] == amount+1) ? -1 : dp[amount];
    }
}

相關文章