Skip to content

Commit 77b92a8

Browse files
imp2002siriak
andauthored
Add implementation of the coin change problem (TheAlgorithms#206)
* Add coin change source code * Update DIRECTORY.md * Add a link to README.md Co-authored-by: Andrii Siriak <siryaka@gmail.com>
1 parent 7ec7a2b commit 77b92a8

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* [Fibonacci](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/fibonacci.rs)
1919
* [Knapsack](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/knapsack.rs)
2020
* [Longest Common Subsequence](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/longest_common_subsequence.rs)
21+
* [Coin Change](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/coin_change.rs)
2122
* [Mod](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/mod.rs)
2223
* General
2324
* [Convex Hull](https://github.com/TheAlgorithms/Rust/blob/master/src/general/convex_hull.rs)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/// Coin change via Dynamic Programming
2+
3+
/// coin_change(coins, amount) returns the fewest number of coins that need to make up that amount.
4+
/// If that amount of money cannot be made up by any combination of the coins, return `None`.
5+
///
6+
/// Arguments:
7+
/// * `coins` - coins of different denominations
8+
/// * `amount` - a total amount of money be made up.
9+
/// Complexity
10+
/// - time complexity: O(amount * coins.length),
11+
/// - space complexity: O(amount),
12+
pub fn coin_change(coins: &[usize], amount: usize) -> Option<usize> {
13+
let mut dp = vec![std::usize::MAX; amount + 1];
14+
dp[0] = 0;
15+
16+
// Assume dp[i] is the fewest number of coins making up amount i,
17+
// then for every coin in coins, dp[i] = min(dp[i - coin] + 1).
18+
for i in 0..=amount {
19+
for j in 0..coins.len() {
20+
if i >= coins[j] && dp[i - coins[j]] != std::usize::MAX {
21+
dp[i] = dp[i].min(dp[i - coins[j]] + 1);
22+
}
23+
}
24+
}
25+
26+
match dp[amount] {
27+
std::usize::MAX => None,
28+
_ => Some(dp[amount]),
29+
}
30+
}
31+
32+
#[cfg(test)]
33+
mod tests {
34+
use super::*;
35+
36+
#[test]
37+
fn basic() {
38+
// 11 = 5 * 2 + 1 * 1
39+
let coins = vec![1, 2, 5];
40+
assert_eq!(Some(3), coin_change(&coins, 11));
41+
42+
// 119 = 11 * 10 + 7 * 1 + 2 * 1
43+
let coins = vec![2, 3, 5, 7, 11];
44+
assert_eq!(Some(12), coin_change(&coins, 119));
45+
}
46+
47+
#[test]
48+
fn coins_empty() {
49+
let coins = vec![];
50+
assert_eq!(None, coin_change(&coins, 1));
51+
}
52+
53+
#[test]
54+
fn amount_zero() {
55+
let coins = vec![1, 2, 3];
56+
assert_eq!(Some(0), coin_change(&coins, 0));
57+
}
58+
59+
#[test]
60+
fn fail_change() {
61+
// 3 can't be change by 2.
62+
let coins = vec![2];
63+
assert_eq!(None, coin_change(&coins, 3));
64+
let coins = vec![10, 20, 50, 100];
65+
assert_eq!(None, coin_change(&coins, 5));
66+
}
67+
}

src/dynamic_programming/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
mod coin_change;
12
mod edit_distance;
23
mod egg_dropping;
34
mod fibonacci;
45
mod knapsack;
56
mod longest_common_subsequence;
67

8+
pub use self::coin_change::coin_change;
79
pub use self::edit_distance::{edit_distance, edit_distance_se};
810
pub use self::egg_dropping::egg_drop;
911
pub use self::fibonacci::fibonacci;

0 commit comments

Comments
 (0)