题目描述
算法思想
举例说明算法的思想,假设现在有数组[1,2,3],请从数组中找到最少的硬币个数凑成纸币6。
次数 | dp[0] | dp[1] | dp[2] | dp[3] | dp[4] | dp[5] | dp[6] |
---|---|---|---|---|---|---|---|
第一次 | 0 | 1(dp[0]+1) | 2(dp[1]+1) | 3(dp[2]+1) | 4(dp[3]+1) | 5(dp[4]+1) | 6(dp[5]+1) |
第二次 | 0 | 1 | 1(dp[0]+1) | 2(dp[1]+1) | 2(dp[2]+1) | 3(dp[3]+1) | 3(dp[4]+1) |
第三次 | 0 | 1 | 1 | 1(dp[0]+1) | 2(dp[1]+1) | 2(dp[2]+1) | 2(dp[3]+1) |
共两层遍历,第一层遍历是从使用数组中[0,0]的数组的值,第二层,来找到所有[0,6]这些纸币需要的[0,0]中的硬币的个数的最小数。
第二次就是第一层使用数组中[0,1]的数组的值,第二层,来找到所有[0,6]这些纸币需要的[0,1]中的硬币的个数的最小数。
第三次就是第一层循环使用数组中[0,2]的数组的值,第二层,来找到所有[0,6]中这些纸币需要的[0,2]中的一笔的个数的最小数。
简言之,就是利用之前的结果,并且再加上一个数字后,看看使用这个数字后,是否能够使使用的硬币的个数达到最小。
代码实现
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
Arrays.fill(dp, 1, amount+1, Integer.MAX_VALUE);
for(int i = 0; i < coins.length; i++){
for(int j = coins[i]; j <= amount; j++){
if(dp[j - coins[i]] != Integer.MAX_VALUE){
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
}
if(dp[amount] != Integer.MAX_VALUE){
return dp[amount];
}
return -1;
}
}