原题链接:
https://leetcode.cn/problems/coin-change/description/
完成情况:
解题思路:
这段代码是一个动态规划的解决方案,用于找零钱问题。函数coinChange
接受两个参数:一个整数数组coins
代表不同面额的硬币,一个整数amount
代表要找零的金额。函数返回最少需要多少枚硬币才能凑出指定的金额,如果无法凑出则返回-1。
首先,初始化一个长度为amount + 1
的整型数组dp
,并将每个元素初始化为amount + 1
,表示最大的找零次数。然后将dp[0]
设为0,表示找零0元需要0枚硬币。
接着,通过两个循环遍历dp
数组和coins
数组,如果当前硬币面额小于等于当前要找零的金额,则更新dp[i]
为dp[i]
和dp[i - coins[j]] + 1
中的较小值。
最后,返回dp[amount]
,如果dp[amount]
大于amount
,则表示无法凑出指定金额,返回-1;否则返回最少需要的硬币数量。
参考代码:
_322零钱兑换_dp
package leetcode板块;
import java.util.Arrays;
import java.util.Map;
public class _322零钱兑换_dp {
/**
*
* @param coins
* @param amount
* @return
*/
public int coinChange(int[] coins, int amount) {
int max = amount + 1;
int dp [] = new int[amount + 1];
Arrays.fill(dp,max);
dp[0] = 0;
for (int i = 1;i<=amount;++i){ // i: 1 --> amount 每个数去寻找
for (int j = 0;j<coins.length;++j){ // j: 遍历coins[]里面的所有数,然后每个数去对应寻找coins[]的最小表示
if (coins[j] <= i){
dp[i] = Math.min(dp[i] ,dp[i - coins[j]] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
}
_322零钱兑换_记忆化递归
package leetcode板块;
public class _322零钱兑换_记忆化递归 {
/**
* 首先需要明确是否明确最小零钱为1,因为1是所有整型数的因数,所以有1的话,一定有解
* @param coins
* @param amount
* @return
*/
public int coinChange(int[] coins, int amount) {
//给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
//从最大的开始dp---记忆化压缩
if (amount < 1) return 0;
int [] curMinCount = new int[amount];
return minCoinChange(coins,amount,curMinCount);
}
/**
*
* @param coins
* @param remindAmount
* @param curMinCount
* @return
*/
private int minCoinChange(int[] coins, int remindAmount, int[] curMinCount) {
if (remindAmount < 0){
return -1;
}
if (remindAmount == 0){
return 0;
}
if (curMinCount[remindAmount - 1] != 0){
return curMinCount[remindAmount - 1];
}
//找到最小值去匹配
int min = Integer.MAX_VALUE;
for (int coin : coins){
int res = minCoinChange(coins,remindAmount - coin ,curMinCount);
if (res >= 0 && res < min){
min = 1 + res;
}
}
curMinCount[remindAmount - 1] = (min == Integer.MAX_VALUE) ? -1 : min;
return curMinCount[remindAmount - 1];
}
}