给你一个整数数组 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

示例 4:

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

示例 5:

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

 

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104
Related Topics
  • 广度优先搜索
  • 数组
  • 动态规划

  • 👍 1479
  • 👎 0
  • emmm动态规划,一开始想写一个从面值大的开始优先使用,依次递减取余,这种方法来处理,但是逻辑没有理太清楚,代码写的非常复杂,最后放弃了。

    还是来看动态规划

    class Solution {
        public int coinChange(int[] coins, int amount) {
            Arrays.sort(coins);
            if ( amount==0 ){
                return 0;
            }
            if  (amount < coins[0] ){
                return -1;
            }
            int[] dp = new int[amount+1];
            Arrays.fill(dp,-1);
            int i = 1;
            while (i <= amount){
                for (int coin : coins) {
                    if (i < coin){
                        break;
                    }
                    if (i == coin){
                        dp[i] = 1;
                        break;
                    }else {
                        if (dp[i-coin] == -1){
                            continue;
                        }
                        if (dp[i] == -1){
                            dp[i] = dp[i-coin]+1;
                        }else {
                            dp[i] = Math.min(dp[i],dp[i-coin]+1);
                        }
                    }
                }
                i++;
            }
            return dp[amount];
        }
    }

    以实际举例来说 [1, 2, 5]的常规面值

    如果需要的面值是0,则0个,这个没有疑问

    如果目标面值是1,因为直接有一个面值为1的,所以结果是F(1) = 1

    如果目标面值是2,因为直接有一个面值是2的硬币,所以结果是F(2) = 1个。但是面值2的情况可以由面值1的值1个加上一枚1元的组合而成,需要两枚硬币。但是这边的两枚大于之前的1,所以丢弃这个结果,当有硬币面值直接相等的时候就可以直接用1枚。

    当面值为3的时候,可以由F(1)加上1枚面值为2的或者F(2)加上1枚面值为1的均为2。当然我们知道面值为3的可以用3枚面值1的硬币组成,这个组合对应为之前求F(2)时候的非最小值情况的两枚面值1的硬币,加上凑到3需要的额外一枚硬币组合而成。

    当面值为4的时候,可以由F(3)加上一个面值1硬币或者F(2)加上一个面值2硬币而来。同样的更多其他的组合都不是最优解了。

    当面值为5的时候,有面值5的硬币,直接F(5) = 1。

    往后递推类似,如果有直接面额的相等的,则直接返1,如果没有,则考虑距离最近的最优解额外加一个硬币的面值的情况。