class Solution1(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
dp = [float("inf")] * (amount + 1)
dp[0] = 0
for i in range(1, len(dp)):
for coin in coins:
if i - coin >= 0 :
dp[i] = min(dp[i-coin] + 1, dp[i])
return dp[-1] if dp[-1] != float("inf") else -1
class Solution2(object):
"""
this recursion from bottom to the top, and return result in the top
we can optimize by store the intermediate result in dict
"""
def coinChange(self, coins, amount):
self.dict = {}
result = self.DFS(coins, amount)
return result if result != float("inf") else -1
def DFS(self, coins, amount):
if amount == 0: return 0
if amount not in self.dict:
miner = min([self.DFS(coins, amount -coin) for coin in coins if amount - coin >= 0] + [float("inf")]) + 1
self.dict[amount] = miner
return self.dict[amount]
class Solution3(object):
"""
this recursion from top to bottom and return result in the bottom
and it's hard to store the intermediate result
"""
def coinChange(self, coins, amount):
self.res = float("inf")
self.DFS(coins, amount, 0)
return self.res if self.res != float("inf") else -1
def DFS(self, coins, amount, count):
if amount == 0:
self.res = min(self.res, count)
for coin in coins:
if amount - coin >= 0:
self.DFS(coins, amount - coin, count + 1)
class Solution4(object):
"""
optimize recursion from top to bottom, and use coin from max to min to prue the repeating path
faster than 97.16%
"""
def coinChange(self, coins, amount):
# must sort
coins.sort(reverse=True)
self.res = float("inf")
for i in range(len(coins)):
self.DFS(i, coins, amount, 0)
return self.res if self.res != float("inf") else -1
def DFS(self, index, coins, amount, count):
if amount == 0 :
self.res = min(self.res, count)
for i in range(index, len(coins)):
if amount - coins[i] >= 0 and amount < coins[i] * (self.res - count) : #prune here, precondition is sort reverse (use max coin can't relaize the the min either)
self.DFS(i, coins, amount - coins[i], count+1)
相关文章: