返回介绍

solution / 0500-0599 / 0518.Coin Change II / README

发布于 2024-06-17 01:03:59 字数 3849 浏览 0 评论 0 收藏 0

518. 零钱兑换 II

English Version

题目描述

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0

假设每一种面额的硬币有无限个。 

题目数据保证结果符合 32 位带符号整数。

 

示例 1:

输入:amount = 5, coins = [1, 2, 5]
输出:4
解释:有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

示例 2:

输入:amount = 3, coins = [2]
输出:0
解释:只用面额 2 的硬币不能凑成总金额 3 。

示例 3:

输入:amount = 10, coins = [10] 
输出:1

 

提示:

  • 1 <= coins.length <= 300
  • 1 <= coins[i] <= 5000
  • coins 中的所有值 互不相同
  • 0 <= amount <= 5000

解法

方法一

class Solution:
  def change(self, amount: int, coins: List[int]) -> int:
    dp = [0] * (amount + 1)
    dp[0] = 1
    for coin in coins:
      for j in range(coin, amount + 1):
        dp[j] += dp[j - coin]
    return dp[-1]
class Solution {
  public int change(int amount, int[] coins) {
    int m = coins.length;
    int[][] dp = new int[m + 1][amount + 1];
    dp[0][0] = 1;
    for (int i = 1; i <= m; ++i) {
      for (int j = 0; j <= amount; ++j) {
        for (int k = 0; k * coins[i - 1] <= j; ++k) {
          dp[i][j] += dp[i - 1][j - coins[i - 1] * k];
        }
      }
    }
    return dp[m][amount];
  }
}
class Solution {
public:
  int change(int amount, vector<int>& coins) {
    vector<int> dp(amount + 1);
    dp[0] = 1;
    for (auto coin : coins) {
      for (int j = coin; j <= amount; ++j) {
        dp[j] += dp[j - coin];
      }
    }
    return dp[amount];
  }
};
func change(amount int, coins []int) int {
  dp := make([]int, amount+1)
  dp[0] = 1
  for _, coin := range coins {
    for j := coin; j <= amount; j++ {
      dp[j] += dp[j-coin]
    }
  }
  return dp[amount]
}
function change(amount: number, coins: number[]): number {
  let dp = new Array(amount + 1).fill(0);
  dp[0] = 1;
  for (let coin of coins) {
    for (let i = coin; i <= amount; ++i) {
      dp[i] += dp[i - coin];
    }
  }
  return dp.pop();
}

方法二

class Solution {
  public int change(int amount, int[] coins) {
    int m = coins.length;
    int[][] dp = new int[m + 1][amount + 1];
    dp[0][0] = 1;
    for (int i = 1; i <= m; ++i) {
      int v = coins[i - 1];
      for (int j = 0; j <= amount; ++j) {
        dp[i][j] = dp[i - 1][j];
        if (j >= v) {
          dp[i][j] += dp[i][j - v];
        }
      }
    }
    return dp[m][amount];
  }
}

方法三

class Solution {
  public int change(int amount, int[] coins) {
    int[] dp = new int[amount + 1];
    dp[0] = 1;
    for (int coin : coins) {
      // 顺序遍历,0-1背包问题是倒序遍历
      for (int j = coin; j <= amount; j++) {
        dp[j] += dp[j - coin];
      }
    }
    return dp[amount];
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文