力扣322. 零钱兑换 Java动态规划

简介: 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -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] <= 231 - 1

0 <= amount <= 104


二、思路讲解



以示例1为例,我们设dp[i]为目标面额i的最小钱币数,那么我们所求的就是dp[11]。假如我们知道dp[10],那么再加一个金币是dp[11]了;同理,我们如果知道dp[6],那么再加一个面额为5的金币也是dp[11]了;我们如果知道dp[9],再加一个面额为2的金币也是dp[11]了。

d9d8a17b45a440528dbe830a4a68a0ea.png


所以,dp[11] 实际上就是dp[10]+1,或者dp[9]+1,或者dp[6]+1,具体取哪个值呢?就看哪个值小,因为我们要求最小金币数。故:


min {dp[i-可能面额1], dp[i-可能面额2] , dp[i-可能面额3] ……} +1         i > 0


dp[i] =      0        i = 0


               -1       i < 0


2738454153b54edba0416cd63c93a880.png


三、Java代码实现



class Solution {
    public int coinChange(int[] coins, int amount) {
        int []dp = new int[amount+1];
        //初始化为amount+1, 便于后面min比较
        for(int i=1; i<amount+1; i++) {
            dp[i] = amount+1;
        }
        dp[0] = 0;
        //外层循环枚举所有可能的面值
        for(int i=0; i<amount+1; i++) {
            //内层循环求出该面值下所有可能选择的最小值
            for(int coin : coins) {
                //过滤掉不可能的情况
                if(i<coin) {
                    continue;
                }
                dp[i] = Math.min(dp[i], dp[i-coin]+1);
            }
        }
        return (dp[amount]==(amount+1)) ? (-1) : dp[amount];
    }
}


参考:动态规划套路详解

相关文章
|
4月前
|
Python
【Leetcode刷题Python】518. 零钱兑换 II
解决LeetCode上518题“零钱兑换 II”的Python代码示例,采用动态规划方法计算构成给定总金额的不同硬币组合数。
35 2
|
2月前
|
算法 Java
LeetCode(一)Java
LeetCode(一)Java
|
4月前
|
Python
【Leetcode刷题Python】322. 零钱兑换
使用动态规划解决LeetCode上322题“零钱兑换”的Python代码示例,目的是计算构成给定金额所需的最少硬币数量。
39 2
【Leetcode刷题Python】322. 零钱兑换
|
4月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
55 6
|
4月前
|
存储 算法 Java
LeetCode经典算法题:打家劫舍java详解
LeetCode经典算法题:打家劫舍java详解
72 2
|
4月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
52 1
|
4月前
|
存储 算法 Java
LeetCode经典算法题:预测赢家+香槟塔java解法
LeetCode经典算法题:预测赢家+香槟塔java解法
64 1
|
4月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
82 0
|
4月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
56 0
|
4月前
|
存储 算法 Java
LeetCode初级算法题:两数之和+斐波拉契数列多种java解法
LeetCode初级算法题:两数之和+斐波拉契数列多种java解法
44 0