diff --git a/solution/0300-0399/0322.Coin Change/README.md b/solution/0300-0399/0322.Coin Change/README.md index e01d9fa5d8cab..0a81144f5d53e 100644 --- a/solution/0300-0399/0322.Coin Change/README.md +++ b/solution/0300-0399/0322.Coin Change/README.md @@ -76,12 +76,6 @@ $$ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为硬币的种类数和总金额。 -注意到 $f[i][j]$ 只与 $f[i - 1][j]$ 和 $f[i][j - x]$ 有关,因此我们可以将二维数组优化为一维数组,空间复杂度降为 $O(n)$。 - -相似题目: - -- [279. 完全平方数](https://github.com/doocs/leetcode/blob/main/solution/0200-0299/0279.Perfect%20Squares/README.md) - ```python @@ -237,7 +231,11 @@ var coinChange = function (coins, amount) { -### 方法二 +我们注意到 $f[i][j]$ 只与 $f[i - 1][j]$ 和 $f[i][j - x]$ 有关,因此我们可以将二维数组优化为一维数组,空间复杂度降为 $O(n)$。 + +相似题目: + +- [279. 完全平方数](https://github.com/doocs/leetcode/blob/main/solution/0200-0299/0279.Perfect%20Squares/README.md) diff --git a/solution/0300-0399/0322.Coin Change/README_EN.md b/solution/0300-0399/0322.Coin Change/README_EN.md index ecafeced744f7..ece6328bbcc77 100644 --- a/solution/0300-0399/0322.Coin Change/README_EN.md +++ b/solution/0300-0399/0322.Coin Change/README_EN.md @@ -46,7 +46,33 @@ ## Solutions -### Solution 1 +### Solution 1: Dynamic Programming (Complete Knapsack) + +We define $f[i][j]$ as the minimum number of coins needed to make up the amount $j$ using the first $i$ types of coins. Initially, $f[0][0] = 0$, and the values of other positions are all positive infinity. + +We can enumerate the quantity $k$ of the last coin used, then we have: + +$$ +f[i][j] = \min(f[i - 1][j], f[i - 1][j - x] + 1, \cdots, f[i - 1][j - k \times x] + k) +$$ + +where $x$ represents the face value of the $i$-th type of coin. + +Let $j = j - x$, then we have: + +$$ +f[i][j - x] = \min(f[i - 1][j - x], f[i - 1][j - 2 \times x] + 1, \cdots, f[i - 1][j - k \times x] + k - 1) +$$ + +Substituting the second equation into the first one, we can get the following state transition equation: + +$$ +f[i][j] = \min(f[i - 1][j], f[i][j - x] + 1) +$$ + +The final answer is $f[m][n]$. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are the number of types of coins and the total amount, respectively. @@ -203,7 +229,11 @@ var coinChange = function (coins, amount) { -### Solution 2 +We notice that $f[i][j]$ is only related to $f[i - 1][j]$ and $f[i][j - x]$. Therefore, we can optimize the two-dimensional array into a one-dimensional array, reducing the space complexity to $O(n)$. + +Similar problems: + +- [279. Perfect Squares](https://github.com/doocs/leetcode/blob/main/solution/0200-0299/0279.Perfect%20Squares/README_EN.md) diff --git a/solution/0500-0599/0518.Coin Change II/README.md b/solution/0500-0599/0518.Coin Change II/README.md index 501bfdfe251bf..168a6ec957f37 100644 --- a/solution/0500-0599/0518.Coin Change II/README.md +++ b/solution/0500-0599/0518.Coin Change II/README.md @@ -61,35 +61,65 @@ ## 解法 -### 方法一 +### 方法一:动态规划(完全背包) + +我们定义 $f[i][j]$ 表示使用前 $i$ 种硬币,凑出金额 $j$ 的硬币组合数。初始时 $f[0][0] = 1$,其余位置的值均为 $0$。 + +我们可以枚举使用的最后一枚硬币的数量 $k$,那么有式子一: + +$$ +f[i][j] = f[i - 1][j] + f[i - 1][j - x] + f[i - 1][j - 2 \times x] + \cdots + f[i - 1][j - k \times x] +$$ + +其中 $x$ 表示第 $i$ 种硬币的面值。 + +不妨令 $j = j - x$,那么有式子二: + +$$ +f[i][j - x] = f[i - 1][j - x] + f[i - 1][j - 2 \times x] + \cdots + f[i - 1][j - k \times x] +$$ + +将式子二代入式子一,得到: + +$$ +f[i][j] = f[i - 1][j] + f[i][j - x] +$$ + +最终的答案为 $f[m][n]$,其中 $m$ 和 $n$ 分别表示硬币的种类数和总金额。 + +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为硬币的种类数和总金额。 ```python 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] + m, n = len(coins), amount + f = [[0] * (n + 1) for _ in range(m + 1)] + f[0][0] = 1 + for i, x in enumerate(coins, 1): + for j in range(n + 1): + f[i][j] = f[i - 1][j] + if j >= x: + f[i][j] += f[i][j - x] + return f[m][n] ``` ```java 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; + int m = coins.length, n = amount; + int[][] f = new int[m + 1][n + 1]; + f[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]; + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; } } } - return dp[m][amount]; + return f[m][n]; } } ``` @@ -98,89 +128,136 @@ class Solution { class Solution { public: int change(int amount, vector& coins) { - vector dp(amount + 1); - dp[0] = 1; - for (auto coin : coins) { - for (int j = coin; j <= amount; ++j) { - dp[j] += dp[j - coin]; + int m = coins.size(), n = amount; + int f[m + 1][n + 1]; + memset(f, 0, sizeof(f)); + f[0][0] = 1; + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; + } } } - return dp[amount]; + return f[m][n]; } }; ``` ```go 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] + m, n := len(coins), amount + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + f[0][0] = 1 + for i := 1; i <= m; i++ { + for j := 0; j <= n; j++ { + f[i][j] = f[i-1][j] + if j >= coins[i-1] { + f[i][j] += f[i][j-coins[i-1]] + } } } - return dp[amount] + return f[m][n] } ``` ```ts 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]; + const [m, n] = [coins.length, amount]; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + f[0][0] = 1; + for (let i = 1; i <= m; ++i) { + for (let j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; + } } } - return dp.pop(); + return f[m][n]; } ``` -### 方法二 +我们注意到 $f[i][j]$ 只与 $f[i - 1][j]$ 和 $f[i][j - x]$ 有关,因此我们可以将二维数组优化为一维数组,空间复杂度降为 $O(n)$。 +```python +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + n = amount + f = [1] + [0] * n + for x in coins: + for j in range(x, n + 1): + f[j] += f[j - x] + return f[n] +``` + ```java 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]; - } + int n = amount; + int[] f = new int[n + 1]; + f[0] = 1; + for (int x : coins) { + for (int j = x; j <= n; ++j) { + f[j] += f[j - x]; } } - return dp[m][amount]; + return f[n]; } } ``` - - -### 方法三 - - - -```java +```cpp 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]; +public: + int change(int amount, vector& coins) { + int n = amount; + int f[n + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + for (int x : coins) { + for (int j = x; j <= n; ++j) { + f[j] += f[j - x]; } } - return dp[amount]; + return f[n]; + } +}; +``` + +```go +func change(amount int, coins []int) int { + n := amount + f := make([]int, n+1) + f[0] = 1 + for _, x := range coins { + for j := x; j <= n; j++ { + f[j] += f[j-x] + } + } + return f[n] +} +``` + +```ts +function change(amount: number, coins: number[]): number { + const n = amount; + const f: number[] = Array(n + 1).fill(0); + f[0] = 1; + for (const x of coins) { + for (let j = x; j <= n; ++j) { + f[j] += f[j - x]; + } } + return f[n]; } ``` diff --git a/solution/0500-0599/0518.Coin Change II/README_EN.md b/solution/0500-0599/0518.Coin Change II/README_EN.md index 5ef47f185cc7d..8a77e3cb6ec4c 100644 --- a/solution/0500-0599/0518.Coin Change II/README_EN.md +++ b/solution/0500-0599/0518.Coin Change II/README_EN.md @@ -54,35 +54,65 @@ ## Solutions -### Solution 1 +### Solution 1: Dynamic Programming (Complete Knapsack) + +We define $f[i][j]$ as the number of coin combinations to make up the amount $j$ using the first $i$ types of coins. Initially, $f[0][0] = 1$, and the values of other positions are all $0$. + +We can enumerate the quantity $k$ of the last coin used, then we have equation one: + +$$ +f[i][j] = f[i - 1][j] + f[i - 1][j - x] + f[i - 1][j - 2 \times x] + \cdots + f[i - 1][j - k \times x] +$$ + +where $x$ represents the face value of the $i$-th type of coin. + +Let $j = j - x$, then we have equation two: + +$$ +f[i][j - x] = f[i - 1][j - x] + f[i - 1][j - 2 \times x] + \cdots + f[i - 1][j - k \times x] +$$ + +Substituting equation two into equation one, we can get the following state transition equation: + +$$ +f[i][j] = f[i - 1][j] + f[i][j - x] +$$ + +The final answer is $f[m][n]$. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are the number of types of coins and the total amount, respectively. ```python 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] + m, n = len(coins), amount + f = [[0] * (n + 1) for _ in range(m + 1)] + f[0][0] = 1 + for i, x in enumerate(coins, 1): + for j in range(n + 1): + f[i][j] = f[i - 1][j] + if j >= x: + f[i][j] += f[i][j - x] + return f[m][n] ``` ```java 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; + int m = coins.length, n = amount; + int[][] f = new int[m + 1][n + 1]; + f[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]; + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; } } } - return dp[m][amount]; + return f[m][n]; } } ``` @@ -91,89 +121,136 @@ class Solution { class Solution { public: int change(int amount, vector& coins) { - vector dp(amount + 1); - dp[0] = 1; - for (auto coin : coins) { - for (int j = coin; j <= amount; ++j) { - dp[j] += dp[j - coin]; + int m = coins.size(), n = amount; + int f[m + 1][n + 1]; + memset(f, 0, sizeof(f)); + f[0][0] = 1; + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; + } } } - return dp[amount]; + return f[m][n]; } }; ``` ```go 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] + m, n := len(coins), amount + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + f[0][0] = 1 + for i := 1; i <= m; i++ { + for j := 0; j <= n; j++ { + f[i][j] = f[i-1][j] + if j >= coins[i-1] { + f[i][j] += f[i][j-coins[i-1]] + } } } - return dp[amount] + return f[m][n] } ``` ```ts 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]; + const [m, n] = [coins.length, amount]; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + f[0][0] = 1; + for (let i = 1; i <= m; ++i) { + for (let j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; + } } } - return dp.pop(); + return f[m][n]; } ``` -### Solution 2 +We notice that $f[i][j]$ is only related to $f[i - 1][j]$ and $f[i][j - x]$. Therefore, we can optimize the two-dimensional array into a one-dimensional array, reducing the space complexity to $O(n)$. +```python +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + n = amount + f = [1] + [0] * n + for x in coins: + for j in range(x, n + 1): + f[j] += f[j - x] + return f[n] +``` + ```java 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]; - } + int n = amount; + int[] f = new int[n + 1]; + f[0] = 1; + for (int x : coins) { + for (int j = x; j <= n; ++j) { + f[j] += f[j - x]; } } - return dp[m][amount]; + return f[n]; } } ``` - - -### Solution 3 - - - -```java +```cpp 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]; +public: + int change(int amount, vector& coins) { + int n = amount; + int f[n + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + for (int x : coins) { + for (int j = x; j <= n; ++j) { + f[j] += f[j - x]; } } - return dp[amount]; + return f[n]; + } +}; +``` + +```go +func change(amount int, coins []int) int { + n := amount + f := make([]int, n+1) + f[0] = 1 + for _, x := range coins { + for j := x; j <= n; j++ { + f[j] += f[j-x] + } + } + return f[n] +} +``` + +```ts +function change(amount: number, coins: number[]): number { + const n = amount; + const f: number[] = Array(n + 1).fill(0); + f[0] = 1; + for (const x of coins) { + for (let j = x; j <= n; ++j) { + f[j] += f[j - x]; + } } + return f[n]; } ``` diff --git a/solution/0500-0599/0518.Coin Change II/Solution.cpp b/solution/0500-0599/0518.Coin Change II/Solution.cpp index 19fadbc5943cb..89eb2834b47fa 100644 --- a/solution/0500-0599/0518.Coin Change II/Solution.cpp +++ b/solution/0500-0599/0518.Coin Change II/Solution.cpp @@ -1,13 +1,18 @@ class Solution { public: int change(int amount, vector& coins) { - vector dp(amount + 1); - dp[0] = 1; - for (auto coin : coins) { - for (int j = coin; j <= amount; ++j) { - dp[j] += dp[j - coin]; + int m = coins.size(), n = amount; + int f[m + 1][n + 1]; + memset(f, 0, sizeof(f)); + f[0][0] = 1; + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; + } } } - return dp[amount]; + return f[m][n]; } }; \ No newline at end of file diff --git a/solution/0500-0599/0518.Coin Change II/Solution.go b/solution/0500-0599/0518.Coin Change II/Solution.go index 53c70c31206c0..a5811c11deca1 100644 --- a/solution/0500-0599/0518.Coin Change II/Solution.go +++ b/solution/0500-0599/0518.Coin Change II/Solution.go @@ -1,10 +1,17 @@ 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] + m, n := len(coins), amount + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + f[0][0] = 1 + for i := 1; i <= m; i++ { + for j := 0; j <= n; j++ { + f[i][j] = f[i-1][j] + if j >= coins[i-1] { + f[i][j] += f[i][j-coins[i-1]] + } } } - return dp[amount] + return f[m][n] } \ No newline at end of file diff --git a/solution/0500-0599/0518.Coin Change II/Solution.java b/solution/0500-0599/0518.Coin Change II/Solution.java index 490e102363b11..d840dcf9b2e66 100644 --- a/solution/0500-0599/0518.Coin Change II/Solution.java +++ b/solution/0500-0599/0518.Coin Change II/Solution.java @@ -1,15 +1,16 @@ 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; + int m = coins.length, n = amount; + int[][] f = new int[m + 1][n + 1]; + f[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]; + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; } } } - return dp[m][amount]; + return f[m][n]; } } \ No newline at end of file diff --git a/solution/0500-0599/0518.Coin Change II/Solution.py b/solution/0500-0599/0518.Coin Change II/Solution.py index e2146982fb3f9..862f2e4217541 100644 --- a/solution/0500-0599/0518.Coin Change II/Solution.py +++ b/solution/0500-0599/0518.Coin Change II/Solution.py @@ -1,8 +1,11 @@ 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] + m, n = len(coins), amount + f = [[0] * (n + 1) for _ in range(m + 1)] + f[0][0] = 1 + for i, x in enumerate(coins, 1): + for j in range(n + 1): + f[i][j] = f[i - 1][j] + if j >= x: + f[i][j] += f[i][j - x] + return f[m][n] diff --git a/solution/0500-0599/0518.Coin Change II/Solution.ts b/solution/0500-0599/0518.Coin Change II/Solution.ts index 2d2e9475ed06b..f72de12470256 100644 --- a/solution/0500-0599/0518.Coin Change II/Solution.ts +++ b/solution/0500-0599/0518.Coin Change II/Solution.ts @@ -1,10 +1,14 @@ 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]; + const [m, n] = [coins.length, amount]; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + f[0][0] = 1; + for (let i = 1; i <= m; ++i) { + for (let j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j]; + if (j >= coins[i - 1]) { + f[i][j] += f[i][j - coins[i - 1]]; + } } } - return dp.pop(); + return f[m][n]; } diff --git a/solution/0500-0599/0518.Coin Change II/Solution2.cpp b/solution/0500-0599/0518.Coin Change II/Solution2.cpp new file mode 100644 index 0000000000000..7be937cd71a50 --- /dev/null +++ b/solution/0500-0599/0518.Coin Change II/Solution2.cpp @@ -0,0 +1,15 @@ +class Solution { +public: + int change(int amount, vector& coins) { + int n = amount; + int f[n + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + for (int x : coins) { + for (int j = x; j <= n; ++j) { + f[j] += f[j - x]; + } + } + return f[n]; + } +}; \ No newline at end of file diff --git a/solution/0500-0599/0518.Coin Change II/Solution2.go b/solution/0500-0599/0518.Coin Change II/Solution2.go new file mode 100644 index 0000000000000..ae0dd9d6ec68a --- /dev/null +++ b/solution/0500-0599/0518.Coin Change II/Solution2.go @@ -0,0 +1,11 @@ +func change(amount int, coins []int) int { + n := amount + f := make([]int, n+1) + f[0] = 1 + for _, x := range coins { + for j := x; j <= n; j++ { + f[j] += f[j-x] + } + } + return f[n] +} \ No newline at end of file diff --git a/solution/0500-0599/0518.Coin Change II/Solution2.java b/solution/0500-0599/0518.Coin Change II/Solution2.java index 84165a13c0907..93fbd145071ce 100644 --- a/solution/0500-0599/0518.Coin Change II/Solution2.java +++ b/solution/0500-0599/0518.Coin Change II/Solution2.java @@ -1,17 +1,13 @@ 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]; - } + int n = amount; + int[] f = new int[n + 1]; + f[0] = 1; + for (int x : coins) { + for (int j = x; j <= n; ++j) { + f[j] += f[j - x]; } } - return dp[m][amount]; + return f[n]; } } \ No newline at end of file diff --git a/solution/0500-0599/0518.Coin Change II/Solution2.py b/solution/0500-0599/0518.Coin Change II/Solution2.py new file mode 100644 index 0000000000000..a253512b4b7da --- /dev/null +++ b/solution/0500-0599/0518.Coin Change II/Solution2.py @@ -0,0 +1,8 @@ +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + n = amount + f = [1] + [0] * n + for x in coins: + for j in range(x, n + 1): + f[j] += f[j - x] + return f[n] diff --git a/solution/0500-0599/0518.Coin Change II/Solution2.ts b/solution/0500-0599/0518.Coin Change II/Solution2.ts new file mode 100644 index 0000000000000..51bb0211ce48a --- /dev/null +++ b/solution/0500-0599/0518.Coin Change II/Solution2.ts @@ -0,0 +1,11 @@ +function change(amount: number, coins: number[]): number { + const n = amount; + const f: number[] = Array(n + 1).fill(0); + f[0] = 1; + for (const x of coins) { + for (let j = x; j <= n; ++j) { + f[j] += f[j - x]; + } + } + return f[n]; +} diff --git a/solution/0500-0599/0518.Coin Change II/Solution3.java b/solution/0500-0599/0518.Coin Change II/Solution3.java deleted file mode 100644 index 13126a286f269..0000000000000 --- a/solution/0500-0599/0518.Coin Change II/Solution3.java +++ /dev/null @@ -1,13 +0,0 @@ -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]; - } -} \ No newline at end of file