-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Expand file tree
/
Copy path0322-coin-change.js
More file actions
124 lines (98 loc) · 3.04 KB
/
0322-coin-change.js
File metadata and controls
124 lines (98 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/**
* Brute Force - DFS
* Time O(S^N) | Space O(N)
* https://leetcode.com/problems/coin-change/
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
var coinChange = (coins, amount, coin = 0) => {
const isBaseCase1 = amount === 0;
if (isBaseCase1) return 0;
const isBaseCase2 = !(coin < coins.length && 0 < amount);
if (isBaseCase2) return -1;
return dfs(coins, amount, coin); /* Time O(S^N) | Space O(N) */
};
var dfs = (coins, amount, coin) => {
let [max, minCost] = [amount / coins[coin], Infinity];
for (let num = 0; num <= max; num++) {
/* Time O(N) */
const caUpdate = num * coins[coin] <= amount;
if (!caUpdate) continue;
const product = num * coins[coin];
const difference = amount - product;
const min = coinChange(
coins,
difference,
coin + 1,
); /* Time O(S^N) | Space O(N) */
const cost = min + num;
const isSentinel = min === -1;
if (isSentinel) continue;
minCost = Math.min(minCost, cost);
}
return minCost !== Infinity ? minCost : -1;
};
/**
* DP - Top Down
* Array - Memoization
* Time O(N) | Space O(N)
* https://leetcode.com/problems/coin-change/
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
var coinChange = (coins, amount, memo = initMemo(amount)) => {
const isBaseCase1 = amount < 0;
if (isBaseCase1) return -1;
const isBaseCase2 = amount < 1;
if (isBaseCase2) return 0;
const isBaseCase3 = memo[amount - 1] !== 0;
if (isBaseCase3) return memo[amount - 1];
return dfs(coins, amount, memo); /* Time O(N) | Space O(N) */
};
const initMemo = (amount) => Array(amount).fill(0);
var dfs = (coins, amount, memo, min = Infinity) => {
for (const coin of coins) {
/* Time O(N) */
const cost = coinChange(
coins,
amount - coin,
memo,
); /* Time O(N) | Space O(N) */
const canUpdate = 0 <= cost && cost < min;
if (!canUpdate) continue;
min = cost + 1;
}
memo[amount - 1] = min !== Infinity ? min : -1;
return memo[amount - 1];
};
/**
* DP - Bottom Up
* Array - Tabulation
* Time O(N) | Space O(N)
* https://leetcode.com/problems/coin-change/
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
var coinChange = (coins, amount) => {
const tabu = initTabu(amount);
for (let _amount = 1; _amount <= amount; _amount++) {
/* Time O(N) */
for (let coin = 0; coin < coins.length; coin++) {
/* Time O(N) */
const canUpdate = coins[coin] <= _amount;
if (!canUpdate) continue;
const difference = _amount - coins[coin];
const min = tabu[difference] + 1;
tabu[_amount] = Math.min(tabu[_amount], min); /* Space O(N) */
}
}
return tabu[amount] <= amount ? tabu[amount] : -1;
};
const initTabu = (amount) => {
const tabu = Array(amount + 1).fill(amount + 1);
tabu[0] = 0;
return tabu;
};