-
Notifications
You must be signed in to change notification settings - Fork 622
/
Copy pathcoin_change.py
94 lines (73 loc) · 2.24 KB
/
coin_change.py
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
'''
Coin Change
You are given coins of different denominations and a total amount of money amount.
Write a function to compute the fewest number of coins that you need to make up that amount.
If that amount of money cannot be made up by any combination of the coins, return -1.
Input: coins = [1, 2, 5], amount = 11
Output: 3
Input: coins = [2], amount = 3
Output: -1
=========================================
Dynamic programming solution 1
Time Complexity: O(A*C) , A = amount, C = coins
Space Complexity: O(A)
Dynamic programming solution 2 (don't need the whole array, just use modulo to iterate through the partial array)
Time Complexity: O(A*C) , A = amount, C = coins
Space Complexity: O(maxCoin)
'''
##############
# Solution 1 #
##############
def coin_change_1(coins, amount):
if amount == 0:
return 0
if len(coins) == 0:
return -1
max_value = amount + 1 # use this instead of math.inf
dp = [max_value for i in range(max_value)]
dp[0] = 0
for i in range(1, max_value):
for c in coins:
if c <= i:
# search on previous positions for min coins needed
dp[i] = min(dp[i], dp[i - c] + 1)
if (dp[amount] == max_value):
return -1
return dp[amount]
##############
# Solution 2 #
##############
def coin_change_2(coins, amount):
if amount == 0:
return 0
if len(coins) == 0:
return -1
max_value = amount + 1
max_coin = min(max_value, max(coins) + 1)
dp = [max_value for i in range(max_coin)]
dp[0] = 0
for i in range(1, max_value):
i_mod = i % max_coin
dp[i_mod] = max_value # reset current position
for c in coins:
if c <= i:
# search on previous positions for min coins needed
dp[i_mod] = min(dp[i_mod], dp[(i - c) % max_coin] + 1)
if (dp[amount % max_coin] == max_value):
return -1
return dp[amount % max_coin]
###########
# Testing #
###########
# Test 1
# Correct result => 3
coins = [1, 2, 5]
amount = 11
print(coin_change_1(coins, amount))
print(coin_change_2(coins, amount))
# Test 2
# Correct result => -1
coins = [2]
amount = 3
print(coin_change_1(coins, amount))
print(coin_change_2(coins, amount))