322. 零钱兑换

动态规划

  1. public int coinChange(int[] coins, int amount) {
  2. // 自底向上的动态规划
  3. if(coins.length == 0){
  4. return -1;
  5. }
  6. // memo[n]的值: 表示的凑成总金额为n所需的最少的硬币个数
  7. int[] memo = new int[amount+1];
  8. // 给memo赋初值,最多的硬币数就是全部使用面值1的硬币进行换
  9. // amount + 1 是不可能达到的换取数量,于是使用其进行填充
  10. Arrays.fill(memo,amount+1);
  11. memo[0] = 0;
  12. for(int i = 1; i <= amount;i++){
  13. for(int j = 0;j < coins.length;j++){
  14. if(i - coins[j] >= 0){
  15. // memo[i]有两种实现的方式,
  16. // 一种是包含当前的coins[i],那么剩余钱就是 i-coins[i],这种操作要兑换的硬币数是 memo[i-coins[j]] + 1
  17. // 另一种就是不包含,要兑换的硬币数是memo[i]
  18. memo[i] = Math.min(memo[i],memo[i-coins[j]] + 1);
  19. }
  20. }
  21. }
  22. return memo[amount] == (amount+1) ? -1 : memo[amount];
  23. }
  24. //作者:sugar666
  25. //链接:https://leetcode-cn.com/problems/coin-change/solution/javadi-gui-ji-yi-hua-sou-suo-dong-tai-gui-hua-by-s/

记忆法

  1. int[] memo;
  2. public int coinChange(int[] coins, int amount) {
  3. if(coins.length == 0){
  4. return -1;
  5. }
  6. memo = new int[amount];
  7. return findWay(coins,amount);
  8. }
  9. // memo[n] 表示钱币n可以被换取的最少的硬币数,不能换取就为-1
  10. // findWay函数的目的是为了找到 amount数量的零钱可以兑换的最少硬币数量,返回其值int
  11. public int findWay(int[] coins,int amount){
  12. if(amount < 0){
  13. return -1;
  14. }
  15. if(amount == 0){
  16. return 0;
  17. }
  18. // 记忆化的处理,memo[n]用赋予了值,就不用继续下面的循环
  19. // 直接的返回memo[n] 的最优值
  20. if(memo[amount-1] != 0){
  21. return memo[amount-1];
  22. }
  23. int min = Integer.MAX_VALUE;
  24. for(int i = 0;i < coins.length;i++){
  25. int res = findWay(coins,amount-coins[i]);
  26. if(res >= 0 && res < min){
  27. min = res + 1; // 加1,是为了加上得到res结果的那个步骤中,兑换的一个硬币...
  28. }
  29. }
  30. memo[amount-1] = (min == Integer.MAX_VALUE ? -1 : min);
  31. return memo[amount-1];
  32. }
  33. 作者:sugar666
  34. 链接:https://leetcode-cn.com/problems/coin-change/solution/javadi-gui-ji-yi-hua-sou-suo-dong-tai-gui-hua-by-s/

递归 超时

  1. int res = Integer.MAX_VALUE;
  2. public int coinChange(int[] coins, int amount) {
  3. if(coins.length == 0){
  4. return -1;
  5. }
  6. findWay(coins,amount,0);
  7. // 如果没有任何一种硬币组合能组成总金额,返回 -1。
  8. if(res == Integer.MAX_VALUE){
  9. return -1;
  10. }
  11. return res;
  12. }
  13. public void findWay(int[] coins,int amount,int count){
  14. if(amount < 0){
  15. return;
  16. }
  17. if(amount == 0){
  18. res = Math.min(res,count);
  19. }
  20. for(int i = 0;i < coins.length;i++){
  21. findWay(coins,amount-coins[i],count+1);
  22. }
  23. }
  24. 作者:sugar666
  25. 链接:https://leetcode-cn.com/problems/coin-change/solution/javadi-gui-ji-yi-hua-sou-suo-dong-tai-gui-hua-by-s/