Skip to content

Commit 8051bfd

Browse files
authored
chore: Merge pull request TheAlgorithms#650 from mandy8055/coinChangeCombMem
Added the recursive-memoized approach for coin change combination pro…
2 parents 24379ea + 9cf1e55 commit 8051bfd

File tree

2 files changed

+67
-35
lines changed

2 files changed

+67
-35
lines changed

Dynamic-Programming/CoinChange.js

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,33 @@
1-
function change (coins, amount) {
1+
/**
2+
* @params {Array} coins
3+
* @params {Number} amount
4+
*/
5+
export const change = (coins, amount) => {
6+
// Create and initialize the storage
27
const combinations = new Array(amount + 1).fill(0)
38
combinations[0] = 1
4-
9+
// Determine the direction of smallest sub-problem
510
for (let i = 0; i < coins.length; i++) {
6-
const coin = coins[i]
7-
8-
for (let j = coin; j < amount + 1; j++) {
9-
combinations[j] += combinations[j - coin]
11+
// Travel and fill the combinations array
12+
for (let j = coins[i]; j < combinations.length; j++) {
13+
combinations[j] += combinations[j - coins[i]]
1014
}
1115
}
1216
return combinations[amount]
1317
}
14-
15-
function minimumCoins (coins, amount) {
16-
// minimumCoins[i] will store the minimum coins needed for amount i
17-
const minimumCoins = new Array(amount + 1).fill(0)
18-
19-
minimumCoins[0] = 0
20-
21-
for (let i = 1; i < amount + 1; i++) {
22-
minimumCoins[i] = Number.MAX_SAFE_INTEGER
23-
}
24-
for (let i = 1; i < amount + 1; i++) {
25-
for (let j = 0; j < coins.length; j++) {
26-
const coin = coins[j]
27-
if (coin <= i) {
28-
const subRes = minimumCoins[i - coin]
29-
if (subRes !== Number.MAX_SAFE_INTEGER && subRes + 1 < minimumCoins[i]) {
30-
minimumCoins[i] = subRes + 1
31-
}
32-
}
18+
/**
19+
* @params {Array} coins
20+
* @params {Number} amount
21+
*/
22+
export const coinChangeMin = (coins, amount) => {
23+
const map = { 0: 1 }
24+
for (let i = 1; i <= amount; i++) {
25+
let min = Infinity
26+
for (const coin of coins) {
27+
if (i < coin) continue
28+
min = Math.min(min, 1 + map[i - coin])
3329
}
30+
map[i] = min
3431
}
35-
return minimumCoins[amount]
36-
}
37-
38-
function main () {
39-
const amount = 12
40-
const coins = [2, 4, 5]
41-
console.log('Number of combinations of getting change for ' + amount + ' is: ' + change(coins, amount))
42-
console.log('Minimum number of coins required for amount :' + amount + ' is: ' + minimumCoins(coins, amount))
32+
return map[amount] === Infinity ? -1 : map[amount] - 1
4333
}
44-
45-
main()
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { change, coinChangeMin } from '../CoinChange'
2+
3+
test('Base Case 1', () => {
4+
const coins = [2, 3, 5]
5+
const amount = 0
6+
expect(change(coins, amount)).toBe(1)
7+
expect(coinChangeMin(coins, amount)).toBe(0)
8+
})
9+
test('Base Case 2', () => {
10+
const coins = []
11+
const amount = 100
12+
expect(change(coins, amount)).toBe(0)
13+
expect(coinChangeMin(coins, amount)).toBe(-1)
14+
})
15+
test('Test Case 1', () => {
16+
const coins = [2, 4, 5]
17+
const amount = 12
18+
expect(change(coins, amount)).toBe(5)
19+
expect(coinChangeMin(coins, amount)).toBe(3)
20+
})
21+
test('Test Case 2', () => {
22+
const coins = [5, 2, 3, 7, 6, 1, 12, 11, 9, 15]
23+
const amount = 45
24+
expect(change(coins, amount)).toBe(12372)
25+
expect(coinChangeMin(coins, amount)).toBe(3)
26+
})
27+
test('Test Case 3', () => {
28+
const coins = [2]
29+
const amount = 3
30+
expect(change(coins, amount)).toBe(0)
31+
expect(coinChangeMin(coins, amount)).toBe(-1)
32+
})
33+
test('Test Case 4', () => {
34+
const coins = [3, 5, 7, 8, 9, 10, 11]
35+
const amount = 500
36+
expect(change(coins, amount)).toBe(35502874)
37+
expect(coinChangeMin(coins, amount)).toBe(46)
38+
})
39+
test('Test Case 5', () => {
40+
const coins = [10]
41+
const amount = 10
42+
expect(change(coins, amount)).toBe(1)
43+
expect(coinChangeMin(coins, amount)).toBe(1)
44+
})

0 commit comments

Comments
 (0)