0
点赞
收藏
分享

微信扫一扫

518. 零钱兑换 II java

零钱兑换 II

问题描述

给定不同面额的硬币和一个总金额,写一个函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

问题分析

这是一个典型的动态规划问题。我们可以使用动态规划来解决这个问题。具体来说,我们可以使用一个一维数组dp来记录目标金额为i时的硬币组合数。数组dp的长度为目标金额加一,初始时所有元素都为零。然后,我们遍历硬币的面额,对于每个面额coin,我们从coin开始遍历到目标金额amount,并更新dp[j]的值。更新的逻辑是,对于每个jdp[j]的值等于dp[j]dp[j-coin]之和,其中dp[j-coin]表示使用硬币coin时的组合数,dp[j]表示不使用硬币coin时的组合数。最终,返回dp[amount]即可。

算法实现

下面是整个算法的流程图:

步骤 动作
1 初始化dp数组,将所有元素设置为零。
2 对于每个硬币面额coin,执行以下步骤:
3 对于icoin到目标金额amount,执行以下步骤:
4 更新dp[i]的值为dp[i] + dp[i-coin]
5 返回dp[amount]的值。

下面是具体的代码实现:

public int change(int amount, int[] coins) {
    // 初始化dp数组
    int[] dp = new int[amount + 1];
    dp[0] = 1;

    // 遍历硬币面额
    for (int coin : coins) {
        // 遍历目标金额
        for (int i = coin; i <= amount; i++) {
            // 更新dp[i]的值
            dp[i] += dp[i - coin];
        }
    }

    // 返回dp[amount]的值
    return dp[amount];
}

代码解析

首先,在算法的开始部分,我们初始化了一个一维数组dp,将所有元素都设置为零。数组的长度为目标金额amount加一,这是因为我们需要考虑目标金额为零的情况。然后,我们将dp[0]的值设置为1,表示当目标金额为零时,存在一种硬币组合方式,即不使用任何硬币。

接下来,我们使用两个嵌套的循环来遍历硬币的面额和目标金额。外层循环遍历硬币面额coin,内层循环从coin开始遍历到目标金额amount,并更新dp[i]的值。更新的逻辑是,我们将dp[i]的值加上dp[i-coin]的值,表示使用硬币coin时的组合数。

最后,我们返回dp[amount]的值,即为目标金额amount的硬币组合数。

总结

通过动态规划算法,我们可以高效地计算出给定金额的硬币组合数。这个算法的时间复杂度为O(amount * n),其中,amount为目标金额,n为硬币的面额个数。通过使用动态规划算法,我们可以避免重复计算,从而提高了算法的效率。

举报

相关推荐

0 条评论