题目描述:
You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1
.
Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3
Output: -1
思路:(实质是一个完全背包问题)
思路同:https://blog.csdn.net/orangefly0214/article/details/91352014找零的另一个版本
根据上图,问题可以转化为递归或者迭代去求解。
问题等价于一个完全背包问题,完全背包问题的求解方法如下:
我们用j表示需要找零的总money,则dp[j]就等于
使用第i中硬币后剩下的money需要找零的求解数+1(“1”表示使用第i中硬币这一种解法) 和
不使用第i中硬币时的money需要找零的求解数,两者之间的较小的那个值。
详细可参加这个视频,讲的太好了
https://www.youtube.com/watch?v=jgiZlGzXMBw
实现:
使用dp将递归这种top-down的复杂运算转化为bottom-up来简化运算。这样在求解一个大问题的时候,它的子问题的最优解我们已经存储在了dp数组中,避免了重复计算。
import java.util.Arrays;
//leetcode 322
public class coinChangeDemo {
//问题是一个完全背包问题
public int coinChange(int[] coins, int amount) {
int[] dp=new int[amount+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0]=0;
for (int i = 0; i < coins.length; i++) {
for (int j =coins[i]; j <=amount; j++) {//j表示需要找零的零钱数
// j-coins[i];使用了第i种硬币,剩余需要找零的数目变为j-coins[i]
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 -1;
}
return dp[amount];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
coinChangeDemo cd=new coinChangeDemo();
int[] coins={2};
System.out.println(cd.coinChange(coins, 3));
}
}