/**
* 322. 零钱兑换
* @author wsq
* @date 2020/10/13
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3
输出:-1
链接:https://leetcode-cn.com/problems/coin-change
*/
package com.wsq.dp;
public class CoinChange {
/**
* 动态规划
* 1.确定最后一步(金额amount兑换硬币的最少个数)
* 2.子问题:到达金额amount有几种情况,(比如:从金币额度2、5等到达amount)
* 3.定义转移方程, 比如f[i] = Math.min(f[i - 2], f[i - 5]) + 1
* 4.初始值以及边界情况
* 5.计算状态矩阵的顺序
* @param coins
* @param amount
* @return
*/
public int coinChange(int[] coins, int amount) {
// 开数组,明确有多少中情况需要存储
int[] dp = new int[amount + 1];
// 获取硬币的种类数
int n = coins.length;
// 初始条件 金额为0时 兑换的硬币数为0
dp[0] = 0;
// 从小到大求出每一个状态的值
for(int i = 1; i < amount + 1; i++){
// 由于是要求最小的 硬币兑换数, 因此在未求出之前, 每一个状态值都初始化为Integer.MAX_VALUE
dp[i] = Integer.MAX_VALUE;
for(int j = 0; j < n; j++){
// 考虑dp[i - coins[j]] != Integer.MAX_VALUE是因为可能存在部分金额无法兑换成功
if(i >= coins[j] && dp[i - coins[j]] != Integer.MAX_VALUE){
dp[i] = Math.min(1 + dp[i - coins[j]], dp[i]);
}
}
}
if(dp[amount] == Integer.MAX_VALUE){
dp[amount] = -1;
}
return dp[amount];
}
public static void main(String[] args) {
int[] coins = {1, 2, 5};
int amount = 10;
CoinChange cc = new CoinChange();
int ans = cc.coinChange(coins, amount);
System.out.println(ans);
}
}
322. 零钱兑换(动态规划)
最新推荐文章于 2024-04-09 20:29:57 发布