思路:
跟279.完全平方数方法一致,动态规划dp
代码:
class Solution {
public int coinChange(int[] coins, int amount) {
int n=coins.length;
//要将长度设置为amount+1
int[] dp=new int[amount+1];
//用amount+1的初始化长度来创建dp
//目的是判断是否没有数字符合
Arrays.fill(dp,amount+1);
//当amount==0时,就返回0
dp[0]=0;
for(int i=1;i<=amount;i++){
for(int j=0;j<n;j++){
if(i-coins[j]>=0){
dp[i]=Math.min(dp[i],dp[i-coins[j]]+1);
}
}
}
return dp[amount]>amount?-1:dp[amount];
}
}
分解:
1)要将dp的长度设置为amount+1,多一列防止越界
2)用amount+1的初始化长度来创建dp,目的是判断是否没有数字符合
如果最后dp[amount]还是amount,就返回-1
3)双重循环,此题跟重复数不同的是,重复数是平方,此题是coins数组里的值
状态转移方程:
dp[i]=Math.min(dp[i],dp[i-coins[j]]+1);
复杂度分析:
时间复杂度:O(S*N)S是总金额(amount),N是面额(coins)
空间复杂度:O(S)dp里存了总金额的数量个数