1. 程式人生 > >(Java) LeetCode 322. Coin Change —— 零錢兌換

(Java) LeetCode 322. Coin Change —— 零錢兌換

null i++ num CA and 動態規劃 沒有 下標 return

You are given coins of different denominations and a total amount of money amount. Write a function to compute 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.

Example 1:

Input: coins = [1, 2, 5], amount = 11
Output: 3 
Explanation: 11 = 5 + 5 + 1

Example 2:

Input: coins = [2], amount = 3
Output: -1

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


動態規劃典型問題,想一想遞推關系是什麽。假設dp[i]代表i這麽多錢所需要的硬幣數量,那麽對於每一個不同面值的硬幣coins[j]來說,dp[i] = dp[i - coins[j]] + 1。只要在遍歷coins面值的時候選擇需要數量最小的就好,即min(dp[i], dp[i - coins[j]] + 1)。通用情況想完了就要想初始情況。dp[0]顯然是0,不需要硬幣組成0元。而既然在遞推中要用到min,那麽把所有值初始為amount + 1的話即可,因為硬幣都是正數,不可能會存在需要比amount還多硬幣的情況。如果最後得到的結果比amount大(其實題裏並沒有說amount不會是最大正數,否則這樣取值就會overflow產生錯誤,test case裏面並沒有這種情況),證明沒有辦法組成面值,需要返回-1。需要註意的是因為i-coins[j]作為數組下標出現,顯然conis[j]不能比i大。


Java

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

(Java) LeetCode 322. Coin Change —— 零錢兌換