LeetCode题解 22(322,518)零钱兑换,零钱兑换 II <动态规划>

文章目录

  • 零钱兑换(322)
    • 代码解答:
  • 零钱兑换 II(518)
    • 代码解答:

零钱兑换(322)

LeetCode题解 22(322,518)零钱兑换,零钱兑换 II <动态规划>_第1张图片
思路: 动态规划
先确定容器dp[ ]:
dp[j] 表示的就是当amount为 j 时,所需的最少的硬币个数为dp[j];
因此我们将dp数组的里面全初始化为最大值。

        int[] dp = new int[amount+1];
        Arrays.fill(dp,Integer.MAX_VALUE);

初始化dp数组,当amount为0时,所需的最少的硬币个数也是0。

        dp[0] = 0;

因为是完全背包,遍历顺序都可以,这里我们先遍历物品,再遍历背包。
当我们去不断的向背包里面放物品,每次放物品时就检查当前所需的最少硬币数是否为最大的。如果不是就直接走dp方程。
dp方程

dp[j] = Math.min(dp[j-coins[i]]+1,dp[j]);

当前的dp取决于是否还能放入coins[i], dp[j-coins[i]]+1 表示的就是放入coins[i]对应的金币数目+1,dp[j]表示的就是不放入coins[i];

        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-coins[i]]+1,dp[j]);
                }
            }
        }

最后我们只需要判断对应的dp[amount],根据我们前面分析的dp数组的含义也就是amount所需要的最少的金币数。当dp[amount]为最大值时就表示没有任何一种硬币组合能组成总金额,返回 -1。不是就返回dp[amount];

        return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];

代码解答:

class Solution {
    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++){
                if(dp[j-coins[i]] != Integer.MAX_VALUE){
                    dp[j] = Math.min(dp[j-coins[i]]+1,dp[j]);
                }
            }
        }
        return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
    }
}

零钱兑换 II(518)

LeetCode题解 22(322,518)零钱兑换,零钱兑换 II <动态规划>_第2张图片
也是动态规划,不同的时这个求的是组成对应amount的所有方式。也就是组合数。这就要求我们先遍历物品再去遍历背包。
先确定容器dp[ ]:
dp[j] 表示的就是当amount为 j 时,对应的能组成的所有方式。

 int[] dp = new int[amount+1];

初始化,当amount为0时就表示0的组成方式也就是0个,但是在Leetcode的后台测试数据中当amount为0时dp[j] = 1。
LeetCode题解 22(322,518)零钱兑换,零钱兑换 II <动态规划>_第3张图片

         dp[0] = 1;

接着就是遍历,确定dp方程。

         //因为是组合,先遍历物品再遍历背包
         for(int i = 0;i<coins.length;i++){
             for(int j = coins[i];j<=amount;j++){
                 dp[j] += dp[j-coins[i]];
             }
         }

当前的 amount 的方式再加上从背包中是否取出另一种硬币去减去。
接着返回dp[amount]即可。

         return dp[amount];

代码解答:

class Solution {
    public int change(int amount, int[] coins) {
         int[] dp = new int[amount+1];
         dp[0] = 1;
         //因为是组合,先遍历物品再遍历背包
         for(int i = 0;i<coins.length;i++){
             for(int j = coins[i];j<=amount;j++){
                 dp[j] += dp[j-coins[i]];
             }
         }
         return dp[amount];
    }
}

你可能感兴趣的:(Leetcode每日一题,leetcode,动态规划,算法,java)