[热题100] [动态规划] 322. 零钱兑换

97 阅读1分钟

题目描述

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

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

 

示例 1:

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

示例 2:

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

示例 3:

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

 

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 2^31 - 1
  • 0 <= amount <= 10^4

思路

/**
dp[0] = 0
dp[1] = dp[1-x]+1, for x in coins. if 1-x < 0. continue. if dp[1] == 0, dp[1] = -1
dp[2] = dp[2-x]+1, for x in coins.


if (i - j < 0 || dp[i-j] == -1) continue;
如果i-coin小于0,说明这个coin用不了。如果dp[i-coin]==-1,说明这个coin用不了。

 */

实现

class Solution {
    public int coinChange(int[] coins, int amount) {
        int n = amount+1;
        int[] dp = new int[n];
        for (int i = 1; i < n; i++) {
            dp[i] = Integer.MAX_VALUE;
            for (int j: coins) {
                if (i - j < 0 || dp[i-j] == -1) continue;
                dp[i] = Math.min(dp[i], dp[i-j]+1);
            }
            if (dp[i] == Integer.MAX_VALUE) dp[i] = -1;
        }
        return dp[n-1];
    }
}



/**
dp[0] = 0
dp[1] = dp[1-x]+1, for x in coins. if 1-x < 0. continue. if dp[1] == 0, dp[1] = -1
dp[2] = dp[2-x]+1, for x in coins.

 */