Skip to content

Commit 72aa82a

Browse files
committed
feat: add solutions to lc problem: No.0322
No.0322.Coin Change
1 parent c0ffc5e commit 72aa82a

File tree

5 files changed

+98
-56
lines changed

5 files changed

+98
-56
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
- [目标和](/solution/0400-0499/0494.Target%20Sum/README.md) - 0-1 背包问题
8181
- [分割等和子集](/solution/0400-0499/0416.Partition%20Equal%20Subset%20Sum/README.md) - 0-1 背包问题
8282
- [最后一块石头的重量 II](/solution/1000-1099/1049.Last%20Stone%20Weight%20II/README.md) - 0-1 背包问题
83+
- [零钱兑换](/solution/0300-0399/0322.Coin%20Change/README.md) - 完全背包问题
8384
<!-- 背包问题、状态机模型、状压DP、区间DP、树形DP、数位DP 待补充 -->
8485

8586
### 4. 高级数据结构

README_EN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Complete solutions to [LeetCode](https://leetcode.com/problemset/all/), [LCOF](h
7777
- [Target Sum](/solution/0400-0499/0494.Target%20Sum/README_EN.md) - 0-1 Knapsack problem
7878
- [Partition Equal Subset Sum](/solution/0400-0499/0416.Partition%20Equal%20Subset%20Sum/README_EN.md) - 0-1 Knapsack problem
7979
- [Last Stone Weight II](/solution/1000-1099/1049.Last%20Stone%20Weight%20II/README_EN.md) - 0-1 Knapsack problem
80+
- [Coin Change](/solution/0300-0399/0322.Coin%20Change/README_EN.md) -Unbounded Knapsack problem
8081

8182
### 4. Advanced Data Structures
8283

solution/0300-0399/0322.Coin Change/README.md

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,45 @@
4848

4949
<!-- 这里可写通用的实现逻辑 -->
5050

51-
动态规划
51+
**方法一:动态规划**
5252

5353
类似完全背包的思路,硬币数量不限,求凑成总金额所需的最少的硬币个数。
5454

55+
定义 `dp[i][j]` 表示从前 i 种硬币选出总金额为 j 所需的最少硬币数。
56+
57+
由于:
58+
59+
- `dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - v] + 1, dp[i - 1][j - 2v] + 2, ... , dp[i - 1][j - kv] + k)`
60+
- `dp[i][j - v] = min( dp[i - 1][j - v], dp[i - 1][j - 2v] + 1, ... , dp[i - 1][j - kv] + k - 1)`
61+
62+
因此 `dp[i][j] = min(dp[i - 1][j], dp[i][j - v] + 1)`
63+
64+
时间复杂度 `O(m*amount)`,其中 m 表示 coins 长度。
65+
5566
<!-- tabs:start -->
5667

5768
### **Python3**
5869

5970
<!-- 这里可写当前语言的特殊实现逻辑 -->
6071

72+
动态规划——完全背包问题朴素做法:
73+
74+
```python
75+
class Solution:
76+
def coinChange(self, coins: List[int], amount: int) -> int:
77+
m, n = len(coins), amount
78+
dp = [[n + 1] * (n + 1) for _ in range(m + 1)]
79+
dp[0][0] = 0
80+
for i in range(1, m + 1):
81+
for j in range(n + 1):
82+
dp[i][j] = dp[i - 1][j]
83+
if j >= coins[i - 1]:
84+
dp[i][j] = min(dp[i][j], dp[i][j - coins[i - 1]] + 1)
85+
return -1 if dp[-1][-1] > n else dp[-1][-1]
86+
```
87+
88+
动态规划——完全背包问题空间优化:
89+
6190
```python
6291
class Solution:
6392
def coinChange(self, coins: List[int], amount: int) -> int:
@@ -73,37 +102,6 @@ class Solution:
73102

74103
<!-- 这里可写当前语言的特殊实现逻辑 -->
75104

76-
```java
77-
class Solution {
78-
public int coinChange(int[] coins, int amount) {
79-
int m = coins.length;
80-
int[][] dp = new int[m + 1][amount + 1];
81-
for (int i = 0; i <= m; ++i) {
82-
Arrays.fill(dp[i], amount + 1);
83-
}
84-
dp[0][0] = 0;
85-
for (int i = 1; i <= m; ++i) {
86-
int v = coins[i - 1];
87-
for (int j = 0; j <= amount; ++j) {
88-
for (int k = 0; k * v <= j; ++k) {
89-
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - k * v] + k);
90-
}
91-
}
92-
}
93-
return dp[m][amount] > amount ? - 1 : dp[m][amount];
94-
}
95-
}
96-
```
97-
98-
下面对 k 这层循环进行优化:
99-
100-
由于:
101-
102-
- `dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - v] + 1, dp[i - 1][j - 2v] + 2, ... , dp[i - 1][j - kv] + k)`
103-
- `dp[i][j - v] = min( dp[i - 1][j - v], dp[i - 1][j - 2v] + 1, ... , dp[i - 1][j - kv] + k - 1)`
104-
105-
因此 `dp[i][j] = min(dp[i - 1][j], dp[i][j - v] + 1)`
106-
107105
```java
108106
class Solution {
109107
public int coinChange(int[] coins, int amount) {
@@ -127,8 +125,6 @@ class Solution {
127125
}
128126
```
129127

130-
空间优化:
131-
132128
```java
133129
class Solution {
134130
public int coinChange(int[] coins, int amount) {
@@ -208,4 +204,25 @@ func min(a, b int) int {
208204
}
209205
```
210206

207+
### **TypeScript**
208+
209+
```ts
210+
function coinChange(coins: number[], amount: number): number {
211+
let dp = new Array(amount + 1).fill(amount + 1);
212+
dp[0] = 0;
213+
for (const coin of coins) {
214+
for (let j = coin; j <= amount; ++j) {
215+
dp[j] = Math.min(dp[j], dp[j - coin] + 1);
216+
}
217+
}
218+
return dp[amount] > amount ? -1 : dp[amount];
219+
}
220+
```
221+
222+
### **....**
223+
224+
```
225+
226+
```
227+
211228
<!-- tabs:end -->

solution/0300-0399/0322.Coin Change/README_EN.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ Similar to the idea of ​​a complete backpack, there is no limit to the numbe
5252

5353
### **Python3**
5454

55+
```python
56+
class Solution:
57+
def coinChange(self, coins: List[int], amount: int) -> int:
58+
m, n = len(coins), amount
59+
dp = [[n + 1] * (n + 1) for _ in range(m + 1)]
60+
dp[0][0] = 0
61+
for i in range(1, m + 1):
62+
for j in range(n + 1):
63+
dp[i][j] = dp[i - 1][j]
64+
if j >= coins[i - 1]:
65+
dp[i][j] = min(dp[i][j], dp[i][j - coins[i - 1]] + 1)
66+
return -1 if dp[-1][-1] > n else dp[-1][-1]
67+
```
68+
5569
```python
5670
class Solution:
5771
def coinChange(self, coins: List[int], amount: int) -> int:
@@ -65,28 +79,6 @@ class Solution:
6579

6680
### **Java**
6781

68-
```java
69-
class Solution {
70-
public int coinChange(int[] coins, int amount) {
71-
int m = coins.length;
72-
int[][] dp = new int[m + 1][amount + 1];
73-
for (int i = 0; i <= m; ++i) {
74-
Arrays.fill(dp[i], amount + 1);
75-
}
76-
dp[0][0] = 0;
77-
for (int i = 1; i <= m; ++i) {
78-
int v = coins[i - 1];
79-
for (int j = 0; j <= amount; ++j) {
80-
for (int k = 0; k * v <= j; ++k) {
81-
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - k * v] + k);
82-
}
83-
}
84-
}
85-
return dp[m][amount] > amount ? - 1 : dp[m][amount];
86-
}
87-
}
88-
```
89-
9082
```java
9183
class Solution {
9284
public int coinChange(int[] coins, int amount) {
@@ -189,4 +181,25 @@ func min(a, b int) int {
189181
}
190182
```
191183

184+
### **TypeScript**
185+
186+
```ts
187+
function coinChange(coins: number[], amount: number): number {
188+
let dp = new Array(amount + 1).fill(amount + 1);
189+
dp[0] = 0;
190+
for (const coin of coins) {
191+
for (let j = coin; j <= amount; ++j) {
192+
dp[j] = Math.min(dp[j], dp[j - coin] + 1);
193+
}
194+
}
195+
return dp[amount] > amount ? -1 : dp[amount];
196+
}
197+
```
198+
199+
### **....**
200+
201+
```
202+
203+
```
204+
192205
<!-- tabs:end -->
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function coinChange(coins: number[], amount: number): number {
2+
let dp = new Array(amount + 1).fill(amount + 1);
3+
dp[0] = 0;
4+
for (const coin of coins) {
5+
for (let j = coin; j <= amount; ++j) {
6+
dp[j] = Math.min(dp[j], dp[j - coin] + 1);
7+
}
8+
}
9+
return dp[amount] > amount ? -1 : dp[amount];
10+
}

0 commit comments

Comments
 (0)