N刷犯得一个错误:将i>=coins[j]放在了for循环判断条件中,导致解答错误。为什么在《完全平方数》就可以呢,因为那里的平方数是有序递增的,而这里的硬币大小不是有序的。
题目
https://leetcode-cn.com/problems/coin-change/
类似题目:279 完全平方数
方法一:自底向上的动态规划
代码
class Solution {
/*
自底向上的动态规划
*/
public int coinChange(int[] coins, int amount) {
if(coins.length==0) return -1;
int[] memo=new int[amount+1];
Arrays.fill(memo,amount+1);//初始化为一个不可能到达的数量amount+1。设置为Integer.MAX_VALUE会出错
memo[0]=0;
for(int i=1;i<=amount;i++){
for(int j=0;j<coins.length;j++){
if(i>=coins[j]){
memo[i]=Math.min(memo[i],memo[i-coins[j]]+1);
//memo[i]的两种情况:包含coins[j],不包含conis[j]
}
}
}
if(memo[amount]==amount+1)//没结果
return -1;
else
return memo[amount];
}
}
复杂度
coins长度为m,amount为n
时间复杂度O(mn):对1…amount取值,需要枚举coins。
空间复杂度O(n):dp数组占用的空间
结果
方法二 递归(会超时)
class Solution {
int res=Integer.MAX_VALUE;
public int coinChange(int[] coins, int amount) {
find(coins,amount,0);
return res==Integer.MAX_VALUE?-1:res;
}
public void find(int[] coins,int amount,int count){
if(amount<0){
return;
}
if(amount==0){
res=Math.min(res,count);
}
for(int coin:coins){
find(coins,amount-coin,count+1);
}
}
}